StoryLens / video_loader.py
Marek4321's picture
Upload 13 files
6bdfadc verified
import tempfile
import os
import subprocess
import json
import shutil
from typing import Optional
import yt_dlp
class VideoLoader:
def __init__(self):
self.temp_dir = tempfile.mkdtemp()
def load_youtube(self, url: str) -> Optional[str]:
"""
Download YouTube video.
Args:
url: YouTube URL
Returns:
Path to downloaded video file, or None if failed
"""
output_path = os.path.join(self.temp_dir, "video.mp4")
ydl_opts = {
'format': 'bestvideo[ext=mp4]+bestaudio[ext=m4a]/bestvideo+bestaudio/best',
'outtmpl': output_path,
'merge_output_format': 'mp4',
'quiet': True,
'no_warnings': True,
'postprocessors': [{
'key': 'FFmpegVideoConvertor',
'preferedformat': 'mp4',
}],
}
try:
with yt_dlp.YoutubeDL(ydl_opts) as ydl:
ydl.download([url])
return output_path
except Exception as e:
print(f"Error downloading YouTube video: {e}")
return None
def load_local(self, uploaded_file) -> Optional[str]:
"""
Save uploaded file to temp directory.
Args:
uploaded_file: Streamlit UploadedFile object
Returns:
Path to saved file
"""
output_path = os.path.join(self.temp_dir, uploaded_file.name)
with open(output_path, "wb") as f:
f.write(uploaded_file.read())
return output_path
def get_video_duration(self, video_path: str) -> float:
"""Get video duration in seconds using ffprobe."""
cmd = [
'ffprobe', '-v', 'quiet', '-print_format', 'json',
'-show_format', video_path
]
result = subprocess.run(cmd, capture_output=True, text=True)
data = json.loads(result.stdout)
return float(data['format']['duration'])
def cleanup(self):
"""Remove temp files."""
if os.path.exists(self.temp_dir):
shutil.rmtree(self.temp_dir)