I would like to send subtitle text from php controller to python program that create video with subtitles using movipy library. I managed to send subtitle text but subtitles only appear started of video. And the time & text informations didn't seperated properly with srt.parse function. I managed the created video from srt file but I would like to use text instead of file. Python program interpret whole posted text as a sentence like below. Can you give me an idea please for solving the problem?
[Subtitle(content=u'', index=None, proprietary='\\r\\n As someone with an AI background, \\r\\n\\r\\n 00:00:01,879 --> 00:00:04,277 \\r\\n I think you can probably explain to us', end=datetime.timedelta(0, 1, 879000), start=datetime.timedelta(0, 0, 319000))]
My php controller is below.
public function store()
{
$str = <<<TEXT
00:00:00,319 --> 00:00:01,879 As someone with an AI background, 00:00:01,879 --> 00:00:04,277 I think you can probably explain to us, 00:00:04,277 --> 00:00:06,916 you know, this whole hype of generative AI, right?
TEXT;
$py_output = exec('python C:\\xampp\\htdocs\\xampp...\\main.py ' . json_encode($str) . '');
var_dump($py_output);
return view('videotest.store');
}
My main.py is below
import sys
from moviepy.editor import VideoFileClip, TextClip, CompositeVideoClip
textList = sys.argv[1]
subtitle_generator = srt.parse(textList)
subtitles = list(subtitle_generator)
mp4filename = "C:\\xampp\\htdocs\\xampp..\\myvideo.mp4"
def create_subtitle_clips(subtitles, videosize,fontsize=24, font='Arial', color='yellow', debug = False):
subtitle_clips = []
i = 0
while subtitles[i:]:
start_time = subtitles[i].start.seconds
end_time = subtitles[i].end.seconds
duration = end_time - start_time
video_width, video_height = videosize
text_clip = TextClip(subtitles[i].proprietary, fontsize=fontsize, font=font, color=color, bg_color = 'black',size=(video_width*3/4, None), method='caption').set_start(start_time).set_duration(duration)
subtitle_x_position = 'center'
subtitle_y_position = video_height* 4 / 5
text_position = (subtitle_x_position, subtitle_y_position)
subtitle_clips.append(text_clip.set_position(text_position))
i = i + 1
return subtitle_clips
video = VideoFileClip(mp4filename)
begin,end= mp4filename.split(".mp4")
output_video_file = begin+'_subtitled5'+".mp4"
subtitle_clips = create_subtitle_clips(subtitles,video.size)
final_video = CompositeVideoClip([video] + subtitle_clips)
final_video.write_videofile(output_video_file)
You need to ensure the subtitle text is correctly formatted and parsed into separate subtitles with their respective timings.
Ensure your subtitle text is in a proper SRT format
1
00:00:00,500 --> 00:00:02,000
Subtitle 1 text here.
2
00:00:02,500 --> 00:00:04,000
Subtitle 2 text here.
In Laravel properly escape and pass the subtitle text. You can use base64 encoding to ensure that newlines and other special characters are preserved when passing the string to Python.
public function store()
{
$str = <<<TEXT
1
00:00:00,319 --> 00:00:01,879 As someone with an AI background,
2
00:00:01,879 --> 00:00:04,277 I think you can probably explain to us,
3
00:00:04,277 --> 00:00:06,916 you know, this whole hype of generative AI, right?
TEXT;
$encodedStr = base64_encode($str); // Encode the string
$py_output = exec('python C:\\xampp\\htdocs\\xampp...\\main.py ' . escapeshellarg($encodedStr));
var_dump($py_output);
return view('videotest.store');
}
In your Python script, decode the input string before parsing it with srt.parse
.
import sys
import base64
import srt
# Decode the input string
encoded_text = sys.argv[1]
decoded_text = base64.b64decode(encoded_text).decode('utf-8')
subtitle_generator = srt.parse(decoded_text)
subtitles = list(subtitle_generator)
# your other code....