Reputation: 67
I'm using moviepy to cut a clip into multiple equally-sized segments, and it's reading from a txt file of start and end values to cut the clip properly. The following is my code:
required_video_file = VideoFileClip(filename)
with open("times.txt") as f:
times = f.readlines()
times = [x.strip() for x in times]
for time in times:
starttime = int(time.split("-")[0])
endtime = int(time.split("-")[1])
required_video_file = required_video_file.subclip(starttime, endtime)
filen = str(times.index(time)+1)+".mp4"
required_video_file.write_videofile(filen, audio_codec='aac')
The current filename value is a 20-ish minute clip which has the times.txt file cut up into 30-second portions.
0-30
30-60
60-90
90-120
120-150
And so on. However, I get a valueerror when it tries to write the third file:
ValueError: t_start (60.00) should be smaller than the clip's duration (30.00).
I'm not sure why this error is happening, because the clip it's trying to create a subclip of is 20 minutes long, not 30 seconds.
FULL ERROR:
<moviepy.video.io.VideoFileClip.VideoFileClip object at 0x105e589a0>
Traceback (most recent call last):
File "vidsplitter.py", line 76, in <module>
required_video_file = required_video_file.subclip(starttime, endtime)
File "<decorator-gen-35>", line 2, in subclip
File "/Users/hypnoticocelot/Library/Python/3.8/lib/python/site-packages/moviepy/decorators.py", line 89, in wrapper
return f(*new_a, **new_kw)
File "<decorator-gen-34>", line 2, in subclip
File "/Users/hypnoticocelot/Library/Python/3.8/lib/python/site-packages/moviepy/decorators.py", line 32, in apply_to_mask
newclip = f(clip, *a, **k)
File "<decorator-gen-33>", line 2, in subclip
File "/Users/hypnoticocelot/Library/Python/3.8/lib/python/site-packages/moviepy/decorators.py", line 43, in apply_to_audio
newclip = f(clip, *a, **k)
File "/Users/hypnoticocelot/Library/Python/3.8/lib/python/site-packages/moviepy/Clip.py", line 391, in subclip
raise ValueError(
ValueError: t_start (60.00) should be smaller than the clip's duration (30.00).
Upvotes: 0
Views: 728
Reputation: 142661
All problem can be because you assing new clip to the same variable
required_video_file = required_video_file.subclip(...)
so in next loop it uses shorter clip - with duration 30s.
You should use different variable
new_clip = required_video_file.subclip(...)
EDIT:
You should get full duration at start
full_duration = required_video_file.duration
and inside loop you should check if endtime
is not too big and crop it.
if endtime > full_duration:
endtime = full_duration
You should also check if starttime
is not too big and skip rest of code.
if startime > full_duration:
break # exit `for`-loop
I would do (with some other changes)
required_video_file = VideoFileClip(filename)
full_duration = required_video_file.duration
with open("times.txt") as f:
times = [x.strip().split('-') for x in f]
for number, (start, end) in enumerate(times, 1):
starttime = int(start)
endtime = int(end)
if starttime > full_duration:
print(f"video too short to get {startime}-{endtime} (full duration: {full_duration})")
break # exit `for`-loop
if endtime > full_duration:
print(f"crop endtime {endtime} to {full_duration}")
endtime = full_duration
new_clip = required_video_file.subclip(starttime, endtime)
new_filename = f"{number}.mp4"
new_clip.write_videofile(new_filename, audio_codec='aac')
Upvotes: 1