|
import os |
|
import subprocess |
|
import uuid |
|
|
|
def download_video(video_url, task_id, temp_dir): |
|
""" |
|
Downloads a video from the given URL to a temporary file. |
|
Uses yt-dlp for robust video downloading. |
|
Returns the path to the downloaded video or None if an error occurs. |
|
""" |
|
video_path = None |
|
try: |
|
print(f"Task {task_id}: Starting video download for {video_url}") |
|
|
|
|
|
|
|
normalized_temp_dir = os.path.abspath(temp_dir) |
|
os.makedirs(normalized_temp_dir, exist_ok=True) |
|
|
|
|
|
video_filename = f"video_{uuid.uuid4()}.mp4" |
|
video_path = os.path.join(normalized_temp_dir, video_filename) |
|
|
|
|
|
|
|
|
|
print(f"Task {task_id}: Ensuring directory exists for video: {os.path.dirname(video_path)}") |
|
print(f"Task {task_id}: Attempting to write video to: {video_path}") |
|
|
|
|
|
|
|
yt_dlp_options = { |
|
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/best[ext=mp4]/best', |
|
'outtmpl': video_path, |
|
'noplaylist': True, |
|
'quiet': True, |
|
'no_warnings': True, |
|
} |
|
|
|
|
|
command = ['yt-dlp', '-f', yt_dlp_options['format'], '-o', yt_dlp_options['outtmpl'], video_url] |
|
if yt_dlp_options['noplaylist']: |
|
command.append('--no-playlist') |
|
if yt_dlp_options['quiet']: |
|
command.append('--quiet') |
|
if yt_dlp_options['no_warnings']: |
|
command.append('--no-warnings') |
|
|
|
print(f"Task {task_id}: yt-dlp command: {' '.join(command)}") |
|
|
|
process = subprocess.run(command, capture_output=True, text=True, check=False) |
|
|
|
if process.returncode != 0: |
|
error_message = f"yt-dlp failed: {process.stderr.strip()}" |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
if not os.path.exists(video_path) or os.path.getsize(video_path) == 0: |
|
error_message = "Video download failed or resulted in an empty file." |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
print(f"Task {task_id}: Video downloaded to {video_path}") |
|
return video_path, None |
|
|
|
except Exception as e: |
|
error_message = f"An error occurred during video download: {e}" |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
|
|
def extract_audio(video_path, task_id, temp_dir): |
|
""" |
|
Extracts audio from the given video file to a temporary WAV file. |
|
Uses FFmpeg for robust audio extraction and conversion. |
|
Returns the path to the extracted audio or None if an error occurs. |
|
""" |
|
audio_path = None |
|
try: |
|
print(f"Task {task_id}: Extracting audio from video...") |
|
|
|
audio_filename = f"audio_{uuid.uuid4()}.wav" |
|
audio_path = os.path.join(temp_dir, audio_filename) |
|
|
|
|
|
ffmpeg_command = [ |
|
'ffmpeg', '-i', video_path, '-ar', '16000', '-ac', '1', '-vn', '-y', audio_path |
|
] |
|
print(f"Task {task_id}: FFmpeg command: {' '.join(ffmpeg_command)}") |
|
process = subprocess.run(ffmpeg_command, capture_output=True, text=True, check=False) |
|
|
|
if process.returncode != 0: |
|
error_message = f"FFmpeg audio extraction failed: {process.stderr.strip()}" |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
if not os.path.exists(audio_path) or os.path.getsize(audio_path) == 0: |
|
error_message = "Audio extraction failed or resulted in an empty file." |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
print(f"Task {task_id}: Audio extracted to {audio_path}") |
|
return audio_path, None |
|
|
|
except Exception as e: |
|
error_message = f"An error occurred during audio extraction: {e}" |
|
print(f"Task {task_id}: {error_message}") |
|
return None, error_message |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|