Hello, I have script which can export clips of time ranges in video, slow it down and keep the original pitch. It is saved then. There are folders of number created into Output directory. Each number represents slow down factor. Now when I play the video which is like 20 times slower I need to see time because vlc just doesn't give me convinient information, I want to keep the time in the video. I cannot find out how to do this correctly. Can anyone here try to fix/finish the script? I mean only the text into video. I need to see the seconds in format like 14.05 (14.05s) or something like 14.053 etc.
I remember there was an error with the lambda function when I tried this.
I have this:
I remember there was an error with the lambda function when I tried this.
I have this:
# REQUIRES: moviepy a pydub # TATO VYBERE NĚKOLIK SEGMENTŮ Z VIDEA, ZPOMALÍ JE, # ZACHOVÁ TÓN, PŘIDÁ TEXT SEKUND (float) import os from moviepy.editor import VideoFileClip, concatenate_videoclips, vfx, AudioFileClip, TextClip, CompositeVideoClip from pydub import AudioSegment from moviepy.video.tools.drawing import color_split # Directories - se absolute home_dir = os.path.expanduser("~") default_path = "/Samba" input_dir = os.path.join("/media/mydisk/home/user/Videos", default_path) file = 'for minutes video.mp4' input_path = os.path.join(input_dir, file) user_choice = input("Do you want to use current folder (.) od default one? Type '.' for current or 'default' ...: ") if user_choice == '.': input_dir = os.path.abspath('.') input_path = os.path.join(input_dir, file) # Slow down factors slowdowns = [2,4,8,10,15,20,25,30] # Output folders creation output_dirs = [os.path.join(input_dir, f"Output/{factor}") for factor in slowdowns] for dir in output_dirs: os.makedirs(dir, exist_ok=True) # change audio pitch - no change speed def audio_pitchup_ffmpeg(input_audio_path, output_audio_path, factor): command = f'ffmpeg -i "{input_audio_path}" -filter_complex "rubberband=pitch={factor}" "{output_audio_path}"' os.system(command) # convert time to s. def convert_to_seconds(time_str): parts = time_str.split(':') minutes = int(parts[0]) seconds = float(parts[1]) return minutes * 60 + seconds # times to be exported time_ranges = [ # ("0:50.40", "0:56.00") # ("0:56.00", "0:56.02") ("1:27.00", "2:27.00") # to export this part # ("1:27.00", "4:37") ] # insert text def add_time_text(get_frame, t): # Vytvoření textového klipu s časem time_str = f"t={t:.2f} sec" txt_clip = TextClip(time_str, fontsize=22, color='white', bg_color='black', size=(200, 50)) txt_clip = txt_clip.set_position(('left', 'top')).set_duration(0.1) # create videoclip with text return CompositeVideoClip([get_frame(t), txt_clip]) # one file process video_path = input_path if os.path.isfile(video_path) and video_path.endswith(".mp4"): video_clip = VideoFileClip(video_path) # export parts temp_clips = [] for start_time, end_time in time_ranges: start_seconds = convert_to_seconds(start_time) end_seconds = convert_to_seconds(end_time) temp_clip = video_clip.subclip(start_seconds, end_seconds) temp_clips.append(temp_clip) # join all temp_joined_path = os.path.join(input_dir, "temp_joined.avi") joined_clip = concatenate_videoclips(temp_clips) joined_clip.write_videofile(temp_joined_path, codec="libx264", audio_codec="aac") # Uzavření všech klipů for clip in temp_clips: clip.close() video_clip.close() joined_clip.close() # slow down and correct pitch in audio tracks for i, factor in enumerate(slowdowns): output_path = os.path.join(output_dirs[i], file) edited_clip = VideoFileClip(temp_joined_path) # text addition edited_clip = edited_clip.fl(lambda gf, t: add_time_text(gf, t)) # extraction and editation temp_audio_path = os.path.join(input_dir, "temp_audio.wav") edited_clip.audio.write_audiofile(temp_audio_path, codec='pcm_s16le') new_audio_path = os.path.join(input_dir, "new_temp_audio.wav") audio_pitchup_ffmpeg(temp_audio_path, new_audio_path, factor) new_audio_clip = AudioFileClip(new_audio_path) # create new video with edited audio track edited_clip = edited_clip.set_audio(new_audio_clip) temp_video_name = os.path.join(input_dir, "temp-final-video.m4a") edited_clip.write_videofile( temp_video_name, codec="libx264", audio_codec="aac", temp_audiofile=os.path.join(input_dir, 'temp-audio-1.m4a'), remove_temp=True, threads=4, preset='ultrafast' ) # close temporals edited_clip.close() new_audio_clip.close() # reopen to slow-down edited_clip = VideoFileClip(temp_video_name) edited_clip = edited_clip.fx(vfx.speedx, 1.0 / factor) edited_clip.set_duration(edited_clip.duration) print(f"Processing {file} with slowdown factor {factor}. Saving to {output_path}") edited_clip.write_videofile( output_path, codec="libx264", audio_codec="aac", temp_audiofile=os.path.join(input_dir,'temp-audio-2.m4a'), remove_temp=True, threads=4, preset='ultrafast' ) # close all edited_clip.close() # remove all if os.path.exists(temp_audio_path): os.remove(temp_audio_path) if os.path.exists(new_audio_path): os.remove(new_audio_path) if os.path.exists(temp_video_name): os.remove(temp_video_name) # remove temporals if os.path.exists(temp_joined_path): os.remove(temp_joined_path) else: print(f"{file} ---> File .mp4 not found") print("Job done.")When I tried the code I got similar error:
Moviepy - Building video /media/toshiba/home/user/Videa/TUTORIALS/temp_joined.avi. MoviePy - Writing audio in temp_joinedTEMP_MPY_wvf_snd.mp4 MoviePy - Done. Moviepy - Writing video /media/toshiba/home/user/Videa/TUTORIALS/temp_joined.avi Moviepy - Done ! Moviepy - video ready /media/toshiba/home/user/Videa/TUTORIALS/temp_joined.avi Traceback (most recent call last): File "get-segments-slow-down-time-lower-sound-quality.py", line 92, in <module> edited_clip = edited_clip.fl(lambda gf, t: add_time_text(gf, t)) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/Clip.py", line 136, in fl newclip = self.set_make_frame(lambda t: fun(self.get_frame, t)) File "<decorator-gen-61>", line 2, in set_make_frame File "/home/user/.venv/lib/python3.8/site-packages/moviepy/decorators.py", line 14, in outplace f(newclip, *a, **k) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/video/VideoClip.py", line 644, in set_make_frame self.size = self.get_frame(0).shape[:2][::-1] File "<decorator-gen-11>", line 2, in get_frame File "/home/user/.venv/lib/python3.8/site-packages/moviepy/decorators.py", line 89, in wrapper return f(*new_a, **new_kw) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/Clip.py", line 93, in get_frame return self.make_frame(t) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/Clip.py", line 136, in <lambda> newclip = self.set_make_frame(lambda t: fun(self.get_frame, t)) File "get-segments-slow-down-time-lower-sound-quality.py", line 92, in <lambda> edited_clip = edited_clip.fl(lambda gf, t: add_time_text(gf, t)) File "get-segments-slow-down-time-lower-sound-quality.py", line 60, in add_time_text return CompositeVideoClip([get_frame(t), txt_clip]) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/video/compositing/CompositeVideoClip.py", line 79, in __init__ self.bg = ColorClip(size, color=self.bg_color) File "/home/user/.venv/lib/python3.8/site-packages/moviepy/video/VideoClip.py", line 1012, in __init__ w, h = size TypeError: cannot unpack non-iterable int object