Spaces:
Sleeping
Sleeping
Update app.py
Browse files
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
|