Spaces:
Sleeping
Sleeping
File size: 5,301 Bytes
70f6f47 c9f042d 230dec4 70f6f47 c9f042d 70f6f47 c9f042d 3d72431 679995a 3d72431 679995a 3d72431 c9f042d 70f6f47 c9f042d 70f6f47 c9f042d |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
from moviepy import *
import pysrt
import gradio as gr
def time_to_seconds(time_obj):
return time_obj.hours * 3600 + time_obj.minutes * 60 + time_obj.seconds + time_obj.milliseconds / 1000
def create_subtitle_clips(subtitles, videosize, fontsize, font, color, debug):
subtitle_clips = []
color_clips=[]
for subtitle in subtitles:
start_time = time_to_seconds(subtitle.start) # Add 2 seconds offset
end_time = time_to_seconds(subtitle.end)
duration = end_time - start_time
video_width, video_height = videosize
max_width = video_width * 0.8
max_height = video_height * 0.2
#reshaped_text = arabic_reshaper.reshape(subtitle.text)
#bidi_text = get_display(reshaped_text)
text_clip = TextClip(font, subtitle.text, font_size=fontsize, size=(int(video_width * 0.8), int(video_height * 0.2)) ,text_align="center" ,color=color, method='caption').with_start(start_time).with_duration(duration)
#myclip = ColorClip(size=(int(video_width * 0.8), int(video_height * 0.2)) , color=(225, 0, 0)).with_opacity(0.2).with_start(start_time).with_duration(duration)
subtitle_x_position = 'center'
subtitle_y_position = video_height * 0.68
text_position = (subtitle_x_position, subtitle_y_position)
subtitle_clips.append(text_clip.with_position(text_position))
#color_clips.append(myclip.with_position(text_position))
return subtitle_clips
import subprocess
import os
# Mapping of color names to FFmpeg-compatible hex codes
COLOR_MAP = {
'white': '#FFFFFF',
'yellow': '#FFFF00',
'red': '#FF0000',
'green': '#00FF00',
'blue': '#0000FF',
'black': '#000000'
}
def hex_to_ffmpeg_color(hex_code):
"""
Convert standard hex color (#RRGGBB) to FFmpeg's PrimaryColour format (&HBBGGRR&).
Args:
hex_code (str): Standard hex color code (e.g., '#FFFFFF')
Returns:
str: FFmpeg color code (e.g., '&HFFFFFF&')
"""
hex_code = hex_code.lstrip('#')
r, g, b = hex_code[0:2], hex_code[2:4], hex_code[4:6]
return f'&H{b}{g}{r}&'
def video_edit(srt, input_video, font_color, font_type, font_size, input_audio=None):
"""
Burns subtitles into a video using FFmpeg with customizable styling.
Args:
srt (str): Path to SRT subtitle file
input_video (dict or str): Input video path or dict with 'video' key
font_color (str): Color name (e.g., 'white', 'yellow')
font_type (str): Font name for subtitles
font_size (int): Font size for subtitles
input_audio (str, optional): Path to audio file (if provided)
Returns:
str: Path to output video file
"""
# Handle input_video as dict or string
if isinstance(input_video, dict):
video_path = input_video.get('video', '')
else:
video_path = input_video
# Validate input
if not video_path or not os.path.exists(video_path):
raise ValueError("Invalid or missing video file")
if not os.path.exists(srt):
raise ValueError("Subtitle file not found")
# Generate output filename
input_base = os.path.splitext(video_path)[0]
output_video = f"{input_base}_subtitled.mp4"
print(font_color, font_type)
# Convert color name to FFmpeg format
hex_color = COLOR_MAP.get(font_color.lower())
if not hex_color:
raise ValueError(f"Unsupported color: {font_color}. Supported colors: {', '.join(COLOR_MAP.keys())}")
ffmpeg_color = hex_to_ffmpeg_color(hex_color)
print(ffmpeg_color)
# Build subtitle style
subtitle_style = f"FontName={font_type},FontSize={font_size},PrimaryColour={ffmpeg_color}"
fonts_dir = os.path.dirname(srt)
# Construct FFmpeg command
cmd = [
'ffmpeg',
'-i', video_path, # Input video
]
# Add audio input if provided (though we'll still keep original audio)
if input_audio and os.path.exists(input_audio):
cmd.extend(['-i', input_audio])
cmd.extend([
'-vf', f"subtitles={srt}:fontsdir={fonts_dir}:force_style='{subtitle_style}'", # Burn subtitles
'-c:v', 'libx264', # Video codec
'-c:a', 'copy', # Always copy original audio
'-r', '24', # Frame rate
'-preset', 'ultrafast',# Encoding preset
'-y', # Overwrite output
output_video
])
# Execute FFmpeg command
try:
subprocess.run(cmd, check=True, stderr=subprocess.PIPE, universal_newlines=True)
except subprocess.CalledProcessError as e:
raise RuntimeError(f"FFmpeg failed: {e.stderr}")
print(f"Video processed successfully: {output_video}")
return output_video
with gr.Blocks() as demo:
gr.Markdown("Start typing below and then click **Run** to see the progress and final output.")
with gr.Column():
srt_file = gr.File()
video_in = gr.Video()
color = gr.Text()
font = gr.Text()
font_size = gr.Number()
audio_in = gr.Audio(type = "filepath")
btn = gr.Button("Create")
output_video = gr.Video()
btn.click(
fn=video_edit,
inputs=[srt_file, video_in, color, font, font_size, audio_in],
outputs=output_video
)
demo.launch(debug=True) |