File size: 4,038 Bytes
8b91f03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2bc1679
8b91f03
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7d653ef
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
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
        )