Whisper の結果をLINEで送る

Whisper の結果をLINEで送る

実行環境
M1 MacbookAir 16GB

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time

def main():

    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()
    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()
                # 処理が10秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("10秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("5秒以上の無音状態が続いたため、ループを終了します。")
            break  # 無音5秒以上でループを抜ける
        text = fasterWhispermodel.audio2text(audio_data)
        print(text)

if __name__ == "__main__":
    main()

としたら停止するが実際には10秒以上かかったので
これを五秒程度にしたらうまく動く

次は line notify でこの文章を送信してみる

しかし、その前にこのtext部分をリストなどで格納してから送信する必要がある

まずここまでのソースを移動しておく

cp -rp module ~/aw10s/linebot
cp -rp configs/ ~/aw10s/linebot 
cp main.py ~/aw10s/linebot
で
cd ~/aw10s/linebot
python main.py

を実行したらエラー

Config.iniがないと出る
これは

cp -rp configs ~/aw10s/linebot

とすることで解決

これでここまで行った音声の自動終了はできたので
入力をリストなどにまとめるようにする

これは以前音声ファイルを出力した時の応用でできるはず

ループを抜けた時に入力した音声を改行付きで一覧表示したい

入力した音声をループを抜けたときに改行付きで一覧表示するには、音声認識されたテキストをリストに格納し、ループを抜けた後にそのリスト内のテキストを改行付きで表示する

recognized_textsリストの作成
* recognized_textsというリストを作成し、各ループで音声認識されたテキストをそのリストに追加
recognized_texts.append(text)
* 各ループで変換されたテキストをrecognized_textsリストに追加
ループ終了後の一覧表示
* ループを抜けた後に、print(“\n”.join(recognized_texts))を使って、リスト内のテキストを改行付きで表示

をmain.pyに追加する

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time

def main():

    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()
    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()
                # 処理が10秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("10秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("5秒以上の無音状態が続いたため、ループを終了します。")
            break  # 無音5秒以上でループを抜ける
        text = fasterWhispermodel.audio2text(audio_data)
        print(text)

if __name__ == "__main__":
    main()
を

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time

def main():
    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()

    # 入力された音声テキストを格納するリスト
    recognized_texts = []

    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()
        
        # 処理が2秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("2秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("無音状態が続いたため、ループを終了します。")
            break  # 無音でループを抜ける
        
        # 音声をテキストに変換
        text = fasterWhispermodel.audio2text(audio_data)
        recognized_texts.append(text)  # テキストをリストに追加
        print(text)

    # ループ終了後に、入力した音声テキストを改行付きで一覧表示
    print("\n入力された音声テキスト一覧:")
    print("\n".join(recognized_texts))

if __name__ == "__main__":
    main()

に変更し実行

[2024-09-06 06:03:52.900] [ctranslate2] [thread 17609052] [warning] The compute type inferred from the saved model is float16, but the target device or backend do not support efficient float16 computation. The model weights have been automatically converted to use the float32 compute type instead.
stand by ready OK
recording...
finished
今日のハンバーグは何にしようか
stand by ready OK
recording...
finished
和風ソースか
stand by ready OK
recording...
finished
オニオンソース
stand by ready OK
recording...
finished
デミグラスソース
stand by ready OK
recording...
finished
出しようかな
stand by ready OK
recording...
finished
今日の買い物リスト
stand by ready OK
recording...
finished
2秒間音声が入力されなかったため、ループを終了します。

入力された音声テキスト一覧:
今日のハンバーグは何にしようか
和風ソースか
オニオンソース
デミグラスソース
出しようかな
今日の買い物リスト

というように一覧表示ができた

次はこれを line notify で送信してみる

これは以前作成した在庫管理送信の機能から使う
チラシの方だとOCR処理が入っているのでより複雑だった

今回の場合、画像は不要で
Whisperで文字起こしした音声を送信するのが目的

 cp ../store_adversting_list/config.json .


LINEのAPIキーが格納されているファイルをコピー

今回はconfig.jsonの中はtoken 以外は削除しておく

{
  "token": "取得したアクセストークン"
}

次に

touch ilne_notify.py

でline notify の処理のモジュールを作成

# line_notify.py
import json
import requests

class LineNotify:
    def __init__(self, token_file_path):
        self.token = self._load_token(token_file_path)

    # JSONファイルからアクセストークンを読み込む
    def _load_token(self, token_file_path):
        with open(token_file_path, 'r') as file:
            data = json.load(file)
        return data["token"]

    # LINE Notifyでメッセージを送信
    def send(self, message):
        url = "https://notify-api.line.me/api/notify"
        headers = {
            "Authorization": f"Bearer {self.token}"
        }
        data = {
            "message": message
        }
        response = requests.post(url, headers=headers, data=data)
        if response.status_code != 200:
            raise Exception(f"Error sending message: {response.status_code}, {response.text}")
        return response

として保存

Main.pyを

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time

def main():
    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()

    # 入力された音声テキストを格納するリスト
    recognized_texts = []

    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()
        
        # 処理が2秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("2秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("無音状態が続いたため、ループを終了します。")
            break  # 無音でループを抜ける
        
        # 音声をテキストに変換
        text = fasterWhispermodel.audio2text(audio_data)
        recognized_texts.append(text)  # テキストをリストに追加
        print(text)

    # ループ終了後に、入力した音声テキストを改行付きで一覧表示
    print("\n入力された音声テキスト一覧:")
    print("\n".join(recognized_texts))

if __name__ == "__main__":
    main()

から

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time
from line_notify import LineNotify  # 作成したLineNotifyモジュールをインポート

def main():
    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()

    # 入力された音声テキストを格納するリスト
    recognized_texts = []

    # LINE Notifyのモジュールを初期化(アクセストークンをJSONファイルから読み込む)
    line_notify = LineNotify("config.json")

    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()

        # 処理が2秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("2秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("無音状態が続いたため、ループを終了します。")
            break  # 無音でループを抜ける
        
        # 音声をテキストに変換
        text = fasterWhispermodel.audio2text(audio_data)
        recognized_texts.append(text)  # テキストをリストに追加
        print(text)

    # ループ終了後に、入力した音声テキストを改行付きで一覧表示
    print("\n入力された音声テキスト一覧:")
    message = "\n".join(recognized_texts)
    print(message)

    # LINE Notifyでメッセージを送信
    line_notify.send(f"入力された音声テキスト一覧:\n{message}")

if __name__ == "__main__":
    main()

へ変更

これで実行すると音声で入力したものがline notify で送信される

しかし、これだと音声入力がなくても送信されるため、
もし入力リストが空ならログ表示だけにする

import sounddevice as sd
from module.module_whisper import FasterWhisperModel
from module.module_recorder import Recorder
import time
from line_notify import LineNotify  # 作成したLineNotifyモジュールをインポート

def main():
    recorder = Recorder()
    fasterWhispermodel = FasterWhisperModel()

    # 入力された音声テキストを格納するリスト
    recognized_texts = []

    # LINE Notifyのモジュールを初期化(config.jsonからトークンを読み込む)
    line_notify = LineNotify("config.json")

    while True:
        start_time = time.time()  # 処理開始時刻を記録
        audio_data = recorder.speech2audio()

        # 処理が2秒間行われなかった場合はループを抜ける
        if time.time() - start_time >= 5:
            print("2秒間音声が入力されなかったため、ループを終了します。")
            break

        if audio_data is None:
            print("無音状態が続いたため、ループを終了します。")
            break  # 無音でループを抜ける
        
        # 音声をテキストに変換
        text = fasterWhispermodel.audio2text(audio_data)
        recognized_texts.append(text)  # テキストをリストに追加
        print(text)

    # ループ終了後に、入力した音声テキストを改行付きで一覧表示
    if recognized_texts:
        message = "\n".join(recognized_texts)
        print("\n入力された音声テキスト一覧:")
        print(message)

        # LINE Notifyでメッセージを送信
        line_notify.send(f"入力された音声テキスト一覧:\n{message}")
    else:
        print("入力メッセージはありませんでした")

if __name__ == "__main__":
    main()

とすることで入力がない場合には
Line notifyで送信しなくなる