File size: 4,749 Bytes
98d243e
fd83c02
98d243e
 
 
 
 
 
 
 
 
 
6bb76af
bb84400
 
6bb76af
fd83c02
6bb76af
bb84400
6bb76af
98d243e
bb84400
98d243e
47f59e0
98d243e
 
 
 
 
6bb76af
 
bb84400
6bb76af
fd83c02
6bb76af
bb84400
 
98d243e
 
 
 
6bb76af
47f59e0
fd83c02
98d243e
47f59e0
 
bb84400
fd83c02
bb84400
98d243e
bb84400
47f59e0
bb84400
47f59e0
bb84400
98d243e
bb84400
 
98d243e
 
6bb76af
47f59e0
6bb76af
98d243e
6bb76af
 
 
 
98d243e
6bb76af
 
 
 
 
 
 
 
 
98d243e
 
bb84400
6bb76af
bb84400
 
98d243e
6bb76af
98d243e
6bb76af
47f59e0
98d243e
6bb76af
 
 
bb84400
 
 
98d243e
bb84400
6bb76af
bb84400
6bb76af
 
 
 
 
 
98d243e
 
6bb76af
bb84400
 
98d243e
 
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
111
112
113
114
115
# --- Fix Streamlit permission issue BEFORE importing streamlit ---
import os

# Put Streamlit state/config under /tmp (writeable on Spaces)
os.environ.setdefault("STREAMLIT_HOME", "/tmp/streamlit")
os.environ.setdefault("XDG_STATE_HOME", "/tmp")
os.environ.setdefault("XDG_CONFIG_HOME", "/tmp")
os.makedirs(os.environ["STREAMLIT_HOME"], exist_ok=True)

# Disable telemetry to avoid writes under root paths
os.environ.setdefault("STREAMLIT_BROWSER_GATHER_USAGE_STATS", "false")

from pathlib import Path
from datetime import datetime
import streamlit as st
from openai import OpenAI

st.set_page_config(page_title="Urdu TTS - OpenAI", page_icon="🔊", layout="centered")

st.title("🔊 Urdu Text → Speech (OpenAI)")
st.caption("Type Urdu text and generate natural Urdu speech with OpenAI TTS. Use a custom voice_id if your account has Voice access.")

# ---- Get API key (your secret name is Key_1). Fallback to manual entry. ----
API_KEY = os.getenv("Key_1") or st.secrets.get("Key_1")
with st.sidebar:
    st.header("API")
    if not API_KEY:
        st.warning("Secret `Key_1` not found. Paste your key temporarily (will not be saved to repo).")
        API_KEY = st.text_input("OpenAI API key (sk-...)", type="password")
if not API_KEY:
    st.stop()

client = OpenAI(api_key=API_KEY)

# ---- Sidebar options ----
with st.sidebar:
    st.header("Options")
    builtin_voices = ["alloy", "verse", "aria", "ballad", "cove", "luna", "sage"]
    use_custom = st.checkbox("Use custom OpenAI voice_id", False)
    custom_voice = st.text_input("Custom voice_id", value="", help="Requires access to custom voices") if use_custom else ""
    preset_voice = st.selectbox("Built-in voice", builtin_voices, index=0) if not use_custom else None
    out_name = st.text_input("Output filename (no extension)", "urdu_tts")
    fmt = st.selectbox("Audio format", options=["mp3", "wav"], index=0)

# ---- Input ----
default_text = "یہ ایک سادہ مثال ہے۔ یہاں اپنا متن لکھیں اور آڈیو حاصل کریں۔"
text = st.text_area("Urdu text", value=default_text, height=200, placeholder="یہاں اردو میں ٹیکسٹ لکھیں یا پیسٹ کریں…")

col1, col2 = st.columns(2)
with col1:
    make_audio = st.button("🎙️ Generate", use_container_width=True)
with col2:
    clear_btn = st.button("🧹 Clear", use_container_width=True)

if clear_btn:
    st.session_state.pop("audio_bytes", None)
    st.session_state.pop("ext", None)
    st.experimental_rerun()

# ---- TTS helper ----
def synth_openai(urdu_text: str, voice: str, audio_format: str):
    model = "gpt-4o-mini-tts"
    ext = "mp3" if audio_format == "mp3" else "wav"
    tmp_path = Path(f"/tmp/tts_{datetime.now().strftime('%H%M%S')}.{ext}")
    # Stream to file to avoid loading all in memory
    with client.audio.speech.with_streaming_response.create(
        model=model,
        voice=voice,
        input=urdu_text,
        format=("mp3" if audio_format == "mp3" else "wav"),
    ) as resp:
        resp.stream_to_file(tmp_path)
    data = tmp_path.read_bytes()
    try:
        tmp_path.unlink(missing_ok=True)
    except Exception:
        pass
    return data, ext

# ---- Generate ----
if make_audio:
    if not text.strip():
        st.warning("براہ کرم اردو متن درج کریں")
    else:
        try:
            voice_to_use = (custom_voice.strip() if use_custom else preset_voice)
            if not voice_to_use:
                st.warning("Please choose a built-in voice or provide a custom voice_id.")
            else:
                st.info("Generating Urdu speech with OpenAI TTS…")
                audio_bytes, ext = synth_openai(text.strip(), voice_to_use, fmt)
                st.session_state["audio_bytes"] = audio_bytes
                st.session_state["ext"] = ext
                st.success("آڈیو تیار ہے")
        except Exception as e:
            st.error(f"کچھ مسئلہ آیا: {e}")

# ---- Preview & Download ----
if "audio_bytes" in st.session_state:
    ext = st.session_state.get("ext", "mp3")
    st.markdown("### ▶️ Preview")
    st.audio(st.session_state["audio_bytes"], format=f"audio/{'mpeg' if ext=='mp3' else 'wav'}")
    fname = f"{(out_name or 'urdu_tts').strip()}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.{ext}"
    st.download_button(
        "⬇️ Download",
        data=st.session_state["audio_bytes"],
        file_name=fname,
        mime=("audio/mpeg" if ext == "mp3" else "audio/wav"),
        use_container_width=True,
    )

st.markdown("---")
st.caption("If your secret is named `Key_1`, keep it in Settings → Variables and secrets → Secrets. "
           "This app stores Streamlit state under /tmp to avoid permission issues on Spaces.")