moviepy icon indicating copy to clipboard operation
moviepy copied to clipboard

Unexpected Behavior With Subclip

Open SenorPez opened this issue 9 years ago • 8 comments

I have a video clip that is created by concatenating intro and outro cards (ImageClips) around the video (VideoFileClip) itself: clip = mpy.concatenate_videoclips([intro, mainevent, outro])

The behavior of subclip is inconsistent in this case.

  • Creating a subclip of the start of the video succeeds. sub = clip.subclip(0, 10) sub = clip.subclip(0, 60)
  • Creating a subclip of the end of the video fails using the duration to calculate, IF the duration is entirely within the outro card: >>> clip.subclip(clip.duration-10, 0) *** ValueError: t_start (615.00) should be smaller than the clip's duration (585.00). >>> clip.duration 625.0
  • Creating a subclip of the end of the video succeeds using the duration to calculate, IF the duration is not entirely within the outro card: >>> clip.subclip(clip.duration-60, 0) <moviepy.video.VideoClip.VideoClip object at 0x7f658f5d60f0>

Suggest investigating behavior so that the third case is consistent with other behavior.

SenorPez avatar Feb 16 '16 18:02 SenorPez

So apparently... this works?

>>> clip.subclip(clip.duration-10) *** ValueError: t_start (615.00) should be smaller than the clip's duration (585.00). >>> clip.duration 625.0 >>> clip.set_duration(clip.duration).subclip(clip.duration-10) <moviepy.video.VideoClip.VideoClip object at 0x7f9a76a3e240>

:confounded:

SenorPez avatar Feb 16 '16 18:02 SenorPez

@SenorPez Not having used the feature you describe myself yet: could you let us know how you think this could/should be improved? Thanks.

keikoro avatar Feb 17 '17 21:02 keikoro

When creating a clip with concatenate, the duration is set correctly (in my example, 625), but that duration isn't recognized by subclip (note the message that "t_start (615) should be smaller than the clip's duration (585)").

You need to chain a set_duration(clip.duration) into the call (which is like saying a=a) to make it work.

SenorPez avatar Feb 24 '17 16:02 SenorPez

@SenorPez that's weird, can you provide a minimal code that produces the error ? Also I dont understand clip.subclip(clip.duration-10, 0): you are setting t_end to 0 ? Does this actually work ? (it shouldn't).

Zulko avatar Feb 24 '17 16:02 Zulko

The issue here is that even though clip.duration is 625, .subclip() is also applied to the clip's audio and mask, which may not have duration 625. In this case, because the outro is composed of an ImageClip, it does not have an audio, so it crashes when it tries to subclip the audio.

I have replicated it here:

from moviepy.editor import *
c1 = VideoFileClip("media/big_buck_bunny_0_30.webm")
c2 = ImageClip("media/vacation_2017.jpg").set_duration(10)
c = concatenate_videoclips([c1, c2])
c.duration
# 40.0
c.audio.duration
# 30.0
c.subclip(c.duration-5)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-36>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-35>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 32, in apply_to_mask
    newclip = f(clip, *a, **k)
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-34>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 45, in apply_to_audio
    newclip.audio = f(newclip.audio, *a, **k)
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/Clip.py", line 384, in subclip
    + "duration (%.02f)." % self.duration
ValueError: t_start (35.00) should be smaller than the clip's duration (30.00).
c.subclip(c.duration-5, 0)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-36>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 89, in wrapper
    return f(*new_a, **new_kw)
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-35>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 32, in apply_to_mask
    newclip = f(clip, *a, **k)
  File "</Users/tomburrows/miniconda3/envs/moviepy/lib/python3.7/site-packages/decorator.py:decorator-gen-34>", line 2, in subclip
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/decorators.py", line 45, in apply_to_audio
    newclip.audio = f(newclip.audio, *a, **k)
  File "/Users/tomburrows/Python/moviepy-dev/moviepy/moviepy/Clip.py", line 384, in subclip
    + "duration (%.02f)." % self.duration
ValueError: t_start (35.00) should be smaller than the clip's duration (30.00).

tburrows13 avatar May 29 '20 00:05 tburrows13

@tburrows13 this is the exact issue I am facing. Did you find any solution to this?

ajainlohika avatar Aug 07 '23 09:08 ajainlohika

For other people facing this issue, adding complete_video = complete_video.set_duration(complete_video.duration) before subclipping complete_video seemed to solve the problem for me. sub = complete_video.subclip(55, 60)

grydev avatar Dec 13 '23 22:12 grydev

For some reason, I keep on making these seemingly random values for duration when I run this code: clip = VideoFileClip('/media/video-1hr.mp4') clip = clip.set_duration(clip.duration) duration = math.floor(clip.duration)

rand_start = int(random.randint(0, int(duration - 60))) rand_end = int(rand_start + 60) print(rand_start, rand_end) short = clip.subclip(rand_start, rand_end) # bro what is wrong with this line

print(short.duration)

(Note it is extra large because I added extra measures to try and remedy the situation to no avail).

When I look at the values rand_start and rand_end, they have a difference of 60 perfectly every time, but when running the subclip function, and then finding out the duration of the clip, it comes out to an assortment of random numbers within the total range of the video, but not a consistent 60 seconds as it should be. Thanks!

dchavre avatar Dec 24 '23 09:12 dchavre