refactor: Update video_analyzer to use ffprobe directly

- Removed dependency on ffmpeg-python package
- Added direct ffprobe command execution
- Improved error handling and logging
- Better organization of analysis methods
This commit is contained in:
pacnpal
2024-11-14 22:36:01 +00:00
parent 9beda06e34
commit 4719f567c6

View File

@@ -3,12 +3,12 @@
import os import os
import subprocess import subprocess
import logging import logging
import ffmpeg
from pathlib import Path from pathlib import Path
from typing import Dict, Any from typing import Dict, Any
from contextlib import contextmanager from contextlib import contextmanager
import tempfile import tempfile
import shutil import shutil
import json
logger = logging.getLogger("VideoArchiver") logger = logging.getLogger("VideoArchiver")
@@ -32,15 +32,24 @@ class VideoAnalyzer:
def analyze_video(self, input_path: str) -> Dict[str, Any]: def analyze_video(self, input_path: str) -> Dict[str, Any]:
"""Analyze video content for optimal encoding settings""" """Analyze video content for optimal encoding settings"""
try: try:
probe = ffmpeg.probe(input_path) # Use ffprobe to get video information
video_info = next(s for s in probe["streams"] if s["codec_type"] == "video") probe_result = self._probe_video(input_path)
if not probe_result:
return {}
video_info = next(
(s for s in probe_result["streams"] if s["codec_type"] == "video"),
None
)
if not video_info:
return {}
# Get video properties # Get video properties
width = int(video_info.get("width", 0)) width = int(video_info.get("width", 0))
height = int(video_info.get("height", 0)) height = int(video_info.get("height", 0))
fps = eval(video_info.get("r_frame_rate", "30/1")) fps = eval(video_info.get("r_frame_rate", "30/1"))
duration = float(probe["format"].get("duration", 0)) duration = float(probe_result["format"].get("duration", 0))
bitrate = float(probe["format"].get("bit_rate", 0)) bitrate = float(probe_result["format"].get("bit_rate", 0))
# Advanced analysis # Advanced analysis
has_high_motion = self._detect_high_motion(video_info) has_high_motion = self._detect_high_motion(video_info)
@@ -48,7 +57,7 @@ class VideoAnalyzer:
# Get audio properties # Get audio properties
audio_info = next( audio_info = next(
(s for s in probe["streams"] if s["codec_type"] == "audio"), (s for s in probe_result["streams"] if s["codec_type"] == "audio"),
None None
) )
audio_props = self._get_audio_properties(audio_info) audio_props = self._get_audio_properties(audio_info)
@@ -69,6 +78,29 @@ class VideoAnalyzer:
logger.error(f"Error analyzing video: {str(e)}") logger.error(f"Error analyzing video: {str(e)}")
return {} return {}
def _probe_video(self, input_path: str) -> Dict:
"""Use ffprobe to get video information"""
try:
cmd = [
str(self.ffmpeg_path).replace('ffmpeg', 'ffprobe'),
"-v", "quiet",
"-print_format", "json",
"-show_format",
"-show_streams",
input_path
]
result = subprocess.run(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
if result.returncode == 0:
return json.loads(result.stdout)
except Exception as e:
logger.error(f"Error probing video: {str(e)}")
return {}
def _detect_high_motion(self, video_info: Dict) -> bool: def _detect_high_motion(self, video_info: Dict) -> bool:
"""Detect high motion content based on frame rate analysis""" """Detect high motion content based on frame rate analysis"""
try: try: