diff --git a/ami_scripts/prepend_title_cards.py b/ami_scripts/prepend_title_cards.py index 8c1bf0a5..2dd883da 100755 --- a/ami_scripts/prepend_title_cards.py +++ b/ami_scripts/prepend_title_cards.py @@ -7,6 +7,21 @@ import re import glob + +def run_ffmpeg_command(command): + process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True, bufsize=1) + stdout, stderr = '', '' + while True: + output = process.stderr.readline() + if output == '' and process.poll() is not None: + break + if output: + print(output.strip()) + stderr += output + rc = process.poll() + return rc, stdout, stderr + + def get_title_cards_for_group(prefix): # Define the paths for the title card images script_dir = os.path.dirname(os.path.realpath(__file__)) @@ -24,7 +39,7 @@ def get_title_cards_for_group(prefix): elif prefix == 'mao': return [nypl_title_card] else: - return [] + return [nypl_title_card] def process_video(video_path, asset_flag): @@ -100,6 +115,13 @@ def process_video(video_path, asset_flag): f"pad=720:480:{pad_x}:0:black", "setdar=16/9" ]) + elif video_stream.get('display_aspect_ratio') == '3:2': + # Handling for videos with 3:2 aspect ratio + filters.extend([ + f"scale={width}:{height}", + "setsar=1", + "setdar=3/2" + ]) else: # For other 720x480 videos, scale as usual filters.extend([ @@ -153,9 +175,44 @@ def process_video(video_path, asset_flag): # Concatenate the title card videos and the original video temp_output_path = os.path.join(os.path.dirname(video_path), 'temp_concat_output.mp4') + + # First concatenation attempt ffmpeg_concat_cmd = ['ffmpeg', '-y', '-f', 'concat', '-safe', '0', '-i', concat_list, '-c', 'copy', temp_output_path] - subprocess.check_output(ffmpeg_concat_cmd) - + returncode, stdout, stderr = run_ffmpeg_command(ffmpeg_concat_cmd) + + if "Non-monotonous DTS in output stream 0:1" in stderr: + print("Non-monotonous DTS error detected. Attempting alternative concatenation method.") + + # Remove the possibly corrupted file + if os.path.exists(temp_output_path): + os.remove(temp_output_path) + + # Construct the alternative concatenation command + alternative_concat_cmd = ['ffmpeg'] + filter_complex_cmd = [] + + # Add each image video file and construct the filter_complex part + for idx, image_file in enumerate(image_video_files): + alternative_concat_cmd.extend(['-i', image_file]) + filter_complex_cmd.extend([f"[{idx}:v:0][{idx}:a:0]"]) + + # Add the original video file + alternative_concat_cmd.extend(['-i', video_path]) + filter_complex_cmd.extend([f"[{len(image_video_files)}:v:0][{len(image_video_files)}:a:0]"]) + + # Finalize the filter_complex command + alternative_concat_cmd.extend([ + '-filter_complex', ''.join(filter_complex_cmd) + f"concat=n={len(image_video_files) + 1}:v=1:a=1[outv][outa]", + '-map', '[outv]', '-map', '[outa]', '-c:v', 'libx264', '-c:a', 'aac', temp_output_path + ]) + + # Run the alternative concatenation command + returncode, stdout, stderr = run_ffmpeg_command(alternative_concat_cmd) + if returncode != 0: + print(f"Error during alternative concatenation: {stderr}") + else: + print("Concatenation successful.") + # Apply text and timecode to the main video after title cards if asset_flag: title_cards_duration = len(title_cards) * 5 # Assuming each title card is 5 seconds @@ -165,20 +222,27 @@ def process_video(video_path, asset_flag): match = re.search(r'_(\d{6})_', video_path) asset_id = match.group(1) if match else '' - # Determine bitrate based on resolution + # Determine bitrate and aspect ratio based on resolution if width == 1920 and height == 1080: # HD content video_bitrate = "8000000" bufsize = "8000000" maxrate = "8000000" - else: # SD content + additional_filters = "" + elif width == 720 and height == 480 and display_aspect_ratio == '3:2': # Specific SD widescreen content + video_bitrate = "3500000" + bufsize = "1750000" + maxrate = "3500000" + additional_filters = ",setdar=4/3" + else: # Other SD content video_bitrate = "3500000" bufsize = "1750000" maxrate = "3500000" + additional_filters = "" ffmpeg_drawtext_cmd = [ 'ffmpeg', '-i', temp_output_path, '-c:v', 'libx264', '-b:v', video_bitrate, '-bufsize', bufsize, '-maxrate', maxrate, '-vf', f"drawtext=fontfile=/System/Library/Fonts/Helvetica.ttc:fontsize=25:text='{asset_id}':x=10:y=10:fontcolor=white:enable='gte(t,{title_cards_duration})'," + - f"drawtext=fontfile=/System/Library/Fonts/Helvetica.ttc:fontsize=20:text='%{{pts\\:hms\\: - {title_cards_duration}}}':box=1:boxcolor=black@0.5:boxborderw=5:x=(w-tw)/2:y=h-th-10:fontcolor=white:enable='gte(t,{title_cards_duration})',format=yuv420p", + f"drawtext=fontfile=/System/Library/Fonts/Helvetica.ttc:fontsize=20:text='%{{pts\\:hms\\: - {title_cards_duration}}}':box=1:boxcolor=black@0.5:boxborderw=5:x=(w-tw)/2:y=h-th-10:fontcolor=white:enable='gte(t,{title_cards_duration})'{additional_filters},format=yuv420p", '-c:a', 'copy', output_path ] subprocess.check_output(ffmpeg_drawtext_cmd)