Skip to main content

Supports async / await pattern for FFmpeg operations.

Project description

Asynchronous FFmpeg

Test Test Coverage Maintainability Code Climate technical debt Updates Python versions Twitter 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

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

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

ffmpeg_coroutine = FFmpegCoroutineFactory.create()

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

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.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

asyncffmpeg-1.0.1.tar.gz (14.7 kB view details)

Uploaded Source

Built Distribution

asyncffmpeg-1.0.1-py3-none-any.whl (13.3 kB view details)

Uploaded Python 3

File details

Details for the file asyncffmpeg-1.0.1.tar.gz.

File metadata

  • Download URL: asyncffmpeg-1.0.1.tar.gz
  • Upload date:
  • Size: 14.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for asyncffmpeg-1.0.1.tar.gz
Algorithm Hash digest
SHA256 4725c386c7baaa75903f49835ed65030a6c6b05b0da516c8ee38765f13e8abcb
MD5 86da4fe2e131497e4ad1687ed19a970e
BLAKE2b-256 3968379b94cae198e3e2a9ea9010d9a28ed84f91860f84e6651064a9eb47a025

See more details on using hashes here.

File details

Details for the file asyncffmpeg-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: asyncffmpeg-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 13.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.4.1 importlib_metadata/3.7.3 pkginfo/1.7.0 requests/2.25.1 requests-toolbelt/0.9.1 tqdm/4.59.0 CPython/3.9.2

File hashes

Hashes for asyncffmpeg-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 55ca519611b3036d42487e1d2360673eec2156d8ae566b7479355edb5548e945
MD5 abcd89629a604ec7880d37504505ade8
BLAKE2b-256 a94fbafb6beb3a94dd284104b8577512ee90e1aeda3dfd7feb5066461aa91070

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page