Skip to main content

Asynchronous FFmpeg

Test CodeQL Code Coverage Maintainability Dependabot Python versions X URL

Supports async / await pattern for FFmpeg operations.

Advantage

  1. Support async / await pattern for FFmpeg operations
  2. Support Ctrl + C

1. Support async / await pattern for FFmpeg operations

This package supports FFmpeg asynchronously invoke with async / await pattern wrapping ffmpeg.run_async() of ffmpeg-python and returned subprocess.Popen.

The async / await syntax makes asynchronous code as:

  • Simple
  • Readable

2. Support Ctrl + C

User can stop FFmpeg process gracefully by Ctrl + C. This works as same as sending q key to running FFmpeg. This action is guaranteed by pytest.

Quickstart

1. Install

pip install asyncffmpeg

2. Implement

asyncffmpeg.FFmpegCoroutine class has asynchronous method: execute(). To run concurrently, it requires not multi threading but multi processing since FFmpeg process is CPU-bound operation. The package asynccpu is helpful to simple implement.

Ex:

import ffmpeg
from asynccpu import ProcessTaskPoolExecutor
from asyncffmpeg import FFmpegCoroutineFactory, StreamSpec


async def create_stream_spec_copy() -> StreamSpec:
    stream = ffmpeg.input("input.mp4")
    return ffmpeg.output(stream, "output1.mp4", c="copy")


async def create_stream_spec_filter() -> StreamSpec:
    stream = ffmpeg.input("input.mp4")
    stream = ffmpeg.filter(stream, "scale", 768, -1)
    return ffmpeg.output(stream, "output2.mp4")


async def main() -> None:
    ffmpeg_coroutine = FFmpegCoroutineFactory.create()

    with ProcessTaskPoolExecutor(max_workers=3, cancel_tasks_when_shutdown=True) as executor:
        awaitables = (
            executor.create_process_task(ffmpeg_coroutine.execute, create_stream_spec)
            for create_stream_spec in [create_stream_spec_copy, create_stream_spec_filter]
        )
        await asyncio.gather(*awaitables)


if __name__ == "__main__":
    asyncio.run(main())

Why not asyncio but asynccpu ?

Unfortunately High-level APIs of asyncio doesn't support CPU-bound operations since it works based on not ProcessPoolExecutor but ThreadPoolExecutor. When we want to run CPU-bound operations concurrently with asyncio, we need to use Low-level APIs which need finer control over the event loop behavior.

Note

The argument of Coroutine requires not "raw Coroutine object" but "Coroutine function" since raw Coroutine object is not picklable.

This specification is depend on the one of Python multiprocessing package:

multiprocessing — Process-based parallelism

Note 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 Overflow

API

FFmpegCoroutineFactory

class FFmpegCoroutineFactory:
    @staticmethod
    def create(
        *,
        time_to_force_termination: int = 8
    ) -> FFmpegCoroutine:

time_to_force_termination: int = 8

The time limit (second) to wait stopping FFmpeg process gracefully when send Ctrl + C. At first, subprocess will try to send q key to FFmpeg process. In case when FFmpeg process doesn't stop gracefully by time limit, subprocess will terminate process.

FFmpegCoroutine

class FFmpegCoroutine:
    async def execute(
        self,
        create_stream_spec: Callable[[], Awaitable[StreamSpec]],
        *,
        after_start: Optional[Callable[[FFmpegProcess], Awaitable]] = None
    ) -> None:

create_stream_spec: Callable[[], Awaitable[StreamSpec]]

Coroutine function to create stream spec for FFmpeg process. Created stream spec will be set the first argument of ffmpeg.run_async() of ffmpeg-python inside of FFmpegCoroutine. stream spec is a Stream, list of Streams, or label-to-Stream dictionary mapping in ffmpeg-python.

after_start: Optional[Callable[[FFmpegProcess], Awaitable]] = None

Coroutine function to execute after start FFmpeg process.

Credits

This package was created with Cookiecutter and the yukihiko-shinoda/cookiecutter-pypackage project template.

Release files for asyncffmpeg 1.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for asyncffmpeg 1.4.0
File Size Uploaded
asyncffmpeg-1.4.0.tar.gz 20.5 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for asyncffmpeg 1.4.0
File Interpreter ABI Platform
asyncffmpeg-1.4.0-py3-none-any.whl Python 3 none any Details

Total release size: 34.5 kB

Release files / asyncffmpeg-1.4.0.tar.gz

Download URL asyncffmpeg-1.4.0.tar.gz
Size 20.5 kB
Tags Source
SHA-256 checksum
How to use checksums
e70fbc16298c7995edae3c878eb18d29388f545e0f67ba17b10a5b3f45b7bda6
BLAKE2b-256 checksum
How to use checksums
0c20cbea4c77ab9ac665d1f7869f9d8e681c2d07673602c2a0b0ab001a1e87ae
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release files / asyncffmpeg-1.4.0-py3-none-any.whl

Download URL asyncffmpeg-1.4.0-py3-none-any.whl
Size 14.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
e154a005d4b198c939f1a806bd2abfe4c7d6d9cd26ed58f3706ad06d2b4fcdcc
BLAKE2b-256 checksum
How to use checksums
49cd92bcad9954b62327763b42dbfaefd2e43d0400fff38158db68d96e8ea0ca
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.1.0 CPython/3.13.12

Release history Release notifications | RSS feed

This release

1.4.0 This release

2 release files

1.3.1

2 release files

1.3.0

2 release files

1.2.0

2 release files

1.1.0

2 release files

1.0.1

2 release files

1.0.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page