Spaces:
Running
Running
import os | |
# Fix Streamlit permission issues by redirecting HOME and XDG_CONFIG_HOME to writable path | |
cwd = os.getcwd() | |
os.environ.setdefault('XDG_CONFIG_HOME', cwd) | |
os.environ.setdefault('HOME', cwd) | |
import streamlit as st | |
from pathlib import Path | |
# Determine BASE_DIR relative to this script's location | |
SCRIPT_DIR = Path(__file__).resolve().parent | |
# Assuming project structure: project_root/src/streamlit_app.py and project_root/tts_smaples | |
BASE_DIR = SCRIPT_DIR.parent / "tts_smaples" | |
def get_providers_and_voices(base_dir: Path): | |
""" | |
Scan the base_dir for subfolders (providers) and .wav files under each. | |
Returns a dict: { provider_name: [voice_filename1.wav, ...], ... } | |
""" | |
providers = {} | |
if not base_dir.is_dir(): | |
return providers | |
for provider in sorted([p for p in base_dir.iterdir() if p.is_dir()]): | |
voices = sorted([f.name for f in provider.iterdir() if f.is_file() and f.suffix.lower() == ".wav"] ) | |
if voices: | |
providers[provider.name] = voices | |
return providers | |
# Main app | |
def main(): | |
# Configure page for better mobile experience | |
st.set_page_config(page_title="TTS 範例播放器", layout="wide") | |
st.title("🎵 TTS 範例播放器") | |
# Short introduction for non-tech users | |
st.markdown( | |
""" | |
**此範例示範 TTS 播放以下句子: | |
> 八和和牛燒肉專門店。沒有將就,只有講究! | |
請在側邊欄選擇 TTS 提供者與語音,然後播放範例音檔。 | |
""" | |
) | |
providers = get_providers_and_voices(BASE_DIR) | |
if not providers: | |
st.warning(f"未找到任何 TTS 提供者資料夾 `{BASE_DIR}`,請確認資料夾存在,且包含 .wav 檔案。") | |
parent = BASE_DIR.parent | |
if parent.exists(): | |
st.info(f"上層資料夾內容 `{parent}`: {sorted([p.name for p in parent.iterdir()])}") | |
return | |
# Sidebar for selection | |
st.sidebar.header("選擇 TTS 範例") | |
provider_list = sorted(providers.keys()) | |
provider = st.sidebar.selectbox("提供者", options=provider_list) | |
voices = providers.get(provider, []) | |
if not voices: | |
st.sidebar.info(f"提供者 `{provider}` 底下沒有 .wav 檔案。") | |
return | |
voice = st.sidebar.selectbox("語音", options=voices) | |
# Main area shows single playback | |
st.markdown(f"### 播放中:**{provider} / {voice}**") | |
file_path = BASE_DIR / provider / voice | |
if file_path.is_file(): | |
try: | |
audio_bytes = file_path.read_bytes() | |
st.audio(audio_bytes, format="audio/wav") | |
except Exception as e: | |
st.error(f"載入音訊時出錯: {e}") | |
else: | |
st.error(f"找不到檔案: `{file_path}`") | |
if __name__ == "__main__": | |
main() | |