100 lines
2.9 KiB
Python
100 lines
2.9 KiB
Python
from pathlib import Path
|
|
import shutil
|
|
import subprocess
|
|
import tempfile
|
|
|
|
try:
|
|
import imageio_ffmpeg
|
|
except ImportError:
|
|
imageio_ffmpeg = None
|
|
|
|
|
|
TARGET_SAMPLE_RATE = 22050
|
|
SUPPORTED_AUDIO_EXTENSIONS = {".wav", ".mp3", ".m4a", ".ogg", ".flac", ".webm", ".aac"}
|
|
|
|
|
|
def validate_audio_extension(file_path):
|
|
extension = Path(file_path).suffix.lower()
|
|
if extension not in SUPPORTED_AUDIO_EXTENSIONS:
|
|
allowed = ", ".join(sorted(SUPPORTED_AUDIO_EXTENSIONS)).upper().replace(".", "")
|
|
raise ValueError(f"Format audio tidak didukung: {extension}. Format yang didukung: {allowed}")
|
|
|
|
|
|
def create_temp_wav_path():
|
|
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix=".wav")
|
|
temp_path = Path(temp_file.name)
|
|
temp_file.close()
|
|
return temp_path
|
|
|
|
|
|
def configure_ffmpeg():
|
|
if imageio_ffmpeg is None:
|
|
raise RuntimeError(
|
|
"ffmpeg belum tersedia. Jalankan `pip install imageio-ffmpeg` "
|
|
"di virtual environment backend."
|
|
)
|
|
try:
|
|
return imageio_ffmpeg.get_ffmpeg_exe()
|
|
except Exception as error:
|
|
raise RuntimeError(
|
|
"ffmpeg belum tersedia. Jalankan `pip install imageio-ffmpeg` "
|
|
"atau install ffmpeg di sistem operasi."
|
|
) from error
|
|
|
|
|
|
def convert_audio_to_wav(input_path, output_path=None):
|
|
input_path = Path(input_path)
|
|
validate_audio_extension(input_path)
|
|
|
|
if not input_path.exists():
|
|
raise FileNotFoundError(f"File audio tidak ditemukan: {input_path}")
|
|
|
|
if input_path.suffix.lower() == ".wav" and output_path is None:
|
|
return input_path
|
|
|
|
output_path = Path(output_path) if output_path else create_temp_wav_path()
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
if input_path.suffix.lower() == ".wav":
|
|
if input_path.resolve() != output_path.resolve():
|
|
shutil.copyfile(input_path, output_path)
|
|
return output_path
|
|
|
|
command = [
|
|
configure_ffmpeg(),
|
|
"-y",
|
|
"-i",
|
|
str(input_path),
|
|
"-vn",
|
|
"-ac",
|
|
"1",
|
|
"-ar",
|
|
str(TARGET_SAMPLE_RATE),
|
|
"-f",
|
|
"wav",
|
|
str(output_path),
|
|
]
|
|
|
|
try:
|
|
result = subprocess.run(command, capture_output=True, text=True, check=False)
|
|
except FileNotFoundError as error:
|
|
raise RuntimeError(
|
|
"ffmpeg tidak bisa dijalankan. Pastikan dependency `imageio-ffmpeg` "
|
|
"sudah terpasang di virtual environment backend."
|
|
) from error
|
|
|
|
if result.returncode != 0:
|
|
error_message = result.stderr.strip() or "Tidak ada detail error dari ffmpeg."
|
|
raise RuntimeError(f"Konversi audio gagal: {error_message}")
|
|
|
|
if not output_path.exists():
|
|
raise RuntimeError("Konversi audio gagal: file WAV output tidak terbentuk.")
|
|
|
|
return output_path
|
|
|
|
|
|
def cleanup_temp_files(*paths):
|
|
for path in paths:
|
|
if path:
|
|
Path(path).unlink(missing_ok=True)
|