first commit
This commit is contained in:
76
utils/audio.py
Normal file
76
utils/audio.py
Normal file
@ -0,0 +1,76 @@
|
||||
"""
|
||||
NovaAi – TTS-Engine-Hub
|
||||
utils/audio.py
|
||||
Version: v0.0.1
|
||||
|
||||
Description:
|
||||
Audio processing utilities: concat, merging chunks, etc.
|
||||
|
||||
Author: Abby (ChatGPT)
|
||||
Date: 2025-07-23
|
||||
Canvas: utils/audio.py
|
||||
"""
|
||||
|
||||
import tempfile
|
||||
import os
|
||||
import ffmpeg
|
||||
import shutil
|
||||
|
||||
def check_ffmpeg():
|
||||
"""Check if ffmpeg is installed and available in the system's PATH."""
|
||||
return shutil.which("ffmpeg") is not None
|
||||
|
||||
def concat_audio(files, fmt):
|
||||
"""
|
||||
Concatenate a list of audio files into a single file of the given format.
|
||||
Supports: wav, ogg, mp3
|
||||
"""
|
||||
if len(files) == 1:
|
||||
# If there's only one file, just return it, no cleanup needed here.
|
||||
return files[0]
|
||||
|
||||
# Securely create a temporary file for the output
|
||||
with tempfile.NamedTemporaryFile(suffix=f'.{fmt}', prefix="chunked_", delete=False) as temp_output_file:
|
||||
output_file_path = temp_output_file.name
|
||||
|
||||
try:
|
||||
if fmt == "wav":
|
||||
import wave
|
||||
data = []
|
||||
params = None
|
||||
for f in files:
|
||||
with wave.open(f, 'rb') as wf:
|
||||
if params is None:
|
||||
params = wf.getparams()
|
||||
data.append(wf.readframes(wf.getnframes()))
|
||||
with wave.open(output_file_path, 'wb') as wf:
|
||||
wf.setparams(params)
|
||||
for d in data:
|
||||
wf.writeframes(d)
|
||||
else:
|
||||
if not check_ffmpeg():
|
||||
raise RuntimeError("ffmpeg not found. Please install ffmpeg and ensure it is in your PATH.")
|
||||
|
||||
with tempfile.NamedTemporaryFile("w", delete=False) as tf:
|
||||
list_file_path = tf.name
|
||||
for f in files:
|
||||
tf.write(f"file '{os.path.abspath(f)}'\\n")
|
||||
tf.flush()
|
||||
|
||||
try:
|
||||
(
|
||||
ffmpeg
|
||||
.input(list_file_path, format='concat', safe=0)
|
||||
.output(output_file_path, acodec='copy')
|
||||
.run(overwrite_output=True, quiet=True)
|
||||
)
|
||||
finally:
|
||||
os.unlink(list_file_path)
|
||||
|
||||
finally:
|
||||
# Clean up the input chunk files
|
||||
for f in files:
|
||||
if os.path.exists(f):
|
||||
os.remove(f)
|
||||
|
||||
return output_file_path
|
||||
22
utils/cache.py
Normal file
22
utils/cache.py
Normal file
@ -0,0 +1,22 @@
|
||||
"""
|
||||
NovaAi – TTS-Engine-Hub
|
||||
utils/cache.py
|
||||
Version: v0.0.1
|
||||
|
||||
Description:
|
||||
Caching utilities for TTS requests (cache key generation, etc).
|
||||
|
||||
Author: Abby (ChatGPT)
|
||||
Date: 2025-07-23
|
||||
Canvas: utils/cache.py
|
||||
"""
|
||||
|
||||
import hashlib
|
||||
|
||||
# Für die API: Wichtig! req muss mindestens die Felder .text, .engine, .model, .speaker, .format, .chunking haben.
|
||||
def build_cache_key(req) -> str:
|
||||
"""
|
||||
Build a cache key from all relevant TTS request parameters.
|
||||
"""
|
||||
data = f"{req.text}|{req.engine}|{req.model}|{req.speaker}|{req.format}|{getattr(req, 'chunking', False)}"
|
||||
return hashlib.sha256(data.encode()).hexdigest()
|
||||
30
utils/text.py
Normal file
30
utils/text.py
Normal file
@ -0,0 +1,30 @@
|
||||
"""
|
||||
NovaAi – TTS-Engine-Hub
|
||||
utils/text.py
|
||||
Version: v0.0.1
|
||||
|
||||
Description:
|
||||
Text processing utilities: chunking, splitting, etc.
|
||||
|
||||
Author: Abby (ChatGPT)
|
||||
Date: 2025-07-23
|
||||
Canvas: utils/text.py
|
||||
"""
|
||||
|
||||
def chunk_text(text, maxlen=250):
|
||||
"""
|
||||
Split text into chunks of roughly maxlen (split at sentence boundaries if possible).
|
||||
"""
|
||||
import re
|
||||
sentences = re.split(r'([.!?]\s)', text)
|
||||
chunks = []
|
||||
buf = ""
|
||||
for s in sentences:
|
||||
if len(buf) + len(s) > maxlen:
|
||||
if buf:
|
||||
chunks.append(buf.strip())
|
||||
buf = ""
|
||||
buf += s
|
||||
if buf.strip():
|
||||
chunks.append(buf.strip())
|
||||
return [c for c in chunks if c.strip()]
|
||||
Reference in New Issue
Block a user