Beispiel #1
0
def export_moviepy(sequence,
                   filename,
                   rate=30,
                   bitrate=None,
                   width=None,
                   height=None,
                   codec='mpeg4',
                   pixel_format='yuv420p',
                   autoscale=None,
                   quality=None,
                   verbose=True,
                   options=None,
                   rate_range=(16, 32)):
    """Export a sequence of images as a standard video file using MoviePy.

    Parameters
    ----------
    sequence : any iterator or array of array-like images
        The images should have two dimensions plus an
        optional third dimensions representing color.
    filename : string
        name of output file
    rate : integer, optional
        frame rate of output file, 30 by default
        NB: The output frame rate will be limited between `rate_range`
    bitrate : integer or string, optional
        Preferably use the parameter `quality` for controlling the bitrate.
    width : integer, optional
        By default, set the width of the images.
    height : integer, optional
        By default, set the  height of the images. If width is specified
        and height is not, the height is autoscaled to maintain the aspect
        ratio.
    codec : string
        a valid video encoding, 'mpeg4' by default. Must be supported by the
        container format. Examples are {'mpeg4', 'wmv2', 'libx264', 'rawvideo'}
        Check https://www.ffmpeg.org/ffmpeg-codecs.html#Video-Encoders.
    pixel_format: string, optional
        Pixel format, 'yuv420p' by default.
        Another possibility is 'bgr24' in combination with the 'rawvideo' codec.
    quality: number or string, optional
        For 'mpeg4' codec: sets qscale:v. 1 = high quality, 5 = default.
        For 'libx264' codec: sets crf. 0 = lossless, 23 = default.
        For 'wmv2' codec: sets fraction of lossless bitrate, 0.01 = default
    autoscale : boolean, optional
        Linearly rescale the brightness to use the full gamut of black to
        white values. False by default for uint8 readers, True otherwise.
    verbose : boolean, optional
        Determines whether MoviePy will print progress. True by default.
    options : dictionary, optional
        Dictionary of parameters that will be passed to ffmpeg. Avoid using
        {'qscale:v', 'crf', 'pixel_format'}.
    rate_range : tuple of two numbers
        As extreme frame rates have playback issues on many players, by default
        the frame rate is limited between 16 and 32. When the desired frame rate
        is too low, frames will be multiplied an integer number of times. When
        the desired frame rate is too high, frames will be skipped at constant
        intervals.

    See Also
    --------
    http://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.write_videofile
    """
    if VideoClip is None:
        raise ImportError('The MoviePy exporter requires moviepy to work.')

    if options is None:
        options = dict()
    ffmpeg_params = []
    for key in options:
        ffmpeg_params.extend(['-{}'.format(key), str(options[key])])

    if rate <= 0:
        raise ValueError
    export_rate = _normalize_framerate(rate, *rate_range)

    clip = VideoClip(
        CachedFrameGenerator(sequence,
                             rate,
                             autoscale,
                             to_bgr=(pixel_format == 'bgr24')))
    clip.duration = len(sequence) / rate
    if not (height is None and width is None):
        clip = clip.resize(height=height, width=width)

    if codec == 'wmv2' and bitrate is None and quality is None:
        quality = 0.01

    if quality is not None:
        if codec == 'libx264':
            ffmpeg_params.extend(['-crf', str(quality)])
        elif codec == 'mpeg4':
            ffmpeg_params.extend(['-qscale:v', str(quality)])
        elif codec == 'wmv2':
            if bitrate is not None:
                warnings.warn("(wmv) quality is ignored when bitrate is set.")
            else:
                bitrate = quality * _estimate_bitrate(clip.size, export_rate)
        else:
            raise NotImplemented

    if format is not None:
        ffmpeg_params.extend(['-pixel_format', str(pixel_format)])
    if bitrate is not None:
        bitrate = str(bitrate)

    clip.write_videofile(filename,
                         export_rate,
                         codec,
                         bitrate,
                         audio=False,
                         verbose=verbose,
                         ffmpeg_params=ffmpeg_params)
Beispiel #2
0
def export_moviepy(sequence, filename, rate=30, bitrate=None, width=None,
                   height=None, codec='mpeg4', pixel_format='yuv420p',
                   autoscale=None, quality=None, verbose=True,
                   options=None, rate_range=(16, 32)):
    """Export a sequence of images as a standard video file using MoviePy.

    Parameters
    ----------
    sequence : any iterator or array of array-like images
        The images should have two dimensions plus an
        optional third dimensions representing color.
    filename : string
        name of output file
    rate : integer, optional
        frame rate of output file, 30 by default
        NB: The output frame rate will be limited between `rate_range`
    bitrate : integer or string, optional
        Preferably use the parameter `quality` for controlling the bitrate.
    width : integer, optional
        By default, set the width of the images.
    height : integer, optional
        By default, set the  height of the images. If width is specified
        and height is not, the height is autoscaled to maintain the aspect
        ratio.
    codec : string
        a valid video encoding, 'mpeg4' by default. Must be supported by the
        container format. Examples are {'mpeg4', 'wmv2', 'libx264', 'rawvideo'}
        Check https://www.ffmpeg.org/ffmpeg-codecs.html#Video-Encoders.
    pixel_format: string, optional
        Pixel format, 'yuv420p' by default.
        Another possibility is 'bgr24' in combination with the 'rawvideo' codec.
    quality: number or string, optional
        For 'mpeg4' codec: sets qscale:v. 1 = high quality, 5 = default.
        For 'libx264' codec: sets crf. 0 = lossless, 23 = default.
        For 'wmv2' codec: sets fraction of lossless bitrate, 0.01 = default
    autoscale : boolean, optional
        Linearly rescale the brightness to use the full gamut of black to
        white values. False by default for uint8 readers, True otherwise.
    verbose : boolean, optional
        Determines whether MoviePy will print progress. True by default.
    options : dictionary, optional
        Dictionary of parameters that will be passed to ffmpeg. Avoid using
        {'qscale:v', 'crf', 'pixel_format'}.
    rate_range : tuple of two numbers
        As extreme frame rates have playback issues on many players, by default
        the frame rate is limited between 16 and 32. When the desired frame rate
        is too low, frames will be multiplied an integer number of times. When
        the desired frame rate is too high, frames will be skipped at constant
        intervals.

    See Also
    --------
    http://zulko.github.io/moviepy/ref/VideoClip/VideoClip.html#moviepy.video.VideoClip.VideoClip.write_videofile
    """
    if VideoClip is None:
        raise ImportError('The MoviePy exporter requires moviepy to work.')

    if options is None:
        options = dict()
    ffmpeg_params = []
    for key in options:
        ffmpeg_params.extend(['-{}'.format(key), str(options[key])])

    if rate <= 0:
        raise ValueError
    export_rate = _normalize_framerate(rate, *rate_range)

    clip = VideoClip(CachedFrameGenerator(sequence, rate, autoscale,
                                          to_bgr=(pixel_format == 'bgr24')))
    clip.duration = len(sequence) / rate
    if not (height is None and width is None):
        clip = clip.resize(height=height, width=width)

    if codec == 'wmv2' and bitrate is None and quality is None:
        quality = 0.01

    if quality is not None:
        if codec == 'libx264':
            ffmpeg_params.extend(['-crf', str(quality)])
        elif codec == 'mpeg4':
            ffmpeg_params.extend(['-qscale:v', str(quality)])
        elif codec == 'wmv2':
            if bitrate is not None:
                warnings.warn("(wmv) quality is ignored when bitrate is set.")
            else:
                bitrate = quality * _estimate_bitrate(clip.size, export_rate)
        else:
            raise NotImplemented

    if format is not None:
        ffmpeg_params.extend(['-pixel_format', str(pixel_format)])
    if bitrate is not None:
        bitrate = str(bitrate)

    clip.write_videofile(filename, export_rate, codec, bitrate, audio=False,
                         verbose=verbose, ffmpeg_params=ffmpeg_params)