Complete initial project setup and core functionality
This commit is contained in:
99
src/converter.py
Normal file
99
src/converter.py
Normal file
@@ -0,0 +1,99 @@
|
||||
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
|
||||
Reference in New Issue
Block a user