Asyncio support async/await #200

This commit is contained in:
Andrey Kolpakov 2019-05-05 00:00:04 +02:00
parent 3ddc5f04bf
commit 7f70fb8f37
2 changed files with 66 additions and 0 deletions

View File

@ -7,6 +7,7 @@ import collections
import copy
import operator
import subprocess
import asyncio
from ._ffmpeg import (
input,
@ -296,10 +297,44 @@ def run(
return out, err
@output_operator()
async def run_asyncio(
stream_spec, cmd='ffmpeg', pipe_stdin=False, pipe_stdout=False, pipe_stderr=False,
quiet=False, overwrite_output=False):
"""Asynchronously invoke ffmpeg in asyncio sync/await style and return coroutine.
Have the same possibilities as `run_async` call.
Args:
pipe_stdin: if True, connect pipe to subprocess stdin (to be
used with ``pipe:`` ffmpeg inputs).
pipe_stdout: if True, connect pipe to subprocess stdout (to be
used with ``pipe:`` ffmpeg outputs).
pipe_stderr: if True, connect pipe to subprocess stderr.
quiet: shorthand for setting ``capture_stdout`` and
``capture_stderr``.
Returns:
A Process instance as a coroutine
"""
args = compile(stream_spec, cmd, overwrite_output=overwrite_output)
stdin_stream = asyncio.subprocess.PIPE if pipe_stdin else None
stdout_stream = asyncio.subprocess.PIPE if pipe_stdout or quiet else None
stderr_stream = asyncio.subprocess.PIPE if pipe_stderr or quiet else None
return await asyncio.create_subprocess_exec(
*args,
stdin=stdin_stream,
stdout=stdout_stream,
stderr=stderr_stream
)
__all__ = [
'compile',
'Error',
'get_args',
'run',
'run_async',
'run_asyncio',
]

View File

@ -1,4 +1,7 @@
from __future__ import unicode_literals
import asyncio
from builtins import bytes
from builtins import range
from builtins import str
@ -655,3 +658,31 @@ def test__probe__exception():
def test__probe__extra_args():
data = ffmpeg.probe(TEST_INPUT_FILE1, show_frames=None)
assert set(data.keys()) == {'format', 'streams', 'frames'}
def test_run_asyncio():
async def test_async():
process = await (
ffmpeg
.input(TEST_INPUT_FILE1)
.output('pipe:', format='rawvideo', pix_fmt='rgb24')['v']
.run_asyncio(pipe_stdout=True, quiet=False)
)
video_frame_size = 320 * 240 * 3 # Note: RGB24 == 3 bytes per pixel. 320x240 - video size
total_bytes = 0
while True:
frame_bytes = await process.stdout.read(video_frame_size)
if len(frame_bytes) == 0:
break
else:
total_bytes += len(frame_bytes)
await process.wait()
assert total_bytes == 48153600, 'Incorrect size of the output frames'
loop = asyncio.get_event_loop()
loop.run_until_complete(test_async())