--- title: JusTalk emoji: ⚡ colorFrom: gray colorTo: blue sdk: docker pinned: false --- ## --- ## グローバル変数と主要な設定 - **`users`** 登録されたユーザー名のリスト。 - **`transcription_text`** 音声から作成された書き起こしのファイルパスまたは内容。 - **`total_audio`** 音声セグメントをマージした結果の音声ファイルパス。 - **`harassment_keywords`** ハラスメントとして検出するキーワードのリスト(例:"バカ", "死ね" など)。 また、外部ライブラリとして `pydub`、および独自の `AudioProcessor`、`TranscriptionMaker`、`TextAnalyzer` を用いて音声処理や解析を行います。 --- ## 各エンドポイントの概要 ### 1. トップページ/ユーザー登録画面 - **URL:** `/index` **メソッド:** GET, POST **機能:** - テンプレート `index.html` を表示。 - 現在の `users` リストをテンプレートに渡す。 - **URL:** `/` または `/userregister` **メソッド:** GET, POST **機能:** - ユーザー登録用の画面を表示するため、`userRegister.html` テンプレートを返す。 --- ### 2. フィードバックおよび会話詳細画面 - **URL:** `/feedback` **メソッド:** GET, POST **機能:** - フィードバック画面(テンプレート:`feedback.html`)を表示。 - **URL:** `/talk_detail` **メソッド:** GET, POST **機能:** - 会話の詳細を表示する画面(テンプレート:`talkDetail.html`)を返す。 --- ### 3. ユーザーとファイルのリセット関連 - **URL:** `/reset_html` **メソッド:** GET, POST **機能:** - リセット画面(テンプレート:`reset.html`)を表示。 - **URL:** `/reset_member` **メソッド:** GET, POST **機能:** - 指定されたメンバー(ユーザー)とその関連の参照音声ファイルを削除する。 - リクエストボディ内で `"names"` キーが必須。 - `/tmp/data/base_audio` 内の各ユーザーの音声ファイル(`{name}.wav`)を削除。 - 削除後、`users` リストから対象ユーザーを除外する。 - 加えて、累積音声ファイル(`total_audio`)や、書き起こしファイル(`transcription_text`)も削除する処理を実施。 - **URL:** `/reset` **メソッド:** GET **機能:** - `users` リストを空にリセットし、成功レスポンスを返す。 --- ### 4. 状態確認エンドポイント - **URL:** `/confirm` **メソッド:** GET **機能:** - 現在登録されているメンバー(`users`)を JSON 形式で返す。 --- ### 5. 音声アップロード・解析関連 #### a. 基本の音声アップロードと参照音声との照合 - **URL:** `/upload_audio` **メソッド:** POST **機能:** - クライアントから受け取った Base64 形式の音声データをデコードし、一時ファイル(`/tmp/data/tmp.wav`)として保存。 - リクエストボディ内には、`audio_data` とともに、`name` または `users`(登録済みユーザーの情報)が必要。 - 各ユーザーの参照音声ファイル(`/tmp/data/base_audio/{user}.wav`)とアップロードされた音声を比較し、 - 複数ユーザーの場合:`process_multi_audio` を使用して各ユーザー毎の一致時間を計算し、その比率(パーセンテージ)を返す。 - 単一ユーザーの場合:`process_audio` を用いて一致時間と非一致時間から比率(パーセンテージ)を計算して返す。 - また、処理後に複数の音声セグメントをマージし、その結果を `total_audio` に格納する。 #### b. 基準音声のアップロード(ユーザー登録時に使用) - **URL:** `/upload_base_audio` **メソッド:** POST **機能:** - リクエストボディ内の `audio_data`(Base64形式)と `name` を受け取り、 - `users` リストに名前を追加(重複排除を実施)。 - `/tmp/data/base_audio/` 内に、`{name}.wav` という名前で保存。 - 登録成功時に、状態とファイルパスを返す。 --- ### 6. 書き起こし生成およびテキスト解析 #### a. 書き起こし作成 - **URL:** `/transcription` **メソッド:** GET, POST **機能:** - グローバル変数 `transcription_text` に書き起こし済みのファイルが存在しない場合、 - `total_audio`(マージ済み音声ファイル)が存在しているかをチェック。 - `TranscriptionMaker` の `merge_segments` メソッドでセグメントをマージし、`create_transcription` で書き起こしファイルを生成。 - 書き起こしファイルを読み込み、内容を JSON 形式で返す。 - エラー発生時には適切な HTTP ステータスコード(400, 404, 500)とエラーメッセージを返す。 #### b. AI によるテキスト解析 - **URL:** `/analyze` **メソッド:** GET, POST **機能:** - `/transcription` と同様に、書き起こしファイルの存在を確認し、必要なら再生成する。 - `TextAnalyzer` クラスを使って、書き起こしテキストとハラスメントキーワードをもとに解析を実施。 - 環境変数 `DEEPSEEK` を API キーとして取得し、DeepSeek 解析を呼び出す。 - 解析結果(会話レベル、ハラスメントの有無や種類、繰り返しの程度、会話の心地よさ、非難やハラスメントの程度など)をコンソール出力し、JSON 形式で返す。 --- ## エンドポイント間の流れとポイント - **ユーザー登録:** `/upload_base_audio` でユーザーごとの基準音声を登録し、`users` リストに名前を追加。 - **音声解析:** `/upload_audio` によりアップロードされた音声を、登録された参照音声と照合。 - 複数ユーザーの場合、各ユーザーの一致時間を計算し、パーセンテージとして返す。 - 単一ユーザーの場合、一致時間と非一致時間から比率を返す。 - この段階で、音声セグメントをマージし、後続の書き起こし・解析に利用するために `total_audio` に格納。 - **書き起こしの生成と利用:** `/transcription` で `total_audio` から書き起こしファイルを生成し、その内容を取得可能。 `/analyze` では、生成済みの書き起こしテキストをもとに、DeepSeek API を用いた AI 解析が実行される。 - **リセット機能:** `/reset_member` で指定ユーザーの音声ファイル、累積音声、書き起こしファイルを削除。 `/reset` で `users` リストを完全にクリアする。 --- ## <process.py> --- ## 全体概要 - **目的:** 音声ファイルの前処理、セグメント分割、音声特徴量(エンベディング)計算、類似度算出、さらに Base64 形式の音声データの保存など、音声データの様々な操作を行うための機能を提供します。 - **利用ライブラリ:** - `pydub`:音声ファイルの読み込み、書き出し、セグメント分割に使用 - `pyannote.audio`:事前学習済みモデルを用いて音声のエンベディング(特徴量)を計算 - `numpy`:数値計算およびベクトル演算(コサイン類似度計算など) - その他、`os`, `shutil`, `base64`, `datetime` など、ファイル操作や乱数生成に利用 - **初期設定:** コンストラクタ (`__init__`) では、環境変数 `HF` から Hugging Face のトークンを取得し、`pyannote` のモデルをロード。標準の音声長さ(秒)も設定します。 --- ## 各関数の詳細 ### 1. `normalize_audio_duration` - **目的:** 指定された音声ファイルの長さを、ターゲットの秒数に合わせて正規化(短い場合は無音でパディング、長い場合は切り詰め)します。 - **引数:** - `input_path`:入力音声ファイルのパス - `target_duration_seconds`:目標とする音声の長さ(秒)。未指定の場合は標準値(`self.standard_duration`)を使用 - `output_path`:出力先のパス(未指定の場合は一時ファイルとして生成) - **戻り値:** 正規化された音声ファイルのパス --- ### 2. `batch_normalize_audio_duration` - **目的:** 指定したディレクトリ内のすべての音声ファイルに対して、`normalize_audio_duration` を適用し、ファイルの長さを統一します。 - **引数:** - `input_directory`:入力音声ファイルが格納されているディレクトリ - `target_duration_seconds`:目標とする音声の長さ(秒) - `output_directory`:出力先ディレクトリ(未指定の場合は入力ディレクトリと同じ場所) - **戻り値:** 処理後の音声ファイルパスのリスト --- ### 3. `cosine_similarity` - **目的:** 2つのベクトル間のコサイン類似度を計算します。 - **引数:** - `vec1`, `vec2`:比較対象となる numpy 配列 - **処理:** 次元が一致しているかを確認し、各ベクトルを正規化した後、内積を計算 - **戻り値:** コサイン類似度(-1~1の範囲) --- ### 4. `segment_audio` - **目的:** 入力音声ファイルを指定した秒数のセグメントに分割し、各セグメントを出力ディレクトリに保存します。 - **引数:** - `path`:入力音声ファイルのパス - `target_path`:分割されたセグメントの保存先ディレクトリ - `seg_duration`:各セグメントの長さ(秒) - **戻り値:** 分割されたセグメントのディレクトリパスと、元の音声の総時間(ミリ秒) --- ### 5. `calculate_embedding` - **目的:** 指定した音声ファイルからエンベディング(特徴量)を計算します。 - **引数:** - `audio_path`:音声ファイルのパス - **処理:** - まず音声の長さを `normalize_audio_duration` で標準化 - `pyannote.audio` の推論機能を使い、エンベディングを計算 - 処理後に一時ファイルを削除(必要に応じて) - **戻り値:** エンベディング(flattened な numpy 配列) --- ### 6. `calculate_similarity` - **目的:** 2つの音声ファイル間の類似度(コサイン類似度)を計算します。 - **引数:** - `path1`, `path2`:比較対象となる2つの音声ファイルのパス - **処理:** - 各音声のエンベディングを計算し、次元チェックを実施 - `cosine_similarity` を利用して類似度を求める - **戻り値:** 類似度(float 値、エラー時は None) --- ### 7. `process_audio` - **目的:** リファレンス音声と入力音声を比較し、リファレンスに類似したセグメントを抽出します。 - **引数:** - `reference_path`:リファレンス音声のパス - `input_path`:入力音声のパス - `output_folder`:マッチしたセグメントの出力先ディレクトリ - `seg_duration`:セグメントの長さ(秒) - `threshold`:類似度の閾値 - **処理:** - リファレンス音声のエンベディングを計算 - 入力音声をセグメントに分割し、各セグメントのエンベディングを計算 - 各セグメントとリファレンス間のコサイン類似度を計算し、閾値以上なら出力フォルダへコピー - マッチしたセグメントの総時間と、マッチしなかった時間を計算 - **戻り値:** タプル (マッチ時間[ms], 非マッチ時間[ms], 出力フォルダパス) --- ### 8. `process_multi_audio` - **目的:** 複数のリファレンス音声に対して、入力音声内の各セグメントの類似度を計算し、各リファレンスごとの一致時間を集計します。 - **引数:** - `reference_pathes`:リファレンス音声のパスのリスト - `input_path`:入力音声のパス - `output_folder`:マッチしたセグメントの出力先ディレクトリ - `seg_duration`:各セグメントの長さ(秒) - `threshold`:類似度の閾値 - **処理:** - 各リファレンス音声のエンベディングを先に計算 - 入力音声をセグメントに分割し、各セグメントのエンベディングを計算 - リファレンス毎に各セグメントとの類似度を算出し、最も高い類似度が閾値以上ならそのリファレンスとマッチと判断 - 各リファレンスごとにマッチしたセグメントの時間(秒)を集計 - **戻り値:** タプル (各リファレンスごとの一致時間のリスト, セグメントが保存されたディレクトリパス) --- ### 9. `save_audio_from_base64` - **目的:** Base64 形式でエンコードされた音声データをデコードし、WAV ファイルとして保存します。 - **引数:** - `base64_audio`:Base64 エンコードされた音声データ - `output_dir`:出力先ディレクトリ - `output_filename`:出力するファイル名 - `temp_format`:一時ファイルのフォーマット(デフォルトは 'webm') - **処理:** - Base64 文字列をデコードし、一時ファイルに保存 - `pydub` を用いてファイルを読み込み、WAV 形式に変換して保存 - 一時ファイルは処理後に削除 - **戻り値:** 保存された WAV ファイルのパス --- ### 10. `delete_files_in_directory` - **目的:** 指定したディレクトリ内に存在するすべてのファイルを削除します。 - **引数:** - `directory_path`:対象のディレクトリパス - **処理:** - ディレクトリ内の各ファイルを走査し、ファイルのみ削除 - 削除結果やエラーはコンソールに出力 ---