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