Fix transcoding to dnxhd mov

This commit is contained in:
Jeena 2025-06-03 14:17:22 +09:00
parent d90c2404cd
commit c0f3618079

View file

@ -52,28 +52,42 @@ class Transcoder:
def _transcode_file(self, input_path, output_dir, basename, idx, total): def _transcode_file(self, input_path, output_dir, basename, idx, total):
os.makedirs(output_dir, exist_ok=True) os.makedirs(output_dir, exist_ok=True)
output_path = os.path.join(output_dir, basename) name, _ = os.path.splitext(basename)
output_path = os.path.join(output_dir, f"{name}.mov")
# Get duration of input file duration = self._get_duration(input_path) or 1.0
duration = self._get_duration(input_path) width, height, rotate = self._get_video_info(input_path)
if duration is None:
duration = 1.0 # fallback to avoid division by zero filters = []
if rotate in [90, 270] or (width and height and height > width):
filters.append("transpose=1")
width, height = height, width
if (width, height) != (1920, 1080):
filters.append("scale=1920:1080")
vf = ",".join(filters) if filters else None
cmd = [ cmd = [
"ffmpeg", "ffmpeg",
"-y", "-y",
"-i", "-i", input_path,
input_path, "-vcodec", "dnxhd",
"-c:v", "-acodec", "pcm_s16le",
"libx264", "-b:v", "36M",
"-preset", "-pix_fmt", "yuv422p",
"fast", "-r", "30000/1001",
"-c:a", "-f", "mov",
"aac", "-map_metadata", "0",
output_path,
] ]
process = subprocess.Popen(cmd, stderr=subprocess.PIPE, universal_newlines=True) if vf:
cmd += ["-vf", vf]
cmd.append(output_path)
process = subprocess.Popen(cmd, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE, text=True)
while True: while True:
line = process.stderr.readline() line = process.stderr.readline()
@ -83,7 +97,7 @@ class Transcoder:
match = self.TIME_RE.search(line) match = self.TIME_RE.search(line)
if match: if match:
hours, minutes, seconds, milliseconds = map(int, match.groups()) hours, minutes, seconds, milliseconds = map(int, match.groups())
elapsed = hours * 3600 + minutes * 60 + seconds + milliseconds / 100 elapsed = hours * 3600 + minutes * 60 + seconds + milliseconds / 1000.0
progress_fraction = min(elapsed / duration, 1.0) progress_fraction = min(elapsed / duration, 1.0)
overall_fraction = (idx - 1 + progress_fraction) / total overall_fraction = (idx - 1 + progress_fraction) / total
self._update_progress(f"Transcoding {basename}", overall_fraction) self._update_progress(f"Transcoding {basename}", overall_fraction)
@ -95,20 +109,35 @@ class Transcoder:
def _get_duration(self, input_path): def _get_duration(self, input_path):
cmd = [ cmd = [
"ffprobe", "ffprobe",
"-v", "-v", "error",
"error", "-show_entries", "format=duration",
"-show_entries", "-of", "default=noprint_wrappers=1:nokey=1",
"format=duration",
"-of",
"default=noprint_wrappers=1:nokey=1",
input_path, input_path,
] ]
try: try:
output = subprocess.check_output(cmd, universal_newlines=True) output = subprocess.check_output(cmd, text=True)
return float(output.strip()) return float(output.strip())
except Exception: except Exception:
return None return None
def _get_video_info(self, input_path):
cmd = [
"ffprobe",
"-v", "error",
"-select_streams", "v:0",
"-show_entries", "stream=width,height:stream_tags=rotate",
"-of", "default=noprint_wrappers=1:nokey=1",
input_path,
]
try:
output = subprocess.check_output(cmd, text=True).splitlines()
width = int(output[0])
height = int(output[1])
rotate = int(output[2]) if len(output) > 2 else 0
return width, height, rotate
except Exception:
return None, None, 0
def _update_progress(self, text, fraction): def _update_progress(self, text, fraction):
if self.progress_callback: if self.progress_callback:
GLib.idle_add(self.progress_callback, text, fraction) GLib.idle_add(self.progress_callback, text, fraction)