Thiophai commited on
Commit
ea2f315
·
verified ·
1 Parent(s): cf45928

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +43 -13
app.py CHANGED
@@ -1,4 +1,5 @@
1
  import os
 
2
  from fastapi import FastAPI, HTTPException, Body
3
  from fastapi.middleware.cors import CORSMiddleware
4
  from fastapi.responses import StreamingResponse, JSONResponse
@@ -9,16 +10,14 @@ from typing import Optional
9
  AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
10
  AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION", "southeastasia")
11
 
12
- # Fail early if missing key in local run; on HF Spaces you can still start but return 500 on call.
13
  if not AZURE_SPEECH_KEY:
14
  print("[WARN] AZURE_SPEECH_KEY is not set. Set it in HF Spaces (Settings → Repository secrets).")
15
 
16
  app = FastAPI(title="Azure TTS API", version="1.0.0")
17
 
18
- # --- CORS (ปรับ origin ตามโดเมน FE ของคุณ) ---
19
  app.add_middleware(
20
  CORSMiddleware,
21
- allow_origins=["*"], # แนะนำระบุโดเมนจริงในโปรดักชัน
22
  allow_credentials=True,
23
  allow_methods=["*"],
24
  allow_headers=["*"],
@@ -26,12 +25,38 @@ app.add_middleware(
26
 
27
  DEFAULT_VOICE = "th-TH-PremwadeeNeural"
28
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
  # Map format → Azure SDK OutputFormat
30
  FORMAT_MAP = {
31
  "wav": speechsdk.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,
32
  "mp3": speechsdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,
33
- # ถ้าต้องการ m4a/aac เพิ่มได้ เช่น:
34
- # "aac": speechsdk.SpeechSynthesisOutputFormat.Raw16Khz16BitMonoPcm
35
  }
36
 
37
  @app.get("/")
@@ -47,6 +72,8 @@ def synthesize(
47
  text: str = Body(..., embed=True, description="ข้อความที่จะสังเคราะห์เสียง"),
48
  voice: Optional[str] = Body(DEFAULT_VOICE, embed=True),
49
  audio_format: Optional[str] = Body("mp3", embed=True, description="mp3 หรือ wav"),
 
 
50
  ):
51
  """
52
  คืน audio bytes เป็น StreamingResponse (Content-Type ตามฟอร์แมต)
@@ -64,11 +91,16 @@ def synthesize(
64
  speech_config.speech_synthesis_voice_name = voice or DEFAULT_VOICE
65
  speech_config.set_speech_synthesis_output_format(FORMAT_MAP[audio_format])
66
 
67
- # 2) ่ง audio_config -> จะได้ audio bytes กบมา result.audio_data
 
 
 
 
 
68
  synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
69
 
70
- # 3) สังเคราะห์
71
- result = synthesizer.speak_text_async(text).get()
72
 
73
  if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
74
  audio_bytes = result.audio_data # bytes
@@ -99,9 +131,6 @@ def synthesize(
99
 
100
  @app.get("/voices")
101
  def list_voices():
102
- """
103
- ดึงรายการ voices ที่ใช้งานได้ (ใช้สำหรับให้ FE เลือก)
104
- """
105
  if not AZURE_SPEECH_KEY:
106
  raise HTTPException(status_code=500, detail="AZURE_SPEECH_KEY not set")
107
 
@@ -114,8 +143,8 @@ def list_voices():
114
  voices = []
115
  for v in voices_result.voices:
116
  voices.append({
117
- "name": v.name, # เช่น th-TH-PremwadeeNeural
118
- "locale": v.locale, # เช่น th-TH
119
  "gender": v.gender.name if v.gender else None,
120
  "shortName": getattr(v, "short_name", None)
121
  })
@@ -125,3 +154,4 @@ def list_voices():
125
 
126
  except Exception as e:
127
  raise HTTPException(status_code=500, detail=str(e))
 
 
1
  import os
2
+ import re # ← เพิ่ม
3
  from fastapi import FastAPI, HTTPException, Body
4
  from fastapi.middleware.cors import CORSMiddleware
5
  from fastapi.responses import StreamingResponse, JSONResponse
 
10
  AZURE_SPEECH_KEY = os.getenv("AZURE_SPEECH_KEY")
11
  AZURE_SPEECH_REGION = os.getenv("AZURE_SPEECH_REGION", "southeastasia")
12
 
 
13
  if not AZURE_SPEECH_KEY:
14
  print("[WARN] AZURE_SPEECH_KEY is not set. Set it in HF Spaces (Settings → Repository secrets).")
15
 
16
  app = FastAPI(title="Azure TTS API", version="1.0.0")
17
 
 
18
  app.add_middleware(
19
  CORSMiddleware,
20
+ allow_origins=["*"],
21
  allow_credentials=True,
22
  allow_methods=["*"],
23
  allow_headers=["*"],
 
25
 
26
  DEFAULT_VOICE = "th-TH-PremwadeeNeural"
27
 
28
+ # --- NEW: ตัวช่วยลบอิโมจิออกจากข้อความก่อนส่งให้ TTS ---
29
+ # ครอบคลุม emoji blocks + ตัวเชื่อม/ตัวเลือกเวอร์ชัน (ZWJ/VS-16) + โทนสีผิว + ธง
30
+ EMOJI_RE = re.compile(
31
+ "[" # main emoji blocks
32
+ "\U0001F300-\U0001F5FF"
33
+ "\U0001F600-\U0001F64F"
34
+ "\U0001F680-\U0001F6FF"
35
+ "\U0001F700-\U0001F77F"
36
+ "\U0001F780-\U0001F7FF"
37
+ "\U0001F800-\U0001F8FF"
38
+ "\U0001F900-\U0001F9FF"
39
+ "\U0001FA00-\U0001FA6F"
40
+ "\U0001FA70-\U0001FAFF"
41
+ "\U00002600-\U000026FF" # misc symbols
42
+ "\U000023F0-\U000023FA" # clocks/media
43
+ "\U00002700-\U000027BF" # dingbats
44
+ "\U0001F1E6-\U0001F1FF" # regional indicator (ธง)
45
+ "\U0001F3FB-\U0001F3FF" # skin tones
46
+ "]",
47
+ flags=re.UNICODE
48
+ )
49
+
50
+ def strip_emoji(s: str) -> str:
51
+ # ตัด emoji ออก + เอา ZWJ/VS-16 ที่หลงเหลือออก + จัดช่องว่างให้เรียบ
52
+ s = EMOJI_RE.sub("", s)
53
+ s = s.replace("\u200d", "").replace("\ufe0f", "")
54
+ return re.sub(r"\s{2,}", " ", s).strip()
55
+
56
  # Map format → Azure SDK OutputFormat
57
  FORMAT_MAP = {
58
  "wav": speechsdk.SpeechSynthesisOutputFormat.Riff16Khz16BitMonoPcm,
59
  "mp3": speechsdk.SpeechSynthesisOutputFormat.Audio16Khz32KBitRateMonoMp3,
 
 
60
  }
61
 
62
  @app.get("/")
 
72
  text: str = Body(..., embed=True, description="ข้อความที่จะสังเคราะห์เสียง"),
73
  voice: Optional[str] = Body(DEFAULT_VOICE, embed=True),
74
  audio_format: Optional[str] = Body("mp3", embed=True, description="mp3 หรือ wav"),
75
+ # ถ้าต้องการสวิตช์ได้ ก็เปิดพารามิเตอร์นี้ (ค่าเริ่มต้น True = ไม่อ่านอิโมจิ)
76
+ strip_emoji_before_tts: Optional[bool] = Body(True, embed=True)
77
  ):
78
  """
79
  คืน audio bytes เป็น StreamingResponse (Content-Type ตามฟอร์แมต)
 
91
  speech_config.speech_synthesis_voice_name = voice or DEFAULT_VOICE
92
  speech_config.set_speech_synthesis_output_format(FORMAT_MAP[audio_format])
93
 
94
+ # 2) เตรียข้อความำหรับ TTS (ลบอิโจิออกเฉพะตอสังเคราะห์เสียง)
95
+ text_for_tts = strip_emoji(text) if strip_emoji_before_tts else text
96
+ if not text_for_tts:
97
+ raise HTTPException(status_code=400, detail="Text contains only emojis after sanitization")
98
+
99
+ # 3) ไม่ส่ง audio_config -> จะได้ audio bytes กลับมาใน result.audio_data
100
  synthesizer = speechsdk.SpeechSynthesizer(speech_config=speech_config, audio_config=None)
101
 
102
+ # 4) สังเคราะห์
103
+ result = synthesizer.speak_text_async(text_for_tts).get()
104
 
105
  if result.reason == speechsdk.ResultReason.SynthesizingAudioCompleted:
106
  audio_bytes = result.audio_data # bytes
 
131
 
132
  @app.get("/voices")
133
  def list_voices():
 
 
 
134
  if not AZURE_SPEECH_KEY:
135
  raise HTTPException(status_code=500, detail="AZURE_SPEECH_KEY not set")
136
 
 
143
  voices = []
144
  for v in voices_result.voices:
145
  voices.append({
146
+ "name": v.name,
147
+ "locale": v.locale,
148
  "gender": v.gender.name if v.gender else None,
149
  "shortName": getattr(v, "short_name", None)
150
  })
 
154
 
155
  except Exception as e:
156
  raise HTTPException(status_code=500, detail=str(e))
157
+