hivecorp commited on
Commit
224a44e
·
verified ·
1 Parent(s): 3f3ae3e

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +89 -64
app.py CHANGED
@@ -1,82 +1,107 @@
1
- import os
2
  import requests
 
3
  import uvicorn
4
- from fastapi import FastAPI
5
- from pydub import AudioSegment
6
  from uuid import uuid4
 
7
 
8
  app = FastAPI()
9
 
10
- # Your first Hugging Face TTS API URL
11
- TTS_API_URL = "https://hivecorp-s8test.hf.space/tts"
12
- MAX_LENGTH = 250 # Max characters per chunk
13
-
14
-
15
- def split_text(text, max_length=MAX_LENGTH):
16
- """Splits text into smaller chunks at sentence boundaries."""
17
- chunks = []
18
- current_chunk = ""
19
- sentences = text.split(". ")
20
-
21
- for sentence in sentences:
22
- if len(current_chunk + sentence) > max_length:
23
- chunks.append(current_chunk.strip())
24
- current_chunk = ""
25
- current_chunk += sentence + ". "
26
-
27
- if current_chunk:
28
- chunks.append(current_chunk.strip())
29
-
 
30
  return chunks
31
 
32
-
33
  def call_tts_api(text, voice):
34
- """Calls the TTS API with the text & voice and returns the generated MP3 file."""
35
- response = requests.post(TTS_API_URL, json={"text": text, "voice": voice})
36
- if response.status_code == 200:
37
- filename = f"audio_{uuid4().hex}.mp3"
38
- with open(filename, "wb") as f:
39
- f.write(response.content)
40
- return filename
41
- return None
42
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  def merge_audio(files):
45
- """Merges multiple MP3 files into one using pydub."""
46
- final_audio = AudioSegment.empty()
47
-
48
- for file in files:
49
- audio = AudioSegment.from_file(file, format="mp3")
50
- final_audio += audio
51
-
52
- final_filename = "final_audio.mp3"
53
- final_audio.export(final_filename, format="mp3")
54
-
55
- # Cleanup temp files
56
- for file in files:
57
- os.remove(file)
58
-
59
- return final_filename
60
-
61
 
62
  @app.post("/generate-audio")
63
- async def generate_audio(text: str, voice: str):
64
- """Processes text, splits it, calls TTS API, and merges MP3s."""
65
- text_chunks = split_text(text)
66
- audio_files = [call_tts_api(chunk, voice) for chunk in text_chunks]
67
-
68
- if None in audio_files:
69
- return {"error": "TTS API failed for some parts"}
70
-
71
- merged_file = merge_audio(audio_files)
72
- return {"audio_url": f"/download/{merged_file}"}
73
-
 
 
 
 
 
 
 
 
 
 
74
 
75
  @app.get("/download/{filename}")
76
- async def download_file(filename: str):
77
- """Endpoint to download the merged MP3 file."""
78
- return {"file": filename}
79
-
 
 
 
80
 
81
  # Ensure the app starts when running in Hugging Face Spaces
82
  if __name__ == "__main__":
 
1
+ from fastapi import FastAPI, Query
2
  import requests
3
+ import os
4
  import uvicorn
 
 
5
  from uuid import uuid4
6
+ from pydub import AudioSegment
7
 
8
  app = FastAPI()
9
 
10
+ TTS_API_URL = "https://hivecorp-s8test.hf.space/generate" # Replace with your TTS API URL
11
+ SAVE_DIR = "generated_audios"
12
+
13
+ # Ensure save directory exists
14
+ os.makedirs(SAVE_DIR, exist_ok=True)
15
+
16
+ def split_text(text, max_length=500):
17
+ """Splits text into smaller chunks without breaking words."""
18
+ words = text.split()
19
+ chunks, chunk = [], []
20
+
21
+ for word in words:
22
+ if len(" ".join(chunk) + " " + word) <= max_length:
23
+ chunk.append(word)
24
+ else:
25
+ chunks.append(" ".join(chunk))
26
+ chunk = [word]
27
+
28
+ if chunk:
29
+ chunks.append(" ".join(chunk))
30
+
31
  return chunks
32
 
 
33
  def call_tts_api(text, voice):
34
+ """Sends text to TTS API and retries if it fails."""
35
+ filename = f"{SAVE_DIR}/audio_{uuid4().hex}.mp3"
36
+
37
+ try:
38
+ response = requests.post(TTS_API_URL, json={"text": text, "voice": voice})
39
+ response_data = response.json()
40
+ print("TTS API Response:", response_data) # Log response
41
+
42
+ if "audio_url" in response_data:
43
+ audio_url = response_data["audio_url"]
44
+ audio_data = requests.get(audio_url).content
45
+
46
+ with open(filename, "wb") as f:
47
+ f.write(audio_data)
48
+
49
+ return filename
50
+ else:
51
+ print("Error: TTS API did not return an audio URL!")
52
+ return None
53
+
54
+ except Exception as e:
55
+ print("Error calling TTS API:", str(e))
56
+ return None
57
 
58
  def merge_audio(files):
59
+ """Merges multiple MP3 files into one."""
60
+ output_file = f"{SAVE_DIR}/final_audio_{uuid4().hex}.mp3"
61
+
62
+ try:
63
+ combined = AudioSegment.from_file(files[0])
64
+
65
+ for file in files[1:]:
66
+ combined += AudioSegment.from_file(file)
67
+
68
+ combined.export(output_file, format="mp3")
69
+ return output_file
70
+ except Exception as e:
71
+ print("Error merging audio files:", str(e))
72
+ return None
 
 
73
 
74
  @app.post("/generate-audio")
75
+ def generate_audio(text: str = Query(...), voice: str = Query(...)):
76
+ """Splits text, calls TTS API, merges audio, and returns the final MP3."""
77
+ chunks = split_text(text)
78
+ print("Total Chunks:", len(chunks))
79
+
80
+ audio_files = []
81
+
82
+ for chunk in chunks:
83
+ filename = call_tts_api(chunk, voice)
84
+ if filename:
85
+ audio_files.append(filename)
86
+
87
+ if not audio_files:
88
+ return {"error": "TTS API failed for all parts"}
89
+
90
+ final_audio = merge_audio(audio_files)
91
+
92
+ if final_audio:
93
+ return {"success": True, "audio_url": f"/download/{os.path.basename(final_audio)}"}
94
+ else:
95
+ return {"error": "Failed to merge audio files"}
96
 
97
  @app.get("/download/{filename}")
98
+ def download_file(filename: str):
99
+ """Serves the generated MP3 file."""
100
+ file_path = os.path.join(SAVE_DIR, filename)
101
+ if os.path.exists(file_path):
102
+ return {"download_url": file_path}
103
+ else:
104
+ return {"error": "File not found"}
105
 
106
  # Ensure the app starts when running in Hugging Face Spaces
107
  if __name__ == "__main__":