Spaces:
Sleeping
Sleeping
import subprocess | |
from utils.video_to_audio import extract_audio | |
from utils.transcribe_audio import transcribe_audio | |
from utils.create_subtitles import create_subtitles, hex_to_ffmpeg_color | |
import os | |
def generate_subway_subtitles(customization_options): | |
customization_options['font_color'] = hex_to_ffmpeg_color(customization_options['font_color']) | |
audio_file = "./data/subway/audio.mp3" | |
subtitle_file = "./data/subway/subtitles.srt" | |
top_video_path = customization_options['top_video'] | |
bottom_video_path = customization_options['bottom_video'] | |
output_directory = "./data/subway/videos" | |
extract_audio(bottom_video_path, audio_file) | |
transcription = transcribe_audio(audio_file) | |
create_subtitles(transcription, subtitle_file) | |
trimmed_output_filepath = top_video_operations(top_video_path, bottom_video_path, output_directory) | |
bottom_video_width, bottom_video_height = bottom_video_operations(bottom_video_path) | |
combined_output_path = combination_video(trimmed_output_filepath, bottom_video_path, bottom_video_width, bottom_video_height, output_directory) | |
subtitle_output_filepath = add_subtitle(combined_output_path, subtitle_file, customization_options, output_directory) | |
result_video_path = add_text_to_video(subtitle_output_filepath, customization_options, output_directory) | |
return result_video_path | |
def top_video_operations(top_video_path, bottom_video_path, output_directory): | |
muted_output_filepath = os.path.join(output_directory, 'top_video_muted.mp4') | |
trimmed_output_filepath = os.path.join(output_directory, 'top_video_muted_trimmed.mp4') | |
mute_top_cmd = [ | |
"ffmpeg", | |
"-i", top_video_path, | |
"-af", "volume=0.0", | |
"-c:v", "copy", | |
"-y", muted_output_filepath | |
] | |
subprocess.run(mute_top_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
get_duration_cmd = [ | |
"ffprobe", | |
"-v", "error", | |
"-show_entries", "format=duration", | |
"-of", "default=noprint_wrappers=1:nokey=1", | |
bottom_video_path | |
] | |
duration = float(subprocess.check_output(get_duration_cmd, universal_newlines=True).strip()) | |
trim_top_cmd = [ | |
"ffmpeg", | |
"-i", muted_output_filepath, | |
"-t", str(duration), | |
"-c:v", "copy", | |
"-y", trimmed_output_filepath | |
] | |
subprocess.run(trim_top_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
return trimmed_output_filepath | |
def bottom_video_operations(bottom_video_path): | |
bottom_video_height = int(subprocess.check_output([ | |
"ffprobe", | |
"-v", "error", | |
"-select_streams", "v:0", | |
"-show_entries", "stream=height", | |
"-of", "csv=s=x:p=0", | |
bottom_video_path | |
], universal_newlines=True).strip()) | |
bottom_video_width = int(subprocess.check_output([ | |
"ffprobe", | |
"-v", "error", | |
"-select_streams", "v:0", | |
"-show_entries", "stream=width", | |
"-of", "csv=s=x:p=0", | |
bottom_video_path | |
], universal_newlines=True).strip()) | |
return bottom_video_width, bottom_video_height | |
def combination_video(trimmed_top_video_path, bottom_video_path, bottom_video_width, bottom_video_height, output_directory): | |
combined_output_filepath = os.path.join(output_directory, 'top_video_muted_trimmed_combined.mp4') | |
combine_cmd = [ | |
"ffmpeg", | |
"-i", trimmed_top_video_path, | |
"-i", bottom_video_path, | |
"-filter_complex", f"[0:v]scale={bottom_video_width}:{bottom_video_height},setsar=1[main];[1:v]scale={bottom_video_width}:{bottom_video_height},setsar=1[bottom_scaled];[main][bottom_scaled]vstack=inputs=2[v];[0:a][1:a]amix=inputs=2[a]", | |
"-map", "[v]", | |
"-map", "[a]", | |
"-y", combined_output_filepath | |
] | |
subprocess.run(combine_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
return combined_output_filepath | |
def add_subtitle(combined_video_path, subtitle_file, customization_options, output_directory): | |
subtitle_output_filepath = os.path.join(output_directory, 'combined_subtitle.mp4') | |
subtitle_cmd = [ | |
"ffmpeg", | |
"-i", combined_video_path, | |
"-vf", f"subtitles={subtitle_file}:force_style='Fontsize={customization_options['font_size']},Fontname={customization_options['font_family']},BorderColor=black@{customization_options['border_size']},PrimaryColour={customization_options['font_color']}'", | |
"-c:a", "aac", | |
"-c:v", "libx264", | |
"-y", subtitle_output_filepath, | |
] | |
subprocess.run(subtitle_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
return subtitle_output_filepath | |
def add_text_to_video(subtitle_output_filepath, customization_options, output_directory): | |
result_video_path = os.path.join(output_directory, 'combined_subtitle_text.mp4') | |
cmd = [ | |
'ffmpeg', | |
'-i', subtitle_output_filepath, | |
'-vf', f'drawtext=text=\'{customization_options["credit"]}\':fontcolor=white:fontsize={customization_options["credit_size"]}:box=1:[email protected]:boxborderw=5:x=(w-text_w)/2:y=(h-text_h)/2', | |
'-codec:a', 'copy', | |
"-y", result_video_path | |
] | |
subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE) | |
return result_video_path | |