mirror of
https://github.com/kkroening/ffmpeg-python.git
synced 2025-08-10 13:10:03 +08:00
Update examples
This commit is contained in:
parent
6364513485
commit
de124673e0
@ -22,10 +22,12 @@ def generate_thumbnail(in_filename, out_filename, time, width):
|
|||||||
.input(in_filename, ss=time)
|
.input(in_filename, ss=time)
|
||||||
.filter_('scale', width, -1)
|
.filter_('scale', width, -1)
|
||||||
.output(out_filename, vframes=1)
|
.output(out_filename, vframes=1)
|
||||||
.run(capture_stdout=True, capture_stderr=True, overwrite_output=True)
|
.overwrite_output()
|
||||||
|
.run(capture_stdout=True, capture_stderr=True)
|
||||||
)
|
)
|
||||||
except ffmpeg.Error as e:
|
except ffmpeg.Error as e:
|
||||||
print(e.stderr.decode(), file=sys.stderr)
|
print(e.stderr.decode(), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
ffmpeg-python
|
ffmpeg-python
|
||||||
|
gevent
|
||||||
google-cloud-speech
|
google-cloud-speech
|
||||||
|
tqdm
|
||||||
|
130
examples/show_progress.py
Executable file
130
examples/show_progress.py
Executable file
@ -0,0 +1,130 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
from __future__ import unicode_literals, print_function
|
||||||
|
from tqdm import tqdm
|
||||||
|
import argparse
|
||||||
|
import contextlib
|
||||||
|
import ffmpeg
|
||||||
|
import gevent
|
||||||
|
import gevent.monkey; gevent.monkey.patch_all(thread=False)
|
||||||
|
import os
|
||||||
|
import shutil
|
||||||
|
import socket
|
||||||
|
import sys
|
||||||
|
import tempfile
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description=textwrap.dedent('''\
|
||||||
|
Process video and report and show progress bar.
|
||||||
|
|
||||||
|
This is an example of using the ffmpeg `-progress` option with a
|
||||||
|
unix-domain socket to report progress in the form of a progress
|
||||||
|
bar.
|
||||||
|
|
||||||
|
The video processing simply consists of converting the video to
|
||||||
|
sepia colors, but the same pattern can be applied to other use
|
||||||
|
cases.
|
||||||
|
'''))
|
||||||
|
|
||||||
|
parser.add_argument('in_filename', help='Input filename')
|
||||||
|
parser.add_argument('out_filename', help='Output filename')
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _tmpdir_scope():
|
||||||
|
tmpdir = tempfile.mkdtemp()
|
||||||
|
try:
|
||||||
|
yield tmpdir
|
||||||
|
finally:
|
||||||
|
shutil.rmtree(tmpdir)
|
||||||
|
|
||||||
|
|
||||||
|
def _do_watch_progress(filename, sock, handler):
|
||||||
|
"""Function to run in a separate gevent greenlet to read progress
|
||||||
|
events from a unix-domain socket."""
|
||||||
|
connection, client_address = sock.accept()
|
||||||
|
data = b''
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
more_data = connection.recv(16)
|
||||||
|
if not more_data:
|
||||||
|
break
|
||||||
|
data += more_data
|
||||||
|
lines = data.split(b'\n')
|
||||||
|
for line in lines[:-1]:
|
||||||
|
line = line.decode()
|
||||||
|
parts = line.split('=')
|
||||||
|
key = parts[0] if len(parts) > 0 else None
|
||||||
|
value = parts[1] if len(parts) > 1 else None
|
||||||
|
handler(key, value)
|
||||||
|
data = lines[-1]
|
||||||
|
finally:
|
||||||
|
connection.close()
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def _watch_progress(handler):
|
||||||
|
"""Context manager for creating a unix-domain socket and listen for
|
||||||
|
ffmpeg progress events.
|
||||||
|
|
||||||
|
The socket filename is yielded from the context manager and the
|
||||||
|
socket is closed when the context manager is exited.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
handler: a function to be called when progress events are
|
||||||
|
received; receives a ``key`` argument and ``value``
|
||||||
|
argument. (The example ``show_progress`` below uses tqdm)
|
||||||
|
|
||||||
|
Yields:
|
||||||
|
socket_filename: the name of the socket file.
|
||||||
|
"""
|
||||||
|
with _tmpdir_scope() as tmpdir:
|
||||||
|
socket_filename = os.path.join(tmpdir, 'sock')
|
||||||
|
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
|
||||||
|
with contextlib.closing(sock):
|
||||||
|
sock.bind(socket_filename)
|
||||||
|
sock.listen(1)
|
||||||
|
child = gevent.spawn(_do_watch_progress, socket_filename, sock, handler)
|
||||||
|
try:
|
||||||
|
yield socket_filename
|
||||||
|
except:
|
||||||
|
gevent.kill(child)
|
||||||
|
raise
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
@contextlib.contextmanager
|
||||||
|
def show_progress(total_duration):
|
||||||
|
"""Create a unix-domain socket to watch progress and render tqdm
|
||||||
|
progress bar."""
|
||||||
|
with tqdm(total=round(total_duration, 2)) as bar:
|
||||||
|
def handler(key, value):
|
||||||
|
if key == 'out_time_ms':
|
||||||
|
time = round(float(value) / 1000000., 2)
|
||||||
|
bar.update(time - bar.n)
|
||||||
|
elif key == 'progress' and value == 'end':
|
||||||
|
bar.update(bar.total - bar.n)
|
||||||
|
with _watch_progress(handler) as socket_filename:
|
||||||
|
yield socket_filename
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
args = parser.parse_args()
|
||||||
|
total_duration = float(ffmpeg.probe(args.in_filename)['format']['duration'])
|
||||||
|
|
||||||
|
with show_progress(total_duration) as socket_filename:
|
||||||
|
# See https://ffmpeg.org/ffmpeg-filters.html#Examples-44
|
||||||
|
sepia_values = [.393, .769, .189, 0, .349, .686, .168, 0, .272, .534, .131]
|
||||||
|
try:
|
||||||
|
(ffmpeg
|
||||||
|
.input(args.in_filename)
|
||||||
|
.colorchannelmixer(*sepia_values)
|
||||||
|
.output(args.out_filename)
|
||||||
|
.global_args('-progress', 'unix://{}'.format(socket_filename))
|
||||||
|
.overwrite_output()
|
||||||
|
.run(capture_stdout=True, capture_stderr=True)
|
||||||
|
)
|
||||||
|
except ffmpeg.Error as e:
|
||||||
|
print(e.stderr, file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
@ -1,13 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals, print_function
|
||||||
|
|
||||||
from google.cloud import speech
|
from google.cloud import speech
|
||||||
from google.cloud.speech import enums
|
from google.cloud.speech import enums
|
||||||
from google.cloud.speech import types
|
from google.cloud.speech import types
|
||||||
import argparse
|
import argparse
|
||||||
import ffmpeg
|
import ffmpeg
|
||||||
import logging
|
import logging
|
||||||
import subprocess
|
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
|
||||||
@ -21,21 +19,17 @@ parser.add_argument('in_filename', help='Input filename (`-` for stdin)')
|
|||||||
|
|
||||||
|
|
||||||
def decode_audio(in_filename, **input_kwargs):
|
def decode_audio(in_filename, **input_kwargs):
|
||||||
p = subprocess.Popen(
|
try:
|
||||||
(ffmpeg
|
out, err = (ffmpeg
|
||||||
.input(in_filename, **input_kwargs)
|
.input(in_filename, **input_kwargs)
|
||||||
.output('-', format='s16le', acodec='pcm_s16le', ac=1, ar='16k')
|
.output('-', format='s16le', acodec='pcm_s16le', ac=1, ar='16k')
|
||||||
.overwrite_output()
|
.overwrite_output()
|
||||||
.compile()
|
.run(capture_stdout=True, capture_stderr=True)
|
||||||
),
|
)
|
||||||
stdout=subprocess.PIPE,
|
except ffmpeg.Error as e:
|
||||||
stderr=subprocess.PIPE
|
print(e.stderr, file=sys.stderr)
|
||||||
)
|
|
||||||
out = p.communicate()
|
|
||||||
if p.returncode != 0:
|
|
||||||
sys.stderr.write(out[1])
|
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
return out[0]
|
return out
|
||||||
|
|
||||||
|
|
||||||
def get_transcripts(audio_data):
|
def get_transcripts(audio_data):
|
||||||
|
@ -11,15 +11,21 @@ parser.add_argument('in_filename', help='Input filename')
|
|||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
probe = ffmpeg.probe(args.in_filename)
|
|
||||||
video_info = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
|
try:
|
||||||
if video_info is None:
|
probe = ffmpeg.probe(args.in_filename)
|
||||||
|
except ffmpeg.Error as e:
|
||||||
|
print(e.stderr, file=sys.stderr)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
|
||||||
|
if video_stream is None:
|
||||||
print('No video stream found', file=sys.stderr)
|
print('No video stream found', file=sys.stderr)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
width = int(video_info['width'])
|
width = int(video_stream['width'])
|
||||||
height = int(video_info['height'])
|
height = int(video_stream['height'])
|
||||||
num_frames = int(video_info['nb_frames'])
|
num_frames = int(video_stream['nb_frames'])
|
||||||
print('width: {}'.format(width))
|
print('width: {}'.format(width))
|
||||||
print('height: {}'.format(height))
|
print('height: {}'.format(height))
|
||||||
print('num_frames: {}'.format(num_frames))
|
print('num_frames: {}'.format(num_frames))
|
||||||
|
Loading…
x
Reference in New Issue
Block a user