-
-
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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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)
9
or so for more availability, but the loop kinda glitchy and doesn't seamless.4
, but in my case--a short video under 2 minutes, I set it at0
.