moviepy icon indicating copy to clipboard operation
moviepy copied to clipboard

MoviePy VideoClip Methods and Gif Looping Issue: set_ Methods Ineffective for VideoClip, Gif Not Looping in Python Code

Open SohamTilekar opened this issue 1 year ago • 3 comments

Description

The Set methods do not work as expected they do not change the new video data. The Gif Do not Loop.

Issue Details

Expected Behavior

When using set_start, set_end, set_position, etc., the CompositeVideoClip should incorporate these changes into the final video, adjusting the start time, end time, and position of the GIF accordingly.

Actual Behavior

The set_start, set_end, and set_position methods appear to be ineffective in modifying the original VideoFileClip. Consequently, the composite video does not reflect the specified alterations, and the output remains inconsistent with the expected changes.

Problematic Code

Output Video:-

https://github.com/Zulko/moviepy/assets/152298897/ff14472a-6684-487f-8097-5265e5f60e5b

from moviepy.editor import CompositeVideoClip, VideoFileClip

bg = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\brole.mp4')

gf = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\tmp7dzte94v.gif')
old_st = gf.start
gf.set_start(t=1)
new_st = gf.start

print(f'{old_st=}, {new_st=}')

old_ed = gf.end
gf.set_end(t=4)
new_ed = gf.end

print(f'{old_ed=}, {new_ed=}')

old_pos = gf.pos(t=1)
gf.set_position((45,150))
new_pos = gf.pos(1)

print(f'{old_pos=}, {new_pos=}')

CompositeVideoClip([bg, gf], use_bgclip=True).write_videofile('temp.mp4', fps=16)

Output Comparison

  • Initial Code Output:
    old_st=0, new_st=0
    old_ed=2.26, new_ed=2.26      
    old_pos=(0, 0), new_pos=(0, 0)
    Moviepy - Building video temp.mp4.
    Moviepy - Writing video temp.mp4
    Moviepy - Done !
    Moviepy - video ready temp.mp4
    

Working Code

Output Video:-

https://github.com/Zulko/moviepy/assets/152298897/11d62d1d-effe-47da-a572-4e50baebef46

from moviepy.editor import CompositeVideoClip, VideoFileClip

bg = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\brole.mp4')

gf = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\tmp7dzte94v.gif')
old_st = gf.start
gf.start = 1
new_st = gf.start

print(f'{old_st=}, {new_st=}')

old_ed = gf.end
gf.end = 4
new_ed = gf.end

gf.duration = 3
dur = gf.duration

print(f'{old_ed=}, {new_ed=}, {dur=}')

old_pos = gf.pos(t=1)
gf.pos = lambda t: (45, 150)
new_pos = gf.pos(1)

print(f'{old_pos=}, {new_pos=}')

CompositeVideoClip([bg, gf], use_bgclip=True).write_videofile('temp.mp4', fps=16)

Output Comparison

  • Modified Code Output:
    old_st=0, new_st=1
    old_ed=2.26, new_ed=4, dur=3     
    old_pos=(0, 0), new_pos=(45, 150)
    Moviepy - Building video temp.mp4.
    Moviepy - Writing video temp.mp4
    Moviepy - Done !
    Moviepy - video ready temp.mp4
    

Specifications

  • Python Version: 3.11.7
  • MoviePy Version: 1.0.3
  • Platform Name: Windows 10

Windows Specification

  • Edition: Windows 10 Pro
  • Version: 22H2
  • OS build: 19045.3803
  • System type: 64-bit operating system, x64-based processor

Hardware

  • Processor: Intel(R) Core(TM) i3-6006U CPU @ 2.00GHz 1.99 GHz
  • Installed RAM: 4.00 GB (3.88 GB usable)

SohamTilekar avatar Dec 21 '23 08:12 SohamTilekar

Using loop function or concatenate_videoclips:

  • fx.loop (not supporting transparent gif)
from moviepy.video.fx.loop import loop
bg = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\brole.mp4')
gf = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\tmp7dzte94v.gif')
gf = loop(gf, duration=bg.duration)
CompositeVideoClip([bg, gf]).write_videofile('temp.mp4', fps=16)
  • concatenate_videoclips (support transparent gif)
bg = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\brole.mp4')
gf = VideoFileClip(r'D:\AI\YT_Automation\Video_Maker\tmp7dzte94v.gif')
duration = bg.duration
loop_count = int(duration // gf.duration + 1)
gf_loop = concatenate_videoclips([gf] * loop_count)
gf_loop = gf_loop.set_duration(duration)
CompositeVideoClip([bg, gf_loop]).write_videofile('temp.mp4', fps=16)

Good0007 avatar Dec 22 '23 08:12 Good0007

Thanks for the GIF issue solving but there are more Issues with the set_ methods and also with the CompositeVideoClip the CompositeVideoClip Put the Video over each other instead of their own Cordinates.

SohamTilekar avatar Dec 22 '23 09:12 SohamTilekar

The CompositeVideoClip DO Not Work Properly. It Do not Position the Clips on each other properly.

        with tempfile.NamedTemporaryFile(suffix='.mp4', delete=False) as f:
            # Write the video content to the temporary file
            for chunk in response.iter_content(chunk_size=1024):
                if chunk:
                    f.write(chunk)
            f.flush()
            bg_vid = VideoFileClip(f.name)

    audio_clip = AudioFileClip(audio)
    canvas = ColorClip(output_width_height, [80, 80, 80])
...
...
            imgs = []
            for on_image in on_imgs:
                img_q = on_image[0]
                img_t = tuple(float(i) for i in on_image[2].split(':'))
                img_ori = on_image[4]
                img_siz = int(on_image[3].removesuffix('%'))/100
                img_clip = img_geter.ImageSearcher.main(
                    img_q, pexels_api, pixabay_api, img_ori, script_line,int(canvas.size[0]*img_siz), int(canvas.size[1]*img_siz)
                )
                img_clip = img_clip.fx(resize, (canvas.size[0]*img_siz, canvas.size[1]*img_siz))
                p = pos_maker(on_image[1], output_width_height, img_clip.size)
                print('on_img', p)
                img_clip.pos = lambda t: p
                print('new_img', img_clip.pos(1))

                img_clip.start = img_t[0]
                img_clip.end = img_t[1]
                imgs.append(img_clip)
            
            gifs = []
            for gif in on_gif:
                on_gif_q = gif[0]
                on_gif_t = tuple(int(strint) for strint in gif[2].split(':'))
                on_gif_siz = int(gif[3].removesuffix('%'))/100
                on_gif_clip = vid_getter.giphy.Gif.main(
                    on_gif_q, gify_api, 15,
                )


                on_gif_clip = on_gif_clip.fx(resize, (canvas.size[0]*on_gif_siz, canvas.size[1]*on_gif_siz))

                p = pos_maker(gif[1], output_width_height, on_gif_clip.size)
                print('gif', p)
                on_gif_clip.pos = lambda t: p
                print('new_gif', on_gif_clip.pos(1))
                on_gif_clip.start = on_gif_t[0]
                on_gif_clip.end = on_gif_t[1]
                gifs.append(on_gif_clip)
            vids: list[VideoClip] = [canvas, bg_vid]
            vids.extend(imgs)
            # vids.extend(gifs)
            f_video = CompositeVideoClip(vids)
            f_video.duration = audio_clip.duration
            f_video.audio = audio_clip # type: ignore
            return f_video```

> It is Only test clip.

Wrong Output Clip: -


https://github.com/Zulko/moviepy/assets/152298897/aa6bdf4c-a3c6-47c2-8e9b-db0333b10119

Specifications
Python Version: 3.11.7
MoviePy Version: 1.0.3
Platform Name: Windows 10
Windows Specification
Edition: Windows 10 Pro
Version: 22H2
OS build: 19045.3803
System type: 64-bit operating system, x64-based processor
Hardware
Processor: Intel(R) Core(TM) i3-6006U CPU @ 2.00GHz 1.99 GHz
Installed RAM: 4.00 GB (3.88 GB usable)

SohamTilekar avatar Dec 22 '23 10:12 SohamTilekar