10000 Merge https://github.com/akolpakov/ffmpeg-python · SUNNET-Kei-Ou/ffmpeg-python@8cb7013 · GitHub
[go: up one dir, main page]

Skip to content

Commit 8cb7013

Browse files
author
SUNNET-Kei-Ou
committed
2 parents ab42ab4 + 7f70fb8 commit 8cb7013

File tree

2 files changed

+66
-1
lines changed

2 files changed

+66
-1
lines changed

ffmpeg/_run.py

Lines changed: 35 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import copy
88
import operator
99
import subprocess
10+
import asyncio
1011

1112
from ._ffmpeg import input, output
1213
from .nodes import (
@@ -326,4 +327,37 @@ def run(
326327
return out, err
327328

328329

329-
__all__ = ['compile', 'Error', 'get_args', 'run', 'run_async']
330+
@output_operator()
331+
async def run_asyncio(
332+
stream_spec, cmd='ffmpeg', pipe_stdin=False, pipe_stdout=False, pipe_stderr=False,
333+
quiet=False, overwrite_output=False):
334+
"""Asynchronously invoke ffmpeg in asyncio sync/await style and return coroutine.
335+
Have the same possibilities as `run_async` call.
336+
337+
Args:
338+
pipe_stdin: if True, connect pipe to subprocess stdin (to be
339+
used with ``pipe:`` ffmpeg inputs).
340+
pipe_stdout: if True, connect pipe to subprocess stdout (to be
341+
used with ``pipe:`` ffmpeg outputs).
342+
pipe_stderr: if True, connect pipe to subprocess stderr.
343+
quiet: shorthand for setting ``capture_stdout`` and
344+
``capture_stderr``.
345+
346+
Returns:
347+
A Process instance as a coroutine
348+
"""
349+
350+
args = compile(stream_spec, cmd, overwrite_output=overwrite_output)
351+
stdin_stream = asyncio.subprocess.PIPE if pipe_stdin else None
352+
stdout_stream = asyncio.subprocess.PIPE if pipe_stdout or quiet else None
353+
stderr_stream = asyncio.subprocess.PIPE if pipe_stderr or quiet else None
354+
355+
return await asyncio.create_subprocess_exec(
356+
*args,
357+
stdin=stdin_stream,
358+
stdout=stdout_stream,
359+
stderr=stderr_stream
360+
)
361+
362+
363+
__all__ = ['compile', 'Error', 'get_args', 'run', 'run_async', 'run_asyncio']

ffmpeg/tests/test_ffmpeg.py

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,7 @@
11
from __future__ import unicode_literals
2+
3+
import asyncio
4+
25
from builtins import bytes
36
from builtins import range
47
from builtins import str
@@ -716,3 +719,31 @@ def test__probe__exception():
716719
def test__probe__extra_args():
717720
data = ffmpeg.probe(TEST_INPUT_FILE1, show_frames=None)
718721
assert set(data.keys()) == {'format', 'streams', 'frames'}
722+
723+
724+
def test_run_asyncio():
725+
async def test_async():
726+
process = await (
727+
ffmpeg
728+
.input(TEST_INPUT_FILE1)
729+
.output('pipe:', format='rawvideo', pix_fmt='rgb24')['v']
730+
.run_asyncio(pipe_stdout=True, quiet=False)
731+
)
732+
733+
video_frame_size = 320 * 240 * 3 # Note: RGB24 == 3 bytes per pixel. 320x240 - video size
734+
735+
total_bytes = 0
736+
737+
while True:
738+
frame_bytes = await process.stdout.read(video_frame_size)
739+
if len(frame_bytes) == 0:
740+
break
741+
else:
742+
total_bytes += len(frame_bytes)
743+
744+
await process.wait()
745+
746+
assert total_bytes == 48153600, 'Incorrect size of the output frames'
747+
748+
loop = asyncio.get_event_loop()
749+
loop.run_until_complete(test_async())

0 commit comments

Comments
 (0)
9 0