100 lines
3.5 KiB
Python
100 lines
3.5 KiB
Python
import ffmpeg
|
|
import os
|
|
import sys
|
|
|
|
from . import utils
|
|
from . import config
|
|
|
|
def convert_video(
|
|
input_file_path,
|
|
output_dir,
|
|
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 audio_info:
|
|
print("Error: Could not retrieve full media 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"]
|
|
# frame_rate = eval(v_stream["avg_frame_rate"]) # avg_frame_rate is a string like '30/1'
|
|
# duration = float(v_stream["duration_ts"]) / frame_rate
|
|
# pix_fmt = v_stream["pix_fmt"]
|
|
except (KeyError, IndexError) as e:
|
|
print(f"Error parsing video stream info: {e}", file=sys.stderr)
|
|
return False
|
|
|
|
# Extract relevant audio stream info
|
|
try:
|
|
a_stream = audio_info["streams"][0]
|
|
# a_codec_name = a_stream["codec_name"]
|
|
# sample_rate = a_stream["sample_rate"]
|
|
# channels = a_stream["channels"]
|
|
except (KeyError, IndexError) as e:
|
|
print(f"Error parsing audio stream info: {e}", file=sys.stderr)
|
|
# This might be a video-only file, proceed with no audio conversion
|
|
audio_codec = None
|
|
|
|
# Determine video profile based on resolution
|
|
video_profile = "dnxhr_sq" # Default to 1080p Standard Quality
|
|
if height > 1080:
|
|
video_profile = "dnxhr_hq" # For 1440p High Quality
|
|
|
|
output_file_path = utils.generate_output_path(
|
|
input_file_path, output_dir, output_suffix, output_prefix, output_ext
|
|
)
|
|
|
|
print(f"Converting '{input_file_path}' to '{output_file_path}'")
|
|
|
|
try:
|
|
stream = ffmpeg.input(input_file_path)
|
|
|
|
# Video stream setup
|
|
video_stream = stream.video
|
|
video_options = {
|
|
"c:v": video_codec,
|
|
"profile:v": video_profile,
|
|
"pix_fmt": config.DEFAULT_VIDEO_PIX_FMT,
|
|
}
|
|
|
|
# Audio stream setup
|
|
audio_stream = None
|
|
audio_options = {}
|
|
if audio_codec:
|
|
audio_stream = stream.audio
|
|
audio_options = {"c:a": audio_codec}
|
|
|
|
# Construct output stream
|
|
if audio_stream:
|
|
out = ffmpeg.output(video_stream, audio_stream, output_file_path, **video_options, **audio_options)
|
|
else:
|
|
out = ffmpeg.output(video_stream, output_file_path, **video_options)
|
|
|
|
# Add global options and run
|
|
out = ffmpeg.overwrite_output(out)
|
|
ffmpeg.run(out, cmd=config.FFMPEG_PATH, capture_stdout=True, capture_stderr=True)
|
|
|
|
print(f"Successfully converted to '{output_file_path}'")
|
|
return True
|
|
|
|
except ffmpeg.Error as e:
|
|
print(f"FFmpeg Error: {e.stderr.decode()}", 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 during conversion: {e}", file=sys.stderr)
|
|
return False
|