import shutil import subprocess from pathlib import Path class MediaService: def planned_mp3_path(self, wav_path: str) -> str: path = Path(wav_path) return str(path.with_suffix('.mp3')) def conversion_command(self, wav_path: str, mp3_path: str) -> list[str]: return [ 'ffmpeg', '-y', '-i', wav_path, '-codec:a', 'libmp3lame', '-q:a', '2', mp3_path, ] def ffmpeg_path(self) -> str | None: return shutil.which('ffmpeg') def can_convert(self) -> bool: return self.ffmpeg_path() is not None def convert_wav_to_mp3(self, wav_path: str, mp3_path: str) -> dict: if not self.can_convert(): return { 'status': 'blocked', 'reason': 'ffmpeg-not-installed', 'command': self.conversion_command(wav_path, mp3_path), } cmd = self.conversion_command(wav_path, mp3_path) result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode != 0: return { 'status': 'failed', 'returncode': result.returncode, 'stderr': result.stderr[-4000:], 'stdout': result.stdout[-2000:], 'command': cmd, } return { 'status': 'ok', 'mp3_path': mp3_path, 'command': cmd, } def delete_source_if_requested(self, wav_path: str, should_delete: bool) -> dict: if not should_delete: return {'status': 'skipped', 'reason': 'delete-not-requested'} path = Path(wav_path) if not path.exists(): return {'status': 'skipped', 'reason': 'source-missing'} path.unlink() return {'status': 'ok', 'deleted': wav_path}