MariaKaiser commited on
Commit
fe0e5ad
·
verified ·
1 Parent(s): 79bfece

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +71 -0
app.py CHANGED
@@ -177,6 +177,77 @@ async def generate_story_audios(story: StoryCreationDTO, base_output: str = "sto
177
  )
178
  os.remove(prosody_file)
179
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
180
  app = FastAPI(title="EGTTS Arabic TTS API")
181
 
182
  #___________________Test end point to test supabase fetch
 
177
  )
178
  os.remove(prosody_file)
179
 
180
+ #_______________ Concatenating the generated audios to make the final story (post-processing)_______________________
181
+
182
+ from pydub import AudioSegment
183
+ import asyncio
184
+
185
+ async def concat_story_audio(story: StoryCreationDTO, base_output="stories", final_path: str = None,): # full path including filename
186
+ story_dir = Path(base_output) / story.storyId
187
+ story_dir.mkdir(parents=True, exist_ok=True)
188
+
189
+ if final_path is None:
190
+ final_path = story_dir / f"{story.storyId}_full.wav"
191
+ else:
192
+ final_path = Path(final_path)
193
+ final_path.parent.mkdir(parents=True, exist_ok=True) # ensure folder exists
194
+
195
+ chapters_audio = AudioSegment.silent(duration=0) # start empty
196
+
197
+ for chapter in story.chapters:
198
+ chapter_dir = story_dir / chapter.chapterId
199
+
200
+ # --- Chapter title ---
201
+ title_path = chapter_dir / "title.wav"
202
+ chapter_audio = AudioSegment.from_wav(title_path)
203
+
204
+ for scene in chapter.scenes:
205
+ scene_dir = chapter_dir / scene.sceneId
206
+ scene_audio = AudioSegment.silent(duration=0)
207
+
208
+ # --- Concatenate sentence audios ---
209
+ for sentence in scene.sentences:
210
+ sentence_path = scene_dir / f"{sentence.sentenceId}.wav"
211
+ sentence_audio = AudioSegment.from_wav(sentence_path)
212
+ scene_audio += sentence_audio
213
+
214
+ # --- Add SFX for location if available ---
215
+ if scene.locationName:
216
+ sfx_file = await download_file_from_url(scene.locationName)
217
+ sfx_audio = AudioSegment.from_wav(sfx_file)
218
+ scene_audio = scene_audio.overlay(sfx_audio)
219
+ os.remove(sfx_file)
220
+
221
+ # --- Add background music if available ---
222
+ if scene.bgMusic and scene.bgMusic.musicPath:
223
+ bg_url = scene.bgMusic.musicPath
224
+ bg_file = await download_file_from_url(bg_url)
225
+ bg_audio = AudioSegment.from_wav(bg_file)
226
+
227
+ # Adjust volume
228
+ bg_audio = bg_audio - (1 - scene.bgMusic.volume) * 30 # approximate
229
+ # Loop if shorter than scene
230
+ if len(bg_audio) < len(scene_audio):
231
+ loops = (len(scene_audio) // len(bg_audio)) + 1
232
+ bg_audio = bg_audio * loops
233
+ bg_audio = bg_audio[:len(scene_audio)] # trim to match scene
234
+ scene_audio = scene_audio.overlay(bg_audio)
235
+ os.remove(bg_file)
236
+
237
+ # Add 2 seconds of silence between scenes
238
+ scene_audio += AudioSegment.silent(duration=2000)
239
+ chapter_audio += scene_audio
240
+
241
+ # Add 3 seconds of silence between chapters
242
+ chapter_audio += AudioSegment.silent(duration=3000)
243
+ chapters_audio += chapter_audio
244
+
245
+ # Export final story
246
+ chapters_audio.export(final_path, format="wav")
247
+ return final_path
248
+
249
+ #-------------------------------------------------------------
250
+
251
  app = FastAPI(title="EGTTS Arabic TTS API")
252
 
253
  #___________________Test end point to test supabase fetch