1import os 2 3from moviepy.audio.io.AudioFileClip import AudioFileClip 4from moviepy.Clip import Clip 5from moviepy.video.io.ffmpeg_reader import FFMPEG_VideoReader 6from moviepy.video.VideoClip import VideoClip 7 8 9class VideoFileClip(VideoClip): 10 11 """ 12 13 A video clip originating from a movie file. For instance: :: 14 15 >>> clip = VideoFileClip("myHolidays.mp4") 16 >>> clip.close() 17 >>> with VideoFileClip("myMaskVideo.avi") as clip2: 18 >>> pass # Implicit close called by context manager. 19 20 21 Parameters 22 ------------ 23 24 filename: 25 The name of the video file. It can have any extension supported 26 by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc. 27 28 has_mask: 29 Set this to 'True' if there is a mask included in the videofile. 30 Video files rarely contain masks, but some video codecs enable 31 that. For istance if you have a MoviePy VideoClip with a mask you 32 can save it to a videofile with a mask. (see also 33 ``VideoClip.write_videofile`` for more details). 34 35 audio: 36 Set to `False` if the clip doesn't have any audio or if you do not 37 wish to read the audio. 38 39 target_resolution: 40 Set to (desired_height, desired_width) to have ffmpeg resize the frames 41 before returning them. This is much faster than streaming in high-res 42 and then resizing. If either dimension is None, the frames are resized 43 by keeping the existing aspect ratio. 44 45 resize_algorithm: 46 The algorithm used for resizing. Default: "bicubic", other popular 47 options include "bilinear" and "fast_bilinear". For more information, see 48 https://ffmpeg.org/ffmpeg-scaler.html 49 50 fps_source: 51 The fps value to collect from the metadata. Set by default to 'tbr', but 52 can be set to 'fps', which may be helpful if importing slow-motion videos 53 that get messed up otherwise. 54 55 56 Attributes 57 ----------- 58 59 filename: 60 Name of the original video file. 61 62 fps: 63 Frames per second in the original file. 64 65 66 Read docs for Clip() and VideoClip() for other, more generic, attributes. 67 68 Lifetime 69 -------- 70 71 Note that this creates subprocesses and locks files. If you construct one of these instances, you must call 72 close() afterwards, or the subresources will not be cleaned up until the process ends. 73 74 If copies are made, and close() is called on one, it may cause methods on the other copies to fail. 75 76 """ 77 78 def __init__(self, filename, has_mask=False, 79 audio=True, audio_buffersize=200000, 80 target_resolution=None, resize_algorithm='bicubic', 81 audio_fps=44100, audio_nbytes=2, verbose=False, 82 fps_source='tbr'): 83 84 VideoClip.__init__(self) 85 86 # Make a reader 87 pix_fmt = "rgba" if has_mask else "rgb24" 88 self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt, 89 target_resolution=target_resolution, 90 resize_algo=resize_algorithm, 91 fps_source=fps_source) 92 93 # Make some of the reader's attributes accessible from the clip 94 self.duration = self.reader.duration 95 self.end = self.reader.duration 96 97 self.fps = self.reader.fps 98 self.size = self.reader.size 99 self.rotation = self.reader.rotation 100 101 self.filename = self.reader.filename 102 103 if has_mask: 104 105 self.make_frame = lambda t: self.reader.get_frame(t)[:,:,:3] 106 mask_mf = lambda t: self.reader.get_frame(t)[:,:,3]/255.0 107 self.mask = (VideoClip(ismask=True, make_frame=mask_mf) 108 .set_duration(self.duration)) 109 self.mask.fps = self.fps 110 111 else: 112 113 self.make_frame = lambda t: self.reader.get_frame(t) 114 115 # Make a reader for the audio, if any. 116 if audio and self.reader.infos['audio_found']: 117 118 self.audio = AudioFileClip(filename, 119 buffersize=audio_buffersize, 120 fps=audio_fps, 121 nbytes=audio_nbytes) 122 123 def close(self): 124 """ Close the internal reader. """ 125 if self.reader: 126 self.reader.close() 127 self.reader = None 128 129 try: 130 if self.audio: 131 self.audio.close() 132 self.audio = None 133 except AttributeError: 134 pass 135