Spaces:
Running
Running
File size: 4,652 Bytes
952467c |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 |
"""
Audio extraction utilities for the video translator application.
"""
import os
import subprocess
from pathlib import Path
from src.utils.logger import get_logger
from config import OUTPUT_DIR, FFMPEG_AUDIO_PARAMS
logger = get_logger(__name__)
def extract_audio(video_path):
"""
Extract audio from video file using ffmpeg.
Args:
video_path (str): Path to the input video file
Returns:
Path: Path to the extracted audio file
Raises:
Exception: If audio extraction fails
"""
try:
video_path = Path(video_path)
logger.info(f"Extracting audio from video: {video_path}")
# Create output filename based on input filename
video_name = video_path.stem
audio_path = OUTPUT_DIR / f"{video_name}_audio.{FFMPEG_AUDIO_PARAMS['format']}"
# Use ffmpeg to extract audio
cmd = [
'ffmpeg',
'-i', str(video_path),
'-vn', # No video
'-acodec', FFMPEG_AUDIO_PARAMS['codec'],
'-ar', str(FFMPEG_AUDIO_PARAMS['sample_rate']),
'-ac', str(FFMPEG_AUDIO_PARAMS['channels']),
'-y', # Overwrite output file
str(audio_path)
]
logger.debug(f"Running command: {' '.join(cmd)}")
process = subprocess.run(cmd, capture_output=True, text=True)
if process.returncode != 0:
error_message = f"Audio extraction failed: {process.stderr}"
logger.error(error_message)
raise Exception(error_message)
logger.info(f"Audio extraction successful: {audio_path}")
return audio_path
except Exception as e:
logger.error(f"Audio extraction failed: {str(e)}", exc_info=True)
raise Exception(f"Audio extraction failed: {str(e)}")
def get_video_duration(video_path):
"""
Get the duration of a video file in seconds.
Args:
video_path (str): Path to the video file
Returns:
float: Duration in seconds
Raises:
Exception: If duration extraction fails
"""
try:
video_path = Path(video_path)
logger.info(f"Getting duration for video: {video_path}")
cmd = [
'ffprobe',
'-v', 'error',
'-show_entries', 'format=duration',
'-of', 'default=noprint_wrappers=1:nokey=1',
str(video_path)
]
process = subprocess.run(cmd, capture_output=True, text=True)
if process.returncode != 0 or not process.stdout.strip():
error_message = f"Failed to get video duration: {process.stderr}"
logger.error(error_message)
raise Exception(error_message)
duration = float(process.stdout.strip())
logger.info(f"Video duration: {duration} seconds")
return duration
except Exception as e:
logger.error(f"Failed to get video duration: {str(e)}", exc_info=True)
raise Exception(f"Failed to get video duration: {str(e)}")
def create_silent_audio(duration, output_path=None):
"""
Create a silent audio file with the specified duration.
Args:
duration (float): Duration in seconds
output_path (str, optional): Path to save the silent audio file
Returns:
Path: Path to the silent audio file
Raises:
Exception: If silent audio creation fails
"""
try:
if output_path is None:
output_path = OUTPUT_DIR / f"silent_{int(duration)}s.wav"
else:
output_path = Path(output_path)
logger.info(f"Creating silent audio track of {duration} seconds")
cmd = [
'ffmpeg',
'-f', 'lavfi',
'-i', f'anullsrc=r={FFMPEG_AUDIO_PARAMS["sample_rate"]}:cl=stereo',
'-t', str(duration),
'-q:a', '0',
'-y',
str(output_path)
]
logger.debug(f"Running command: {' '.join(cmd)}")
process = subprocess.run(cmd, capture_output=True, text=True)
if process.returncode != 0:
error_message = f"Silent audio creation failed: {process.stderr}"
logger.error(error_message)
raise Exception(error_message)
logger.info(f"Silent audio created: {output_path}")
return output_path
except Exception as e:
logger.error(f"Failed to create silent audio: {str(e)}", exc_info=True)
raise Exception(f"Failed to create silent audio: {str(e)}")
|