Created
February 26, 2017 22:00
-
-
Save eruffaldi/0ee7509d383ef64d18bb3b0e0b6d1a2f to your computer and use it in GitHub Desktop.
Moviepy slicing in time and space
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
# Clips and Crops moviepy videos using slicers | |
# | |
# Emanuele Ruffaldi 2017 | |
# | |
from moviepy.editor import * | |
import moviepy.video.fx.crop | |
# TODO support multiple ranges | |
# TODO normalized time | |
class TSlicer: | |
def __init__(self,target): | |
self.target = target | |
def __getitem__(self,key): | |
if isinstance(key,tuple): | |
# tuple of slices | |
print key | |
elif isinstance(key,slice): | |
# TODO decide for .step | |
if key.step is not None: | |
raise BaseException("TSlicer step not supported " + key) | |
return self.target.subclip(key.start,None if key.stop == 9223372036854775807 else key.stop) | |
elif isinstance(key,float) or isinstance(key,int): | |
return self.target.to_ImageClip(key) | |
class ISlicer: | |
def __init__(self,target): | |
self.target = target | |
def __getitem__(self,key): | |
if isinstance(key,tuple): | |
if len(key) == 2: | |
return self.target.fx(moviepy.video.fx.crop.crop, key[0].start,key[1].start,key[0].stop,key[1].stop) | |
else: | |
raise BaseException("expected slicing [x1:x2,y1:y2]") | |
elif isinstance(key,slice): | |
raise BaseException("only tuple slicing") | |
else: | |
raise BaseException("only tuple slicing") | |
# normalized image slicer | |
class NSlicer: | |
def __init__(self,target): | |
self.target = target | |
def __getitem__(self,key): | |
print key | |
if isinstance(key,tuple): | |
if len(key) == 2: | |
k,ky = self.target.size | |
print k,ky,key,int(key[0].start*k),int(key[0].stop*k),int(key[1].start*ky),int(key[1].stop*ky) | |
# TODO handle missing and excess | |
return self.target.fx(moviepy.video.fx.crop.crop, int(key[0].start*k),int(key[1].start*k),int(key[0].stop*ky),int(key[1].stop*ky)) | |
else: | |
raise BaseException("expected slicing [x1:x2,y1:y2]") | |
elif isinstance(key,slice): | |
raise BaseException("only tuple slicing") | |
else: | |
raise BaseException("only tuple slicing") | |
# Note | |
# x[:,...] = (None,None,None) | |
# x[1:,...] = (1,None,None) | |
# x[2:,....] with 9223372036854775807 | |
# monkeypatching | |
setattr(VideoClip,"t",lambda self: TSlicer(self)) | |
setattr(VideoClip,"n",lambda self: NSlicer(self)) | |
setattr(VideoClip,"i",lambda self: ISlicer(self)) | |
if __name__ == '__main__': | |
import sys | |
x = VideoFileClip(sys.argv[1]) | |
y = x.t()[10].set_duration(10) # single frames require duration | |
y = x.t()[2:5] | |
y = x.t()[2:] | |
y = y.n()[0.2:1.0,0:1] | |
#y = y.i()[0.2:1.0,0:1] | |
print "Result:",y.duration,y.size | |
#y = y.i()[10:100,10:100] | |
#y = y.i()[10:100,20:300] | |
y.preview() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment