Spaces:
Running
title: JusTalk
emoji: ⚡
colorFrom: gray
colorTo: blue
sdk: docker
pinned: false
<app.py>
グローバル変数と主要な設定
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
に格納する。
- クライアントから受け取った Base64 形式の音声データをデコードし、一時ファイル(
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
:対象のディレクトリパス
- 処理:
- ディレクトリ内の各ファイルを走査し、ファイルのみ削除
- 削除結果やエラーはコンソールに出力