Spaces:
Running
Running
import gradio as gr | |
import os | |
import glob | |
import re | |
# --- 定数定義 --- | |
# Style-Bert-VITS2の実際の出力フォルダ名を指定 | |
OUTPUT_DIR = "sample_audio" | |
# --- 1. ヘルパー関数 --- | |
def natural_sort_key(s): | |
""" | |
文字列を自然順ソート(例: 'FN2'が'FN10'より前に来る)するためのキーを生成する。 | |
""" | |
return [int(text) if text.isdigit() else text.lower() for text in re.split(r'(\d+)', s)] | |
def get_folders(): | |
"""outputsディレクトリ内のサブフォルダのリストを自然順ソートで取得します。""" | |
if not os.path.exists(OUTPUT_DIR) or not os.path.isdir(OUTPUT_DIR): | |
print(f"警告: '{OUTPUT_DIR}' フォルダが見つかりません。") | |
return [] | |
folders = [f.name for f in os.scandir(OUTPUT_DIR) if f.is_dir()] | |
folders.sort(key=natural_sort_key) | |
return folders | |
def update_file_list(folder_name): | |
""" | |
選択されたフォルダに応じて、ファイルリストの選択肢を更新します。 | |
""" | |
if not folder_name: | |
return gr.update(choices=[], value=None, label="ファイルを選択") | |
search_pattern = os.path.join(OUTPUT_DIR, folder_name, f"{folder_name}_*.mp3") | |
file_paths = sorted(glob.glob(search_pattern)) | |
choices_list = [] | |
for path in file_paths: | |
basename = os.path.basename(path) | |
prefix_to_remove = f"{folder_name}_" | |
if basename.startswith(prefix_to_remove): | |
display_name = basename[len(prefix_to_remove):] | |
else: | |
display_name = basename | |
display_name = display_name.removesuffix(".mp3") | |
choices_list.append((display_name, path)) | |
if not choices_list: | |
return gr.update(choices=[], value=None, label=f"{folder_name} にはファイルがありません") | |
return gr.update(choices=choices_list, value=None, label=f"「{folder_name}」のサンプル音声") | |
def play_audio(filepath): | |
""" | |
選択されたファイルパスをAudioコンポーネントに渡して再生可能にします。 | |
""" | |
return gr.update(value=filepath, visible=bool(filepath)) | |
# --- 2. Gradio UIの構築 --- | |
def create_player_tab(): | |
""" | |
音声再生プレイヤーのUIコンポーネントを作成し、タブ内に配置できるようにする関数。 | |
""" | |
# gr.Markdown( | |
# f""" | |
# # Style-Bert-VITS2 音声再生プレイヤー | |
# `{OUTPUT_DIR}` フォルダ内の音声ファイルを再生します。 | |
# フォルダ(話者)を選択すると、その中のファイルリストが表示されます。 | |
# """ | |
# ) | |
initial_folders = get_folders() | |
if not initial_folders: | |
gr.Warning(f"'{OUTPUT_DIR}' フォルダが見つからないか、空です。Style-Bert-VITS2で音声を生成してからアプリを再起動してください。") | |
else: | |
with gr.Row(): | |
folder_selector = gr.Dropdown( | |
choices=initial_folders, | |
label="1. 話者を選択", | |
interactive=True | |
) | |
# フォルダリストが長い場合に見やすくなるようにコンポーネントを分ける | |
with gr.Column(scale=2): # 横幅の比率を調整 | |
file_selector = gr.Radio( | |
label="2. ファイルを選択", | |
choices=[], | |
interactive=True | |
) | |
audio_player = gr.Audio(label="再生プレイヤー", type="filepath", visible=False) | |
# --- 3. コンポーネント間の連携を設定 --- | |
folder_selector.change( | |
fn=update_file_list, | |
inputs=folder_selector, | |
outputs=file_selector | |
).then( | |
fn=lambda: gr.update(value=None, visible=False), | |
inputs=None, | |
outputs=audio_player | |
) | |
file_selector.change( | |
fn=play_audio, | |
inputs=file_selector, | |
outputs=audio_player | |
) |