Update util.py

This commit is contained in:
None 2025-04-16 10:20:13 +02:00 committed by GitHub
parent 2ebcc2eaad
commit a4fe75b9fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -130,61 +130,62 @@ def print_duration_table(file_path: str, description: str = "Duration", return_s
def get_ffprobe_info(file_path): def get_ffprobe_info(file_path):
""" """Get format and codec information for a media file using ffprobe."""
Get format and codec information for a media file using ffprobe.
Parameters:
- file_path (str): Path to the media file.
Returns:
dict: A dictionary containing the format name and a list of codec names.
Returns None if file does not exist or ffprobe crashes.
"""
if not os.path.exists(file_path): if not os.path.exists(file_path):
logging.error(f"File not found: {file_path}") logging.error(f"File not found: {file_path}")
return None return None
# Get ffprobe path and verify it exists
ffprobe_path = get_ffprobe_path()
if not ffprobe_path or not os.path.exists(ffprobe_path):
logging.error(f"FFprobe not found at path: {ffprobe_path}")
return None
# Verify file permissions
try: try:
# Use subprocess.Popen instead of run to better handle crashes file_stat = os.stat(file_path)
cmd = [get_ffprobe_path(), '-v', 'error', '-show_format', '-show_streams', '-print_format', 'json', file_path] logging.info(f"File permissions: {oct(file_stat.st_mode)}")
logging.info(f"FFmpeg command: {cmd}") if not os.access(file_path, os.R_OK):
logging.error(f"No read permission for file: {file_path}")
return None
except OSError as e:
logging.error(f"Cannot access file {file_path}: {e}")
return None
with subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True) as proc: try:
stdout, stderr = proc.communicate() cmd = [ffprobe_path, '-v', 'error', '-show_format', '-show_streams', '-print_format', 'json', file_path]
logging.info(f"Running FFprobe command: {' '.join(cmd)}")
if proc.returncode != 0: # Use subprocess.run instead of Popen for better error handling
logging.error(f"FFprobe failed with return code {proc.returncode} for file {file_path}") result = subprocess.run(
if stderr: cmd,
logging.error(f"FFprobe stderr: {stderr}") capture_output=True,
return { text=True,
'format_name': None, check=False # Don't raise exception on non-zero exit
'codec_names': [] )
}
# Make sure we have valid JSON before parsing if result.returncode != 0:
if not stdout or not stdout.strip(): logging.error(f"FFprobe failed with return code {result.returncode}")
logging.warning(f"FFprobe returned empty output for file {file_path}") logging.error(f"FFprobe stderr: {result.stderr}")
return { logging.error(f"FFprobe stdout: {result.stdout}")
'format_name': None, logging.error(f"Command: {' '.join(cmd)}")
'codec_names': [] logging.error(f"FFprobe path permissions: {oct(os.stat(ffprobe_path).st_mode)}")
} return None
info = json.loads(stdout)
format_name = info['format']['format_name'] if 'format' in info else None
codec_names = [stream['codec_name'] for stream in info['streams']] if 'streams' in info else []
# Parse JSON output
try:
info = json.loads(result.stdout)
return { return {
'format_name': format_name, 'format_name': info.get('format', {}).get('format_name'),
'codec_names': codec_names 'codec_names': [stream.get('codec_name') for stream in info.get('streams', [])]
} }
except json.JSONDecodeError as e:
logging.error(f"Failed to parse FFprobe output: {e}")
return None
except Exception as e: except Exception as e:
logging.error(f"Failed to get ffprobe info for file {file_path}: {e}") logging.error(f"FFprobe execution failed: {e}")
return { return None
'format_name': None,
'codec_names': []
}
def is_png_format_or_codec(file_info): def is_png_format_or_codec(file_info):