hivecorp commited on
Commit
366652b
·
verified ·
1 Parent(s): 9e1fa9a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +30 -67
app.py CHANGED
@@ -1,20 +1,14 @@
1
- from fastapi import FastAPI
2
- import edge_tts
3
- import asyncio
4
  import os
5
  import time
6
- import io
7
- from fastapi.responses import StreamingResponse
8
- from tempfile import TemporaryDirectory
9
- from pydub import AudioSegment
10
 
11
  app = FastAPI()
12
 
13
  def split_text(text, max_chunk_size=500):
14
- """Split text into chunks if it exceeds max_chunk_size."""
15
- if len(text) <= max_chunk_size:
16
- return [text]
17
-
18
  sentences = text.replace('।', '.').replace('؟', '?').split('.')
19
  chunks = []
20
  current_chunk = []
@@ -38,71 +32,40 @@ def split_text(text, max_chunk_size=500):
38
  return chunks
39
 
40
  async def process_chunk(text, voice, temp_dir, chunk_index):
41
- """Process a single chunk into an MP3 file."""
42
- tmp_path = os.path.join(temp_dir, f"chunk_{chunk_index}_{int(time.time())}.mp3")
 
43
  communicate = edge_tts.Communicate(text, voice)
44
  await communicate.save(tmp_path)
45
  return tmp_path
46
 
47
- async def combine_audio_files(chunk_files):
48
- """Combine multiple MP3 files into one final MP3 file."""
 
 
49
  combined = AudioSegment.empty()
50
-
51
  for file in chunk_files:
52
- audio_segment = AudioSegment.from_mp3(file)
53
- combined += audio_segment
54
 
55
- output = io.BytesIO()
56
- combined.export(output, format="mp3")
57
- output.seek(0)
58
 
59
- # Cleanup chunk files
60
  for file in chunk_files:
61
- try:
62
- os.remove(file)
63
- except:
64
- pass
65
-
66
- return output
67
-
68
- @app.get("/")
69
- def home():
70
- return {"message": "EdgeTTS FastAPI is running!"}
71
 
72
  @app.get("/tts")
73
  async def tts(text: str, voice: str = "en-US-AriaNeural"):
74
- if not text.strip():
75
- return {"error": "Text cannot be empty."}
76
-
77
- text_chunks = split_text(text) # Only splits if text > 500 characters
78
-
79
- async def event_stream():
80
- """Send real-time status updates to the client while processing."""
81
- yield "Processing started...\n"
82
-
83
- if len(text_chunks) == 1:
84
- # Single request processing
85
- output_audio = io.BytesIO()
86
- communicate = edge_tts.Communicate(text_chunks[0], voice)
87
- await communicate.save(output_audio)
88
- output_audio.seek(0)
89
- yield "Processing completed. Downloading audio...\n"
90
- yield output_audio.read()
91
- return
92
-
93
- with TemporaryDirectory() as temp_dir:
94
- # Process all chunks concurrently
95
- tasks = [process_chunk(chunk, voice, temp_dir, i) for i, chunk in enumerate(text_chunks)]
96
- chunk_files = await asyncio.gather(*tasks)
97
-
98
- yield f"Processing {len(text_chunks)} chunks completed. Merging audio...\n"
99
- output_audio = await combine_audio_files(chunk_files)
100
-
101
- yield "Merging completed. Downloading final audio...\n"
102
- yield output_audio.read()
103
-
104
- return StreamingResponse(event_stream(), media_type="audio/mpeg")
105
-
106
- if __name__ == "__main__":
107
- import uvicorn
108
- uvicorn.run(app, host="0.0.0.0", port=7860)
 
 
 
 
1
  import os
2
  import time
3
+ import asyncio
4
+ from fastapi import FastAPI
5
+ import edge_tts
6
+ from fastapi.responses import FileResponse
7
 
8
  app = FastAPI()
9
 
10
  def split_text(text, max_chunk_size=500):
11
+ """Split text into smaller chunks."""
 
 
 
12
  sentences = text.replace('।', '.').replace('؟', '?').split('.')
13
  chunks = []
14
  current_chunk = []
 
32
  return chunks
33
 
34
  async def process_chunk(text, voice, temp_dir, chunk_index):
35
+ """Process a single chunk of text."""
36
+ tmp_path = os.path.join(temp_dir, f"chunk_{chunk_index}.mp3")
37
+ print(f"🎤 Processing chunk {chunk_index}: {text[:50]}...") # Logging
38
  communicate = edge_tts.Communicate(text, voice)
39
  await communicate.save(tmp_path)
40
  return tmp_path
41
 
42
+ async def combine_audio_files(chunk_files, output_path):
43
+ """Combine multiple MP3 files into one."""
44
+ from pydub import AudioSegment
45
+
46
  combined = AudioSegment.empty()
 
47
  for file in chunk_files:
48
+ print(f"🔹 Adding {file} to final output") # Logging
49
+ combined += AudioSegment.from_mp3(file)
50
 
51
+ combined.export(output_path, format="mp3")
 
 
52
 
 
53
  for file in chunk_files:
54
+ os.remove(file)
 
 
 
 
 
 
 
 
 
55
 
56
  @app.get("/tts")
57
  async def tts(text: str, voice: str = "en-US-AriaNeural"):
58
+ """Main API function to process TTS."""
59
+ temp_dir = "temp_audio"
60
+ os.makedirs(temp_dir, exist_ok=True)
61
+ chunks = split_text(text)
62
+
63
+ if len(chunks) == 1:
64
+ return await FileResponse(await process_chunk(text, voice, temp_dir, 0), media_type="audio/mpeg", filename="speech.mp3")
65
+
66
+ chunk_files = await asyncio.gather(*[process_chunk(ch, voice, temp_dir, i) for i, ch in enumerate(chunks)])
67
+
68
+ output_file = "final_output.mp3"
69
+ await combine_audio_files(chunk_files, output_file)
70
+
71
+ return FileResponse(output_file, media_type="audio/mpeg", filename="speech.mp3")