Package: asyncffmpeg
Asynchronous FFmpegSupports async / await pattern for FFmpeg operations.AdvantageSupport async / await pattern for FFmpeg operationsSupport Ctrl + C1. Support async / await pattern for FFmpeg operationsThis package supports FFmpeg asynchronously invoke with async / await pattern
wrappingffmpeg.run_async()offfmpeg-pythonand returnedsubprocess.Popen.The async / await syntax makes asynchronous code as:SimpleReadable2. Support Ctrl + CUser can stop FFmpeg process gracefully by Ctrl + C.
This works as same as sendingqkey to running FFmpeg.
This action is guaranteed by pytest.Quickstart1. Installpip install asyncffmpeg2. Implementasyncffmpeg.FFmpegCoroutineclass has asynchronous method:execute().
To run concurrently, it requires not multi threading but multi processing
since FFmpeg process is CPU-bound operation.
The packageasynccpuis helpful to simple implement.Ex:importffmpegfromasynccpuimportProcessTaskPoolExecutorfromasyncffmpegimportFFmpegCoroutineFactory,StreamSpecasyncdefcreate_stream_spec_copy()->StreamSpec:stream=ffmpeg.input("input.mp4")returnffmpeg.output(stream,"output1.mp4",c="copy")asyncdefcreate_stream_spec_filter()->StreamSpec:stream=ffmpeg.input("input.mp4")stream=ffmpeg.filter(stream,"scale",768,-1)returnffmpeg.output(stream,"output2.mp4")asyncdefmain()->None:ffmpeg_coroutine=FFmpegCoroutineFactory.create()withProcessTaskPoolExecutor(max_workers=3,cancel_tasks_when_shutdown=True)asexecutor:awaitables=(executor.create_process_task(ffmpeg_coroutine.execute,create_stream_spec)forcreate_stream_specin[create_stream_spec_copy,create_stream_spec_filter])awaitasyncio.gather(*awaitables)if__name__=="__main__":asyncio.run(main())Why notasynciobutasynccpu?Unfortunately High-level APIs ofasynciodoesn't support CPU-bound operations
since it works based on notProcessPoolExecutorbutThreadPoolExecutor.
When we want to run CPU-bound operations concurrently withasyncio,
we need to use Low-level APIs which need finer control over the event loop behavior.NoteThe argument ofCoroutinerequires not "rawCoroutineobject" but "Coroutinefunction"
since rawCoroutineobject is not picklable.This specification is depend on the one of Pythonmultiprocessingpackage:multiprocessing — Process-based parallelismNote When an object is put on a queue, the object is pickled
and a background thread later flushes the pickled data to an underlying pipe.See:Answer: Python multiprocessing PicklingError: Can't pickle <type 'function'> - Stack OverflowAPIFFmpegCoroutineFactoryclassFFmpegCoroutineFactory:@staticmethoddefcreate(*,time_to_force_termination:int=8)->FFmpegCoroutine:time_to_force_termination: int = 8The time limit (second) to wait stopping FFmpeg process gracefully
when send Ctrl + C.
At first, subprocess will try to sendqkey to FFmpeg process.
In case when FFmpeg process doesn't stop gracefully by time limit,
subprocess will terminate process.FFmpegCoroutineclassFFmpegCoroutine:asyncdefexecute(self,create_stream_spec:Callable[[],Awaitable[StreamSpec]],*,after_start:Optional[Callable[[FFmpegProcess],Awaitable]]=None)->None:create_stream_spec: Callable[[], Awaitable[StreamSpec]]Coroutinefunction to createstream specfor FFmpeg process.
Createdstream specwill be set the first argument offfmpeg.run_async()offfmpeg-pythoninside ofFFmpegCoroutine.stream specis a Stream, list of Streams, or label-to-Stream dictionary mapping
inffmpeg-python.after_start: Optional[Callable[[FFmpegProcess], Awaitable]] = NoneCoroutinefunction to execute after start FFmpeg process.CreditsThis package was created withCookiecutterand theyukihiko-shinoda/cookiecutter-pypackageproject template.