Example #1
0
def test_sequential_frame_pos():
    """test_video.mp4 contains 5 frames at 1 fps.
    Each frame is 1x1 pixels and the sequence is Red, Green, Blue, Black, White.
    The rgb values are not pure due to compression.
    """
    reader = FFMPEG_VideoReader("media/test_video.mp4")
    assert reader.pos == 1

    # Get first frame
    frame_1 = reader.get_frame(0)
    assert reader.pos == 1
    assert np.array_equal(frame_1, [[[254, 0, 0]]])

    # Get a specific sequential frame
    frame_2 = reader.get_frame(1)
    assert reader.pos == 2
    assert np.array_equal(frame_2, [[[0, 255, 1]]])

    # Get next frame. Note `.read_frame()` instead of `.get_frame()`
    frame_3 = reader.read_frame()
    assert reader.pos == 3
    assert np.array_equal(frame_3, [[[0, 0, 255]]])

    # Skip a frame
    skip_frame = reader.get_frame(4)
    assert reader.pos == 5
    assert np.array_equal(skip_frame, [[[255, 255, 255]]])
Example #2
0
def test_large_skip_frame_pos():
    reader = FFMPEG_VideoReader("media/big_buck_bunny_0_30.webm")
    assert reader.fps == 24

    # 10 sec * 24 fps = 240 frames
    frame = reader.get_frame(240 // 24)
    assert reader.pos == 241

    frame2 = reader.get_frame(719 / 24)
    assert reader.pos == 720

    # Go backwards
    backwards_frame = reader.get_frame(120 // 24)
    assert reader.pos == 121
Example #3
0
def default_loader(path, frame_selector, transform=None):
    video = Video(path)
    frames = frame_selector.select(video.nframes, video.fps)
    if transform:
        state = random.getstate()
        data = [_same_transform((video.get_frame(f / video.fps)), transform, state) for f in frames]
        random.seed(None)
    else:
        data = [video.get_frame(f / video.fps) for f in frames]
    if isinstance(data[0], np.ndarray):
        return np.stack(data)
    elif isinstance(data[0], torch.Tensor):
        return torch.stack(data)
    else:
        raise RuntimeError()
Example #4
0
def video_uniform_sample_n_frames_old(video_path, n_samples, max_dim):
    """
    Sample only n frames from the video.
    """

    raise Exception('Needs to add argument about resizing type')

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    step = duration / (n_samples)

    frames = []
    for i in range(n_samples):
        time_sec = i * step
        frame = cap.get_frame(time_sec)
        # resize frame to fit in the array, it's going to be used by caffe anyway
        frame = image_utils.resize_keep_aspect_ratio_max_dim(frame, max_dim)
        # frame encoded as uint and values are from 0-255
        # but caffe needs float32 and values from 0-1
        frame = frame.astype('float32') / float(255)
        frames.append(frame)

    # very important, or we'd have memory leakage
    cap.__del__()

    return frames
Example #5
0
def __play_video_ffmpeg(video_path, caption, window_name='window', speed=1):
    is_playing = True

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    n_frames = cap.nframes

    index = 0
    while True:
        if is_playing:
            time_sec = index / fps
            # increment by speed
            index += speed
            frame = cap.get_frame(time_sec)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame_size = frame.shape

            # resize the frame
            f_width = 800
            resize_factor = float(f_width) / frame_size[1]
            f_height = int(frame_size[0] * resize_factor)
            frame_size = (f_width, f_height)
            frame = cv2.resize(src=frame,
                               dsize=frame_size,
                               interpolation=cv2.INTER_AREA)

            # write caption on frame
            top = int((f_height * 0.9))
            text_width = cv2.getTextSize(caption, font, 1.2, 1)[0][0] + 20
            cv2.rectangle(frame, (0, top - 22), (text_width, top + 10),
                          black_color, cv2.cv.CV_FILLED)
            cv2.putText(img=frame,
                        text=caption,
                        org=(10, top),
                        fontFace=font,
                        fontScale=1.2,
                        color=white_color,
                        thickness=1,
                        lineType=8)

            # show the frame
            cv2.imshow(window_name, frame)

            e = cv2.waitKey(2)
            if e == 27:
                break
            if e == 32:
                is_playing = False
                print('Pause video')
            # If the number of captured frames is equal to the total number of frames,we stop
            if index >= n_frames:
                break
        else:
            # toggle pause with 'space'
            e = cv2.waitKey(2)
            if e == 32:
                is_playing = True
                print('Play video')
Example #6
0
def get_regions(video_path, annot, resize_type, verbose=False):
    """
    Get the frames whose numbers are given in the "annot" dictionary.. Then, for each frame get the regions as specificed in the "annot" dictionary.
    Finally, return these regions.
    """

    assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    n_frames = cap.nframes
    duration = cap.duration
    n_regions = sum([len(v) for k, v in annot.iteritems()])

    frame_size = 224
    bbox_resize_factor = 2
    regions = np.zeros(shape=(n_regions, frame_size, frame_size, 3),
                       dtype='float32')
    region_idx = -1

    frame_nums = annot.keys()
    for frame_num in frame_nums:

        if (region_idx + 1) % 100 == 0 and verbose:
            print(' ... reading region %d/%d' % (region_idx + 1, n_regions))

        # get the frame
        i = frame_num - 1
        time_sec = i / fps
        frame = cap.get_frame(time_sec)

        # get the regions (resized) from the frame
        regions_info = annot[frame_num]
        for region_info in regions_info:
            region_idx += 1
            bbox = region_info[1:5]
            bbox = np.multiply(bbox, bbox_resize_factor).astype(np.int)
            x1, y1, x2, y2 = bbox
            region = frame[y1:y2, x1:x2]
            # resize frame to fit in the array, it's going to be used by caffe anyway
            region = resize_function(region)
            # frame encoded as uint and values are from 0-255, but caffe needs float32 and values from 0-1
            region = region.astype('float32') / float(255)
            regions[region_idx] = region

    # very important, or we'd have memory leakage
    cap.__del__()

    return regions
Example #7
0
def test_large_small_skip_equal():
    sequential_reader = FFMPEG_VideoReader("media/big_buck_bunny_0_30.webm")
    small_skip_reader = FFMPEG_VideoReader("media/big_buck_bunny_0_30.webm")
    large_skip_reader = FFMPEG_VideoReader("media/big_buck_bunny_0_30.webm")
    assert small_skip_reader.fps == large_skip_reader.fps == sequential_reader.fps == 24

    # Read every frame sequentially
    for t in np.arange(0, 10, 1 / 24):
        sequential_reader.get_frame(t)
    sequential_final_frame = sequential_reader.get_frame(10)

    # Read in increments of 24 frames
    for t in range(10):
        small_skip_reader.get_frame(t)
    small_skip_final_frame = small_skip_reader.get_frame(10)

    # Jumps straight forward 240 frames. This is greater than 100 so it uses
    # FFmpeg to reseek at the right position.
    large_skip_final_frame = large_skip_reader.get_frame(10)

    assert (
        sequential_reader.pos == small_skip_reader.pos == large_skip_reader.pos == 241
    )

    # All frames have gone forward an equal amount, so should be equal
    assert np.array_equal(sequential_final_frame, small_skip_final_frame)
    assert np.array_equal(small_skip_final_frame, large_skip_final_frame)
Example #8
0
def test_seeking_beyond_file_end():
    reader = FFMPEG_VideoReader("media/test_video.mp4")
    frame_1 = reader.get_frame(0)

    with pytest.warns(UserWarning, match="Using the last valid frame instead"):
        end_of_file_frame = reader.get_frame(5)
    assert np.array_equal(frame_1, end_of_file_frame)
    assert reader.pos == 6

    # Try again with a jump larger than 100 frames
    # (which triggers different behaivour in `.get_frame()`
    reader = FFMPEG_VideoReader("media/big_buck_bunny_0_30.webm")
    frame_1 = reader.get_frame(0)

    with pytest.warns(UserWarning, match="Using the last valid frame instead"):
        end_of_file_frame = reader.get_frame(30)
    assert np.array_equal(frame_1, end_of_file_frame)
    assert reader.pos == 30 * 24 + 1
Example #9
0
    def __init__(self,
                 filename,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False):

        VideoClip.__init__(self)

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
        self.reader = reader
        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size

        self.filename = self.reader.filename

        if has_mask:

            self.make_frame = lambda t: reader.get_frame(t)[:, :, :3]
            mask_mf = lambda t: reader.get_frame(t)[:, :, 3] / 255.0
            self.mask = (VideoClip(
                ismask=True, make_frame=mask_mf).set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:

            self.audio = AudioFileClip(filename,
                                       buffersize=audio_buffersize,
                                       fps=audio_fps,
                                       nbytes=audio_nbytes)
Example #10
0
def get_frame(video, t_frame=0.0):
    """Crop a single frame from the video to check cropping result. Stored alongside video.

    :param video: Path to video
    :param t_frame: position to extract example frame from, in seconds. Default: 0
    :return: image

    """
    clip = FFMPEG_VideoReader(str(video)) 
    image = clip.get_frame(t_frame)

    return image
Example #11
0
    def __init__(self, filename, has_mask=False,
                 audio=True, audio_buffersize = 200000,
                 audio_fps=44100, audio_nbytes=2, verbose=False, iterframe_callback=None):
        
        VideoClip.__init__(self)
        
        # Make a reader
        pix_fmt= "rgba" if has_mask else "rgb24"
        reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
        self.reader = reader
        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration
        
        self.fps = self.reader.fps
        self.size = self.reader.size

        if has_mask:

            self.make_frame = lambda t: reader.get_frame(t)[:,:,:3]
            mask_mf =  lambda t: reader.get_frame(t)[:,:,3]/255.0
            self.mask = (VideoClip(ismask = True, make_frame = mask_mf)
                       .set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: reader.get_frame(t)
        
        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:

            self.audio = AudioFileClip(filename,
                                       buffersize= audio_buffersize,
                                       fps = audio_fps,
                                       nbytes = audio_nbytes)

        self.iterframe_callback = iterframe_callback
Example #12
0
def test_unusual_order_frame_pos():
    reader = FFMPEG_VideoReader("media/test_video.mp4")
    assert reader.pos == 1

    # Go straight to end
    end_frame = reader.get_frame(4)
    assert reader.pos == 5
    assert np.array_equal(end_frame, [[[255, 255, 255]]])

    # Repeat the previous frame
    second_end_frame = reader.get_frame(4)
    assert reader.pos == 5
    assert np.array_equal(second_end_frame, [[[255, 255, 255]]])

    # Go backwards
    previous_frame = reader.get_frame(3)
    assert reader.pos == 4
    assert np.array_equal(previous_frame, [[[0, 0, 0]]])

    # Go back to start
    start_frame = reader.get_frame(0)
    assert reader.pos == 1
    assert np.array_equal(start_frame, [[[254, 0, 0]]])
Example #13
0
def video_save_frames_specific_duration(action_num,
                                        video_num,
                                        video_path,
                                        frames_root_pathes,
                                        start_stop_sec,
                                        image_name_format,
                                        verbose=False):
    assert len(frames_root_pathes) == len(start_stop_sec)

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    duration_sec = cap.duration
    img_dim = 224

    start_stop_sec = np.array(start_stop_sec)

    for i, s_s_sec in enumerate(start_stop_sec):
        start_sec, stop_sec = s_s_sec
        frame_root_path = frames_root_pathes[i]

        # offset of starting/stopping the action
        sec_offset = 0.25

        start_idx = int((start_sec + sec_offset) * fps)
        stop_idx = int((stop_sec + sec_offset) * fps) + 1

        if verbose:
            print('action, video: %d, %d' % (action_num, video_num))
            print('%d/%d' % (start_sec, stop_sec))
            print('%d/%d' % (start_idx, stop_idx))

        for idx_frame in range(start_idx, stop_idx):
            time_sec = idx_frame / fps
            if verbose and idx_frame % 100 == 0:
                print('... time_sec, frame: %d/%d' % (time_sec, idx_frame))

            frame = cap.get_frame(time_sec)
            frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
            frame = image_utils.resize_crop(frame,
                                            target_width=img_dim,
                                            target_height=img_dim)

            image_name = image_name_format % (idx_frame, )
            frame_path = os.path.join(frame_root_path, image_name)
            cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.__del__()
Example #14
0
def video_uniform_sample_and_save_old(spf,
                                      video_path,
                                      frames_path,
                                      image_name_format,
                                      resize_type,
                                      verbose=False):
    if resize_type is not None:
        assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    n_samples = int(duration / float(spf))

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    for i in range(n_samples):
        num = i + 1
        if verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf
        frame = cap.get_frame(time_sec)

        if resize_type is not None:
            # resize frame to fit in the array, it's going to be used by caffe anyway
            frame = resize_function(frame)

        frame = cv2.cvtColor(frame, cv2.COLOR_RGB2BGR)
        image_name = image_name_format % (num, )
        frame_path = os.path.join(frames_path, image_name)
        cv2.imwrite(frame_path, frame)

    # very important, or we'd have memory leakage
    cap.close()

    return fps, n_frames, duration
Example #15
0
def video_uniform_sampling(spf,
                           video_path,
                           resize_type,
                           is_local,
                           verbose=False):
    assert resize_type in ['resize', 'resize_crop', 'resize_crop_scaled']

    resize_function = None
    if resize_type == 'resize':
        resize_function = image_utils.resize_frame
    elif resize_type == 'resize_crop':
        resize_function = image_utils.resize_crop
    elif resize_type == 'resize_crop_scaled':
        resize_function = image_utils.resize_crop_scaled

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = cap.fps
    n_frames = cap.nframes
    duration = cap.duration
    n_samples = int(duration / float(spf))

    # check if no samples because the video duration is less than spf
    # then at least, get 1 frame of the video
    if n_samples == 0:
        n_samples = 1

    frame_size = 224
    frames = np.zeros(shape=(n_samples, frame_size, frame_size, 3),
                      dtype='float32')
    for i in range(n_samples):
        num = i + 1
        if num % 100 == 0 and verbose:
            print(' ... reading frame %d/%d' % (num, n_samples))
        time_sec = i * spf
        frame = cap.get_frame(time_sec)
        # resize frame to fit in the array, it's going to be used by caffe anyway
        frame = resize_function(frame)
        # frame encoded as uint and values are from 0-255
        # but caffe needs float32 and values from 0-1
        frame = frame.astype('float32') / float(255)
        frames[i] = frame

    # very important, or we'd have memory leakage
    cap.__del__()

    return frames, fps, n_frames, duration
Example #16
0
def comparechunk(queryVidName, dbVidName, dbStart, dbEnd, thresh):
    """
    This function takes the names of the files to compare, and where in the
    comparison file to begin checking from. Threshold is a user determined value
    that they chose qualitatively, and the GUI turned into a quantitative number
    Args: path to query video, path to comparison video, start frame number, 
    endframe number, callback to process results, RMSE threshold (a number from 
    0-255, realistically should be between 10-50)
    """
    # Create the FFMPEG class variables
    dbVid = FFMPEG_VideoReader(dbVidName)
    queryVid = FFMPEG_VideoReader(queryVidName)

    # Skip to the correct frames in the video
    frameQ = queryVid.get_frame(0)
    dbVid.skip_frames(dbStart)
    frameD = dbVid.read_frame()

    scores = []

    # Compare the first frame in the query video to every frame in the chunk
    belowThresh = []
    for i in range(dbStart, dbEnd):
        score = frame_rmse(frameQ, frameD)
        # Immediately look at startframes below the threshold
        if frame_rmse(frameQ, frameD) < thresh:
            print "Found a frame below the threshold. Scanning sequence..."
            score = startpointCompare(queryVidName, dbVidName, i)
            if score < thresh and score is not None:
                scores.append({
                    "Video Name": dbVidName,
                    "Timestamp": secondsToTimestamp(i / dbVid.fps),
                    "Frame Number": i,
                    "Score": score
                })
                return scores
            else:
                print "A sequence had a poor score of", score, ". Moving on..."
        frameD = dbVid.read_frame()

    return scores
Example #17
0
class VideoFileClip(VideoClip):
    """
    
    A video clip originating from a movie file. For instance: ::
    
        >>> clip = VideoFileClip("myHolidays.mp4")
        >>> clip2 = VideoFileClip("myMaskVideo.avi")
    
    
    Parameters
    ------------
    
    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
      
    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For istance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also 
      ``VideoClip.write_videofile`` for more details).
    
    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.

    target_resolution:
      Set to (desired_height, desired_width) to have ffmpeg resize the frames
      before returning them. This is much faster than streaming in high-res
      and then resizing. If either dimension is None, the frames are resized
      by keeping the existing aspect ratio.

    resize_algorithm:
      The algorithm used for resizing. Default: "bicubic", other popular
      options include "bilinear" and "fast_bilinear". For more information, see
      https://ffmpeg.org/ffmpeg-scaler.html

      
    Attributes
    -----------
    
    filename:
      Name of the original video file.
    
    fps:
      Frames per second in the original file.
      
    Read docstrings for Clip() and VideoClip() for other, more generic, attributes.
        
    """
    def __init__(self,
                 filename,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 target_resolution=None,
                 resize_algorithm='bicubic',
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False):

        VideoClip.__init__(self)

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        self.reader = None  # need this just in case FFMPEG has issues (__del__ complains)
        self.reader = FFMPEG_VideoReader(filename,
                                         pix_fmt=pix_fmt,
                                         target_resolution=target_resolution,
                                         resize_algo=resize_algorithm)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size

        self.filename = self.reader.filename

        if has_mask:

            self.make_frame = lambda t: self.reader.get_frame(t)[:, :, :3]
            mask_mf = lambda t: self.reader.get_frame(t)[:, :, 3] / 255.0
            self.mask = (VideoClip(
                ismask=True, make_frame=mask_mf).set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:

            self.audio = AudioFileClip(filename,
                                       buffersize=audio_buffersize,
                                       fps=audio_fps,
                                       nbytes=audio_nbytes)

    def __del__(self):
        """ Close/delete the internal reader. """
        try:
            del self.reader
        except AttributeError:
            pass

        try:
            del self.audio
        except AttributeError:
            pass
Example #18
0
class VideoFileClip(VideoClip):

    """
    
    A video clip originating from a movie file. For instance: ::
    
        >>> clip = VideofileClip("myHolidays.mp4")
        >>> clip2 = VideofileClip("myMaskVideo.avi")
    
    
    Parameters
    ------------
    
    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
      
    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For istance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also 
      ``VideoClip.to_videofile`` for more details).
    
    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.
      
    Attributes
    -----------
    
    filename:
      Name of the original video file.
    
    fps:
      Frames per second in the original file. 
        
    """

    def __init__(self, filename, has_mask=False,
                 audio=True, audio_buffersize = 200000,
                 audio_fps=44100, audio_nbytes=2, verbose=False):
        
        VideoClip.__init__(self)
        
        # Make a reader
        pix_fmt= "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
        
        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration
        
        self.fps = self.reader.fps
        self.size = self.reader.size

        if has_mask:

          self.get_frame = lambda t: self.reader.get_frame(t)[:,:,:3]
          mask_gf =  lambda t: self.reader.get_frame(t)[:,:,3]/255.0
          self.mask = (VideoClip(ismask = True, get_frame = mask_gf)
                       .set_duration(self.duration))
          self.mask.fps = self.fps

        else:

          self.get_frame = lambda t: self.reader.get_frame(t)
        
        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:
            self.audio = AudioFileClip(filename,
                                       buffersize= audio_buffersize,
                                       fps = audio_fps,
                                       nbytes = audio_nbytes)
Example #19
0
def play_video_specific_frames(video_path, seconds, caption=''):
    """
    Play video. Show only frames at given seconds.
    """

    is_playing = True

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    speed = 1
    sec_idx = -1
    n_secs = len(seconds)
    window_name = 'Window_Title'

    while True:
        if is_playing:
            sec_idx += 1

            # finish condition
            if sec_idx >= n_secs:
                break

            second = seconds[sec_idx]
            frame = cap.get_frame(second)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame_size = frame.shape

            # resize the frame
            f_width = 800
            resize_factor = float(f_width) / frame_size[1]
            f_height = int(frame_size[0] * resize_factor)
            frame_size = (f_width, f_height)
            frame = cv2.resize(src=frame,
                               dsize=frame_size,
                               interpolation=cv2.INTER_AREA)

            # write caption on frame
            top = int((f_height * 0.9))
            text_width = cv2.getTextSize(caption, font, 1.2, 1)[0][0] + 20
            cv2.rectangle(frame, (0, top - 22), (text_width, top + 10),
                          black_color, -1)
            cv2.putText(img=frame,
                        text=caption,
                        org=(10, top),
                        fontFace=font,
                        fontScale=1.2,
                        color=white_color,
                        thickness=1,
                        lineType=8)

            # show the frame
            cv2.imshow(window_name, frame)

            e = cv2.waitKey(1)
            if e == 27:
                break
            if e == 32:
                is_playing = False
                print('Pause video')
        else:
            # toggle pause with 'space'
            e = cv2.waitKey(2)
            if e == 32:
                is_playing = True
                print('Play video')
Example #20
0
class VideoFileClip(VideoClip):

    """
    
    A video clip originating from a movie file. For instance:
    
    >>> clip = VideofileClip("myHolidays.mp4")
    >>> clip2 = VideofileClip("myMaskVideo.avi",ismask = True)
    
    :param filename: Any video file: .ogv, .mp4, .mpeg, .avi, .mov etc.
    :param ismask: `True` if the clip is a mask.
    :param has_mask: 'True' if there is a mask included in the videofile.
       Commonly, video files don't have mask, but you can save the mask
       for the videos that you make with MoviePy (see the doc from
       ``VideoClip.to_videofile`` for more details).
    :param audio: If `True`, then the audio is extracted from the video
                  file, in wav format, and it attributed to the clip.
    
    :ivar filename: Name of the original video file
    :ivar fps: Frames per second in the original file. 
        
    """

    def __init__(self, filename, ismask=False, has_mask=False,
                 audio=True, audio_buffersize = 200000,
                 audio_fps=44100, audio_nbytes=2, verbose=False):
        
        VideoClip.__init__(self, ismask)
        
        # We store the construction parameters in case we need to make
        # a copy (a 'co-reader').
        
        self.parameters = {'filename':filename, 'ismask':ismask,
                           'has_mask':has_mask, 'audio':audio,
                           'audio_buffersize':audio_buffersize}
        
        # Make a reader
        pix_fmt= "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
        
        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.fps = self.reader.fps
        self.size = self.reader.size
        self.get_frame = lambda t: self.reader.get_frame(t)
        
        # Make a reader for the audio, if any.
        if audio:
            try:
                self.audio = AudioFileClip(filename, buffersize= audio_buffersize,
                    fps = audio_fps, nbytes = audio_nbytes)
            except:
                if verbose:
                    print "No audio found in %s"%filename
                pass
    
    def coreader(self, audio=True):
        """ Returns a copy of the AudioFileClip, i.e. a new entrance point
            to the video file. Use copy when you have different clips
            watching the same video file at different times. """
        return VideoFileClip(**self.parameters)
Example #21
0
class VideoFileClip(VideoClip):

    """
    
    A video clip originating from a movie file. For instance: ::
    
        >>> clip = VideofileClip("myHolidays.mp4")
        >>> clip2 = VideofileClip("myMaskVideo.avi",ismask = True)
    
    
    Parameters
    ------------
    
    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
    
    ismask:
      Set this to `True` if the clip is going to be used as a mask.
      
    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
       Video files rarely contain masks, but some video codecs enable
       that. For istance if you have a MoviePy VideoClip with a mask you
       can save it to a videofile with a mask. (see also 
       ``VideoClip.to_videofile`` for more details).
    
    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.
      
    Attributes
    -----------
    
    filename:
      Name of the original video file.
    
    fps:
      Frames per second in the original file. 
        
    """

    def __init__(self, filename, ismask=False, has_mask=False,
                 audio=True, audio_buffersize = 200000,
                 audio_fps=44100, audio_nbytes=2, verbose=False):
        
        VideoClip.__init__(self, ismask)
        
        # We store the construction parameters in case we need to make
        # a copy (a 'co-reader').
        
        self.parameters = {'filename':filename, 'ismask':ismask,
                           'has_mask':has_mask, 'audio':audio,
                           'audio_buffersize':audio_buffersize}
        
        # Make a reader
        pix_fmt= "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)
        
        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration
        
        self.fps = self.reader.fps
        self.size = self.reader.size
        self.get_frame = lambda t: self.reader.get_frame(t)
        
        # Make a reader for the audio, if any.
        if audio:
            self.audio = AudioFileClip(filename,
                                       buffersize= audio_buffersize,
                                       fps = audio_fps,
                                       nbytes = audio_nbytes)
    
    def coreader(self, audio=True):
        """
        Returns a copy of the AudioFileClip with an autonomous reader.
        Maybe REMOVED in the coming versions. Wait and see. ::
        
            >>> clip = VideofileClip("myHolidays.mp4", ismask=True)
            >>> clip2 = VideofileClip("myHolidays.mp4", ismask=True)
        
        is equivalent to ::
        
            >>> clip = VideofileClip("myHolidays.mp4", ismask=True)
            >>> clip2 = clip.coreader()
        """
            
        return VideoFileClip(**self.parameters)
Example #22
0
def play_video_specific_frames_matplotlib(video_path, seconds, caption=''):
    """
    Play video. Show only frames at given seconds.
    """

    cap = FFMPEG_VideoReader(video_path, False)
    cap.initialize()
    fps = float(cap.fps)
    speed = 1
    sec_idx = -1
    n_secs = len(seconds)
    window_name = 'Window_Title'

    plt.figure(window_name)
    plt.ion()
    plt.axis('off')

    global is_exit
    global is_playing

    is_exit = False
    is_playing = True

    def __key_press(event):
        event_key = event.key
        if event_key == 'escape':
            global is_exit
            is_exit = True
        elif event_key == ' ':
            global is_playing
            is_playing = not is_playing

    fig = plt.gcf()
    fig.canvas.mpl_connect('key_press_event', __key_press)

    while True:
        if is_exit:
            break
        if is_playing:
            sec_idx += 1

            # finish condition
            if sec_idx >= n_secs:
                break

            second = seconds[sec_idx]
            frame = cap.get_frame(second)
            frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
            frame_size = frame.shape

            # resize the frame
            f_width = 800
            resize_factor = float(f_width) / frame_size[1]
            f_height = int(frame_size[0] * resize_factor)
            frame_size = (f_width, f_height)
            frame = cv2.resize(src=frame,
                               dsize=frame_size,
                               interpolation=cv2.INTER_AREA)

            # write caption
            plt.title(caption)

            # show the frame
            frame = frame[:, :, (2, 1, 0)]
            plt.imshow(frame)

        # in both case, pause figure to capture key press
        plt.pause(0.01)

    plt.close()
                                repeat=False)
 anim.save(tmp_video_name,
           fps=1,
           extra_args=['-vcodec', 'libx264'],
           dpi=dpi)
 new_fps = 24
 play_slow_rate = 1.5  # controls how many times a frame repeats.
 movie_reader = FFMPEG_VideoReader(tmp_video_name)
 movie_writer = FFMPEG_VideoWriter(video_save_newFps_name,
                                   movie_reader.size, new_fps)
 print "n_frames:", movie_reader.nframes
 # the 1st frame of the saved video can't be directly read by movie_reader.read_frame(), I don't know why
 # maybe it's a bug of anim.save, actually, if we look at the movie we get from anim.save
 # we can easilly see that the 1st frame just close very soon.
 # so I manually get it at time 0, this is just a trick, I think.
 tmp_frame = movie_reader.get_frame(0)
 [
     movie_writer.write_frame(tmp_frame)
     for _ in range(int(new_fps * play_slow_rate))
 ]
 # for the above reason, we should read (movie_reader.nframes-1) frames so that the last frame is not
 # read twice (not that get_frame(0) alread read once)
 # However, I soon figure out that it should be (movie_reader.nframes-2). The details: we have actually
 # 6 frames, but (print movie_reader.nframes) is 7. I read the first frame through movie_reader.get_frame(0)
 # then are are 5 left. So I should use movie_reader.nframes - 2. Note that in fig1_pcm_fs2.py
 # in the case of: original fps=1
 # new_fps = 24, play_slow_rate = 1.5 the result is: 1st frame last 1.8s, others 1.5s, i.e., the 1st frame
 # has more duration. This is messy.
 for i in range(movie_reader.nframes - 2):
     tmp_frame = movie_reader.read_frame()
     [
    def __getitem__(self, index):
        # Find the video first.
        vid = np.histogram(index, self.sums)
        assert (np.sum(vid[0]) == 1)
        vid = np.where(vid[0] > 0)[0][0]

        v_fmax = len(self.gt_list[vid])
        vframe = index - self.sums[vid]
        #vframes = [min(vframe + i, len(self.gt_list[vid])- 1) for i in np.arange(0, 1 +10*self.multi_frame, 10)]
        #vframes = [min(vframe, len(self.gt_list[vid])- 1)]
        #cap = self.video_list[vid]

        imgs = []
        if self.prod_Img:

            cap = FFMPEG_VideoReader(self.video_list[vid])
            cap.initialize()

            for i in range(self.multi_frame):
                if i == 0:
                    img = cap.get_frame(vframe / cap.fps)
                else:
                    cap.skip_frames(n=9)
                    img = cap.read_frame()

                img = Image.fromarray(img)
                if self.transform is not None:
                    img = self.transform(img)
                imgs.append(img)
            '''
            for v in vframes:
                #cap = cv2.VideoCapture(self.video_list[vid])
                #assert cap.isOpened() == True, 'The Video cannot be read:{}'.format(self.video_list[vid])
                

                #cap.set(1, v)
                #ret, frame= cap.read()
                img = cap.get_frame(v)
                #assert ret == True, 'Cannot Load this frame{}:{}'.format(self.video_list[vid], v)
                #cv2_im = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
                img = Image.fromarray(img)
                if self.transform is not None:
                    img = self.transform(img)
                imgs.append(img)    
            '''
            imgs = [img.unsqueeze(0) for img in imgs]
            imgs = torch.cat(imgs, 0)

        text = []
        if self.prod_Text:
            text = self.text_list[vid][
                min(vframe + self.text_delay, len(self.text_list[vid])
                    ):min(vframe + self.text_window +
                          self.text_delay, len(self.text_list[vid]))]
            text = '\n'.join(text)

        gt = self.gt_list[vid][vframe]

        if (len(text) == 0):
            text = ' '
        #text = text_util.lineToTensor(text)

        return imgs, text, gt
Example #25
0
class VideoFileClip(VideoClip):
    """

    A video clip originating from a movie file. For instance: ::

        >>> clip = VideoFileClip("myHolidays.mp4")
        >>> clip.close()
        >>> with VideoFileClip("myMaskVideo.avi") as clip2:
        >>>    pass  # Implicit close called by context manager.


    Parameters
    ------------

    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.

    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For istance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also
      ``VideoClip.write_videofile`` for more details).

    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.

    target_resolution:
      Set to (desired_height, desired_width) to have ffmpeg resize the frames
      before returning them. This is much faster than streaming in high-res
      and then resizing. If either dimension is None, the frames are resized
      by keeping the existing aspect ratio.

    resize_algorithm:
      The algorithm used for resizing. Default: "bicubic", other popular
      options include "bilinear" and "fast_bilinear". For more information, see
      https://ffmpeg.org/ffmpeg-scaler.html

    fps_source:
      The fps value to collect from the metadata. Set by default to 'tbr', but
      can be set to 'fps', which may be helpful if importing slow-motion videos
      that get messed up otherwise.


    Attributes
    -----------

    filename:
      Name of the original video file.

    fps:
      Frames per second in the original file.


    Read docs for Clip() and VideoClip() for other, more generic, attributes.

    Life time
    --------

    Note that this creates sub-processes and locks files. If you construct one of these instances, you must call
    close() afterwards, or the sub-resources will not be cleaned up until the process ends.

    If copies are made, and close() is called on one, it may cause methods on the other copies to fail.

    """
    def __init__(self,
                 filename,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 target_resolution=None,
                 resize_algorithm='bicubic',
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False,
                 fps_source='tbr'):

        VideoClip.__init__(self)

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename,
                                         pix_fmt=pix_fmt,
                                         target_resolution=target_resolution,
                                         resize_algo=resize_algorithm,
                                         fps_source=fps_source)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size
        self.rotation = self.reader.rotation

        self.filename = self.reader.filename

        if has_mask:

            self.make_frame = lambda t: self.reader.get_frame(t)[:, :, :3]
            mask_mf = lambda t: self.reader.get_frame(t)[:, :, 3] / 255.0
            self.mask = (VideoClip(
                ismask=True, make_frame=mask_mf).set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:
            self.audio = AudioFileClip(filename,
                                       buffersize=audio_buffersize,
                                       fps=audio_fps,
                                       nbytes=audio_nbytes)

    def close(self):
        """ Close the internal reader. """
        if self.reader:
            self.reader.close()
            self.reader = None

        try:
            if self.audio:
                self.audio.close()
                self.audio = None
        except AttributeError:
            pass
Example #26
0
class VideoFileClip(VideoClip):
    """
    
    A video clip originating from a movie file. For instance:
    
    >>> clip = VideofileClip("myHolidays.mp4")
    >>> clip2 = VideofileClip("myMaskVideo.avi",ismask = True)
    
    :param filename: Any video file: .ogv, .mp4, .mpeg, .avi, .mov etc.
    :param ismask: `True` if the clip is a mask.
    :param has_mask: 'True' if there is a mask included in the videofile.
       Commonly, video files don't have mask, but you can save the mask
       for the videos that you make with MoviePy (see the doc from
       ``VideoClip.to_videofile`` for more details).
    :param audio: If `True`, then the audio is extracted from the video
                  file, in wav format, and it attributed to the clip.
    
    :ivar filename: Name of the original video file
    :ivar fps: Frames per second in the original file. 
        
    """
    def __init__(self,
                 filename,
                 ismask=False,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False):

        VideoClip.__init__(self, ismask)

        # We store the construction parameters in case we need to make
        # a copy (a 'co-reader').

        self.parameters = {
            'filename': filename,
            'ismask': ismask,
            'has_mask': has_mask,
            'audio': audio,
            'audio_buffersize': audio_buffersize
        }

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.fps = self.reader.fps
        self.size = self.reader.size
        self.get_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio:
            try:
                self.audio = AudioFileClip(filename,
                                           buffersize=audio_buffersize,
                                           fps=audio_fps,
                                           nbytes=audio_nbytes)
            except:
                if verbose:
                    print "No audio found in %s" % filename
                pass

    def coreader(self, audio=True):
        """ Returns a copy of the AudioFileClip, i.e. a new entrance point
            to the video file. Use copy when you have different clips
            watching the same video file at different times. """
        return VideoFileClip(**self.parameters)
Example #27
0
class VideoFileClip(VideoClip):
    """
    
    A video clip originating from a movie file. For instance: ::
    
        >>> clip = VideofileClip("myHolidays.mp4")
        >>> clip2 = VideofileClip("myMaskVideo.avi")
    
    
    Parameters
    ------------
    
    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
      
    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For istance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also 
      ``VideoClip.to_videofile`` for more details).
    
    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.
      
    Attributes
    -----------
    
    filename:
      Name of the original video file.
    
    fps:
      Frames per second in the original file. 
        
    """
    def __init__(self,
                 filename,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False):

        VideoClip.__init__(self)

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size

        if has_mask:

            self.get_frame = lambda t: self.reader.get_frame(t)[:, :, :3]
            mask_gf = lambda t: self.reader.get_frame(t)[:, :, 3] / 255.0
            self.mask = (VideoClip(
                ismask=True, get_frame=mask_gf).set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.get_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:
            self.audio = AudioFileClip(filename,
                                       buffersize=audio_buffersize,
                                       fps=audio_fps,
                                       nbytes=audio_nbytes)

    def __del__(self):
        """ Close/delete the internal reader. """
        del self.reader
Example #28
0
class VideoFileClip(VideoClip):

    """

    A video clip originating from a movie file. For instance: ::

        >>> clip = VideoFileClip("myHolidays.mp4")
        >>> clip.close()
        >>> with VideoFileClip("myMaskVideo.avi") as clip2:
        >>>    pass  # Implicit close called by contex manager.


    Parameters
    ------------

    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.

    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For istance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also
      ``VideoClip.write_videofile`` for more details).

    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.

    target_resolution:
      Set to (desired_height, desired_width) to have ffmpeg resize the frames
      before returning them. This is much faster than streaming in high-res
      and then resizing. If either dimension is None, the frames are resized
      by keeping the existing aspect ratio.

    resize_algorithm:
      The algorithm used for resizing. Default: "bicubic", other popular
      options include "bilinear" and "fast_bilinear". For more information, see
      https://ffmpeg.org/ffmpeg-scaler.html

    fps_source:
      The fps value to collect from the metadata. Set by default to 'tbr', but
      can be set to 'fps', which may be helpful if importing slow-motion videos
      that get messed up otherwise.


    Attributes
    -----------

    filename:
      Name of the original video file.

    fps:
      Frames per second in the original file.
    
    
    Read docs for Clip() and VideoClip() for other, more generic, attributes.
    
    Lifetime
    --------
    
    Note that this creates subprocesses and locks files. If you construct one of these instances, you must call
    close() afterwards, or the subresources will not be cleaned up until the process ends.
    
    If copies are made, and close() is called on one, it may cause methods on the other copies to fail.  

    """

    def __init__(self, filename, has_mask=False,
                 audio=True, audio_buffersize = 200000,
                 target_resolution=None, resize_algorithm='bicubic',
                 audio_fps=44100, audio_nbytes=2, verbose=False,
                 fps_source='tbr'):

        VideoClip.__init__(self)

        # Make a reader
        pix_fmt= "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt,
                                         target_resolution=target_resolution,
                                         resize_algo=resize_algorithm,
                                         fps_source=fps_source)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size
        self.rotation = self.reader.rotation

        self.filename = self.reader.filename

        if has_mask:

            self.make_frame = lambda t: self.reader.get_frame(t)[:,:,:3]
            mask_mf =  lambda t: self.reader.get_frame(t)[:,:,3]/255.0
            self.mask = (VideoClip(ismask = True, make_frame = mask_mf)
                       .set_duration(self.duration))
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos['audio_found']:

            self.audio = AudioFileClip(filename,
                                       buffersize= audio_buffersize,
                                       fps = audio_fps,
                                       nbytes = audio_nbytes)

    def close(self):
        """ Close the internal reader. """
        if self.reader:
            self.reader.close()
            self.reader = None

        try:
            if self.audio:
                self.audio.close()
                self.audio = None
        except AttributeError:
            pass
Example #29
0
frameNum = int(cap.get(7))
fps = int(cap.get(5))

fgbg = cv2.createBackgroundSubtractorMOG2(detectShadows=False)

FrameDiff = np.array([])

lapse = int(sys.argv[2])

i = 0

while (i < frameNum):
    ret, frame = cap.read()
    fgmask = fgbg.apply(frame)
    if i > lapse * fps + 1 and i < frameNum - fps:
        ref = rec.get_frame((i - lapse * fps) / fps)
        refmask = fgbg.apply(ref)
        try:
            frameDelta = cv2.absdiff(refmask, fgmask)
        except:
            frameDelta = np.array([])
            print(str(i) + ' out of ' + str(frameNum))
        entry = [float(i) / fps, np.sum(frameDelta)]
        FrameDiff = np.insert(FrameDiff, [0], entry, axis=0)
    if i < frameNum - fps:
        try:
            cv2.imshow('frame', fgmask)
        except:
            print(str(i) + ' out of ' + str(frameNum))
            break
    i += 1
Example #30
0
class VideoFileClip(VideoClip):
    """
    A video clip originating from a movie file. For instance: ::

        >>> clip = VideoFileClip("myHolidays.mp4")
        >>> clip.close()
        >>> with VideoFileClip("myMaskVideo.avi") as clip2:
        >>>    pass  # Implicit close called by context manager.


    Parameters
    ----------

    filename:
      The name of the video file, as a string or a path-like object.
      It can have any extension supported by ffmpeg:
      .ogv, .mp4, .mpeg, .avi, .mov etc.

    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
      Video files rarely contain masks, but some video codecs enable
      that. For instance if you have a MoviePy VideoClip with a mask you
      can save it to a videofile with a mask. (see also
      ``VideoClip.write_videofile`` for more details).

    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.

    target_resolution:
      Set to (desired_width, desired_height) to have ffmpeg resize the frames
      before returning them. This is much faster than streaming in high-res
      and then resizing. If either dimension is None, the frames are resized
      by keeping the existing aspect ratio.

    resize_algorithm:
      The algorithm used for resizing. Default: "bicubic", other popular
      options include "bilinear" and "fast_bilinear". For more information, see
      https://ffmpeg.org/ffmpeg-scaler.html

    fps_source:
      The fps value to collect from the metadata. Set by default to 'fps', but
      can be set to 'tbr', which may be helpful if you are finding that it is reading
      the incorrect fps from the file.

    pixel_format
      Optional: Pixel format for the video to read. If is not specified
      'rgb24' will be used as the default format unless ``has_mask`` is set
      as ``True``, then 'rgba' will be used.


    Attributes
    ----------

    filename:
      Name of the original video file.

    fps:
      Frames per second in the original file.


    Read docs for Clip() and VideoClip() for other, more generic, attributes.

    Lifetime
    --------

    Note that this creates subprocesses and locks files. If you construct one
    of these instances, you must call close() afterwards, or the subresources
    will not be cleaned up until the process ends.

    If copies are made, and close() is called on one, it may cause methods on
    the other copies to fail.

    """
    @convert_path_to_string("filename")
    def __init__(
        self,
        filename,
        decode_file=False,
        has_mask=False,
        audio=True,
        audio_buffersize=200000,
        target_resolution=None,
        resize_algorithm="bicubic",
        audio_fps=44100,
        audio_nbytes=2,
        fps_source="fps",
        pixel_format=None,
    ):

        VideoClip.__init__(self)

        # Make a reader
        if not pixel_format:
            pixel_format = "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(
            filename,
            decode_file=decode_file,
            pixel_format=pixel_format,
            target_resolution=target_resolution,
            resize_algo=resize_algorithm,
            fps_source=fps_source,
        )

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size
        self.rotation = self.reader.rotation

        self.filename = filename

        if has_mask:

            self.make_frame = lambda t: self.reader.get_frame(t)[:, :, :3]

            def mask_make_frame(t):
                return self.reader.get_frame(t)[:, :, 3] / 255.0

            self.mask = VideoClip(is_mask=True,
                                  make_frame=mask_make_frame).with_duration(
                                      self.duration)
            self.mask.fps = self.fps

        else:

            self.make_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio and self.reader.infos["audio_found"]:

            self.audio = AudioFileClip(
                filename,
                buffersize=audio_buffersize,
                fps=audio_fps,
                nbytes=audio_nbytes,
            )

    def __deepcopy__(self, memo):
        """Implements ``copy.deepcopy(clip)`` behaviour as ``copy.copy(clip)``.

        VideoFileClip class instances can't be deeply copied because the locked Thread
        of ``proc`` isn't pickleable. Without this override, calls to
        ``copy.deepcopy(clip)`` would raise a ``TypeError``:

        ```
        TypeError: cannot pickle '_thread.lock' object
        ```
        """
        return self.__copy__()

    def close(self):
        """Close the internal reader."""
        if self.reader:
            self.reader.close()
            self.reader = None

        try:
            if self.audio:
                self.audio.close()
                self.audio = None
        except AttributeError:  # pragma: no cover
            pass
Example #31
0
class VideoFileClip(VideoClip):
    """
    
    A video clip originating from a movie file. For instance: ::
    
        >>> clip = VideofileClip("myHolidays.mp4")
        >>> clip2 = VideofileClip("myMaskVideo.avi",ismask = True)
    
    
    Parameters
    ------------
    
    filename:
      The name of the video file. It can have any extension supported
      by ffmpeg: .ogv, .mp4, .mpeg, .avi, .mov etc.
    
    ismask:
      Set this to `True` if the clip is going to be used as a mask.
      
    has_mask:
      Set this to 'True' if there is a mask included in the videofile.
       Video files rarely contain masks, but some video codecs enable
       that. For istance if you have a MoviePy VideoClip with a mask you
       can save it to a videofile with a mask. (see also 
       ``VideoClip.to_videofile`` for more details).
    
    audio:
      Set to `False` if the clip doesn't have any audio or if you do not
      wish to read the audio.
      
    Attributes
    -----------
    
    filename:
      Name of the original video file.
    
    fps:
      Frames per second in the original file. 
        
    """
    def __init__(self,
                 filename,
                 ismask=False,
                 has_mask=False,
                 audio=True,
                 audio_buffersize=200000,
                 audio_fps=44100,
                 audio_nbytes=2,
                 verbose=False):

        VideoClip.__init__(self, ismask)

        # We store the construction parameters in case we need to make
        # a copy (a 'co-reader').

        self.parameters = {
            'filename': filename,
            'ismask': ismask,
            'has_mask': has_mask,
            'audio': audio,
            'audio_buffersize': audio_buffersize
        }

        # Make a reader
        pix_fmt = "rgba" if has_mask else "rgb24"
        self.reader = FFMPEG_VideoReader(filename, pix_fmt=pix_fmt)

        # Make some of the reader's attributes accessible from the clip
        self.duration = self.reader.duration
        self.end = self.reader.duration

        self.fps = self.reader.fps
        self.size = self.reader.size
        self.get_frame = lambda t: self.reader.get_frame(t)

        # Make a reader for the audio, if any.
        if audio:
            self.audio = AudioFileClip(filename,
                                       buffersize=audio_buffersize,
                                       fps=audio_fps,
                                       nbytes=audio_nbytes)

    def coreader(self, audio=True):
        """
        Returns a copy of the AudioFileClip with an autonomous reader.
        Maybe REMOVED in the coming versions. Wait and see. ::
        
            >>> clip = VideofileClip("myHolidays.mp4", ismask=True)
            >>> clip2 = VideofileClip("myHolidays.mp4", ismask=True)
        
        is equivalent to ::
        
            >>> clip = VideofileClip("myHolidays.mp4", ismask=True)
            >>> clip2 = clip.coreader()
        """

        return VideoFileClip(**self.parameters)