""" 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