Source code for moviepy.video.io.ffplay_previewer

"""
On the long term this will implement several methods to make videos
out of VideoClips
"""

import subprocess as sp

from moviepy.config import FFPLAY_BINARY
from moviepy.tools import cross_platform_popen_params


[docs] class FFPLAY_VideoPreviewer: """A class for FFPLAY-based video preview. Parameters ---------- size : tuple or list Size of the output video in pixels (width, height). fps : int Frames per second in the output video file. pixel_format : str Pixel format for the output video file, ``rgb24`` for normal video, ``rgba`` if video with mask. """ def __init__( self, size, fps, pixel_format, ): # order is important cmd = [ FFPLAY_BINARY, "-autoexit", # If you don't precise, ffplay won't stop at end "-f", "rawvideo", "-pixel_format", pixel_format, "-video_size", "%dx%d" % (size[0], size[1]), "-framerate", "%.02f" % fps, "-", ] popen_params = cross_platform_popen_params( {"stdout": sp.DEVNULL, "stderr": sp.STDOUT, "stdin": sp.PIPE} ) self.proc = sp.Popen(cmd, **popen_params)
[docs] def show_frame(self, img_array): """Writes one frame in the file.""" try: self.proc.stdin.write(img_array.tobytes()) except IOError as err: _, ffplay_error = self.proc.communicate() if ffplay_error is not None: ffplay_error = ffplay_error.decode() error = ( f"{err}\n\nMoviePy error: FFPLAY encountered the following error while " f"previewing clip :\n\n {ffplay_error}" ) raise IOError(error)
[docs] def close(self): """Closes the writer, terminating the subprocess if is still alive.""" if self.proc: self.proc.stdin.close() if self.proc.stderr is not None: self.proc.stderr.close() self.proc.wait() self.proc = None
# Support the Context Manager protocol, to ensure that resources are cleaned up. def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.close()
[docs] def ffplay_preview_video( clip, fps, pixel_format="rgb24", audio_flag=None, video_flag=None ): """Preview the clip using ffplay. See VideoClip.preview for details on the parameters. Parameters ---------- clip : VideoClip The clip to preview fps : int Number of frames per seconds in the displayed video. pixel_format : str, optional Warning: This is not used anywhere in the code and should probably be removed. It is believed pixel format rgb24 does not work properly for now because it requires applying a mask on CompositeVideoClip and that is believed to not be working. Pixel format for the output video file, ``rgb24`` for normal video, ``rgba`` if video with mask audio_flag : Thread.Event, optional A thread event that video will wait for. If not provided we ignore audio video_flag : Thread.Event, optional A thread event that video will set after first frame has been shown. If not provided, we simply ignore """ with FFPLAY_VideoPreviewer(clip.size, fps, pixel_format) as previewer: first_frame = True for t, frame in clip.iter_frames(with_times=True, fps=fps, dtype="uint8"): previewer.show_frame(frame) # After first frame is shown, if we have audio/video flag, set video ready # and wait for audio if first_frame: first_frame = False if video_flag: video_flag.set() # say to the audio: video is ready if audio_flag: audio_flag.wait() # wait for the audio to be ready