-
-
Save gphg/60852c868bb38328e7003ad4bfcd69b7 to your computer and use it in GitHub Desktop.
My own custom of makegifs.py.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env python | |
# Taken from http://zulko.github.io/blog/2015/02/01/extracting-perfectly-looping-gifs-from-videos-with-python-and-moviepy/ | |
import os | |
import sys | |
import moviepy.editor as mp | |
from moviepy.video.tools.cuts import FramesMatches | |
# Extends FramesMatches, the code is copied from source file then modified | |
def _write_mp4s(self, clip, mp4s_dir, **kwargs): | |
for (start, end, _, _) in self: | |
name = "%s/%08d_%08d.mp4" % (mp4s_dir, 100 * start, 100 * end) | |
clip.subclip(start, end).write_videofile(name, **kwargs) | |
FramesMatches.write_mp4s = _write_mp4s | |
if len(sys.argv) != 2: | |
print("makegifs.py <video file>") | |
sys.exit(1) | |
clip = mp.VideoFileClip(sys.argv[1]) | |
name = os.path.splitext(os.path.basename(sys.argv[1]))[0] | |
if not os.path.isdir(name): os.mkdir(name) | |
# Skip matches, just load existed file if exists | |
if os.path.isfile(name+"/matches.txt"): | |
# load the scenes from a previous time to avoid recomputing them | |
scenes = FramesMatches.load(name+"/matches.txt") | |
else: | |
# Compute matches (slow; take more time) | |
# clip.resize() set with video's scaled-down dimenions in integer for best fits. | |
scenes = FramesMatches.from_clip(clip.resize(width=160), 5, 3) # I increase 2 to 3 to get more gifs | |
scenes.save(name+"/matches.txt") | |
""" | |
That's the hard part that you must tweak. Not that the whole method is | |
very sloppy so maybe you can just redefine/customize this function if | |
you have the time | |
The last number "0.5" says that you want at least 0.5 second between the start of each clip. | |
If you really want to avoid having multiple times the same scene with just a few different frames, | |
increase this to e.g. 1.5 | |
""" | |
selected_scenes = scenes.select_scenes(2, 0.5, 0, 0.5) | |
if not os.path.isdir(name+"/mp4"): os.mkdir(name+"/mp4") | |
selected_scenes.write_mp4s(clip.without_audio(), name+"/mp4") # save mp4 as it, without reencode (fast) | |
if not os.path.isdir(name+"/gif"): os.mkdir(name+"/gif") | |
gif_clip_width = clip.w / 2 | |
selected_scenes.write_gifs(clip.resize(width=gif_clip_width), name+"/gif") # save gif as it, resized by half |
Some notes based on looking up the source code and do several tries:
from_clip(clip, x, y)
At the moment I have no idea what is this. I tried to tweak the number up and down, either it ended up losing or unexpected result. Keep it as it is: x=5
and y=3
for best.
select_scenes(2, 0.5, 0, 0.5)
- Keep the first param as smallest possible for best seamless loop. You can set higher, eg
9
or so for more availability, but the loop kinda glitchy and doesn't seamless. - Keep the second param as it.
- Third param is the distance between gifs. The suggested value as the original code base is
4
, but in my case--a short video under 2 minutes, I set it at0
. - Forth param, consider follow as the comment mentioned.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Bonus: change the
write_gifs
ontowrite_videofile
on this linehttps://gist.github.com/gphg/60852c868bb38328e7003ad4bfcd69b7#file-makegifs-py-L35
to save the loop as video instead gif.
Edit:
I'll figured out how to fix it.
Update: I figured it and made some videos.
https://gfycat.com/@garett/collections/iiOjSrfe/delicious-party-precure
I'll post how to reproduce it later.