108 lines
3.9 KiB
Python
108 lines
3.9 KiB
Python
import os
|
|
import subprocess
|
|
import sys
|
|
|
|
import utils
|
|
import config
|
|
|
|
def convert_video(
|
|
input_file_path,
|
|
output_dir,
|
|
quality_level=config.DEFAULT_QUALITY_LEVEL,
|
|
video_codec=config.DEFAULT_VIDEO_CODEC,
|
|
audio_codec=config.DEFAULT_AUDIO_CODEC,
|
|
output_suffix=config.OUTPUT_SUFFIX,
|
|
output_prefix=config.OUTPUT_PREFIX,
|
|
output_ext=config.DEFAULT_CONTAINER
|
|
):
|
|
"""Converts a video file to a DaVinci Resolve compatible format."""
|
|
print(f"Analyzing input file: {input_file_path}")
|
|
video_info = utils.get_video_info(input_file_path)
|
|
audio_info = utils.get_audio_info(input_file_path)
|
|
|
|
if not video_info or not video_info.get("streams"):
|
|
print("Error: Could not retrieve video stream information. Aborting conversion.", file=sys.stderr)
|
|
return False
|
|
|
|
# Extract relevant video stream info
|
|
try:
|
|
v_stream = video_info["streams"][0]
|
|
width = v_stream["width"]
|
|
height = v_stream["height"]
|
|
except (KeyError, IndexError) as e:
|
|
print(f"Error parsing video stream info: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
# Determine video profile based on resolution and quality level
|
|
target_resolution_key = '1080p'
|
|
if height > 1080:
|
|
target_resolution_key = '1440p'
|
|
|
|
video_profile = config.DNXHD_PROFILES[quality_level][target_resolution_key]
|
|
|
|
output_file_path = utils.generate_output_path(
|
|
input_file_path, output_dir, output_suffix, output_prefix, output_ext
|
|
)
|
|
|
|
# Fail-safe: Generate unique filename if target already exists
|
|
counter = 0
|
|
original_output_file_path = output_file_path
|
|
while os.path.exists(output_file_path):
|
|
counter += 1
|
|
name, ext = os.path.splitext(original_output_file_path)
|
|
output_file_path = f"{name}_{counter}{ext}"
|
|
print(f"Warning: Output file '{original_output_file_path}' already exists. Trying '{output_file_path}'.", file=sys.stderr)
|
|
|
|
print(f"Converting '{input_file_path}' to '{output_file_path}'")
|
|
|
|
# Construct FFmpeg command
|
|
ffmpeg_command = [
|
|
config.FFMPEG_PATH,
|
|
*config.FFMPEG_GLOBAL_OPTIONS,
|
|
"-progress", "ffmpeg_progress.log",
|
|
"-i", input_file_path,
|
|
"-c:v", video_codec,
|
|
"-profile:v", video_profile,
|
|
"-pix_fmt", config.DEFAULT_VIDEO_PIX_FMT,
|
|
]
|
|
|
|
# Add audio options if audio_info is available
|
|
if audio_info and audio_info.get("streams"):
|
|
ffmpeg_command.extend([
|
|
"-c:a", audio_codec,
|
|
])
|
|
else:
|
|
print("Warning: No audio stream found or parsed. Output will be video-only.", file=sys.stderr)
|
|
ffmpeg_command.append("-an") # Disable audio if no audio stream
|
|
|
|
ffmpeg_command.append(output_file_path)
|
|
|
|
try:
|
|
with open(config.FFMPEG_LOG_FILE_PATH, "w") as log_file:
|
|
process = subprocess.run(
|
|
ffmpeg_command,
|
|
stdout=log_file,
|
|
stderr=log_file,
|
|
text=True,
|
|
check=True
|
|
)
|
|
return True
|
|
except subprocess.CalledProcessError as e:
|
|
print(f"Error during FFmpeg conversion: {e}", file=sys.stderr)
|
|
print(f"Check {config.FFMPEG_LOG_FILE_PATH} for details.", file=sys.stderr)
|
|
# Optionally print last few lines of log for quick debugging
|
|
try:
|
|
with open(config.FFMPEG_LOG_FILE_PATH, "r") as log_file:
|
|
lines = log_file.readlines()
|
|
print("Last 10 lines of FFmpeg log:", file=sys.stderr)
|
|
for line in lines[-10:]:
|
|
print(line.strip(), file=sys.stderr)
|
|
except Exception as log_err:
|
|
print(f"Could not read FFmpeg log file: {log_err}", file=sys.stderr)
|
|
return False
|
|
except FileNotFoundError:
|
|
print("Error: FFmpeg not found. Please ensure FFmpeg is installed and in your PATH.", file=sys.stderr)
|
|
return False
|
|
except Exception as e:
|
|
print(f"An unexpected error occurred: {e}", file=sys.stderr)
|
|
return False |