10000 Update examples · monir-dev/ffmpeg-python@de12467 · GitHub
[go: up one dir, main page]

Skip to content

Commit de12467

Browse files
committed
Update examples
1 parent 6364513 commit de12467

File tree

5 files changed

+155
-21
lines changed

5 files changed

+155
-21
lines changed

examples/get_video_thumbnail.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,12 @@ def generate_thumbnail(in_filename, out_filename, time, width):
2222
.input(in_filename, ss=time)
2323
.filter_('scale', width, -1)
2424
.output(out_filename, vframes=1)
25-
.run(capture_stdout=True, capture_stderr=True, overwrite_output=True)
25+
.overwrite_output()
26+
.run(capture_stdout=True, capture_stderr=True)
2627
)
2728
except ffmpeg.Error as e:
2829
print(e.stderr.decode(), file=sys.stderr)
30+
sys.exit(1)
2931

3032

3133
if __name__ == '__main__':

examples/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
ffmpeg-python
2+
gevent
23
google-cloud-speech
4+
tqdm

examples/show_progress.py

Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
#!/usr/bin/env python
2+
from __future__ import unicode_literals, print_function
3+
from tqdm import tqdm
4+
import argparse
5+
import contextlib
6+
import ffmpeg
7+
import gevent
8+
import gevent.monkey; gevent.monkey.patch_all(thread=False)
9+
import os
10+
import shutil
11+
import socket
12+
import sys
13+
import tempfile
14+
import textwrap
15+
16+
17+
parser = argparse.ArgumentParser(description=textwrap.dedent('''\
18+
Process video and report and show progress bar.
19+
20+
This is an example of using the ffmpeg `-progress` option with a
21+
unix-domain socket to report progress in the form of a progress
22+
bar.
23+
24+
The video processing simply consists of converting the video to
25+
sepia colors, but the same pattern can be applied to other use
26+
cases.
27+
'''))
28+
29+
parser.add_argument('in_filename', help='Input filename')
30+
parser.add_argument('out_filename', help='Output filename')
31+
32+
33+
@contextlib.contextmanager
34+
def _tmpdir_scope():
35+
tmpdir = tempfile.mkdtemp()
36+
try:
37+
yield tmpdir
38+
finally:
39+
shutil.rmtree(tmpdir)
40+
41+
42+
def _do_watch_progress(filename, sock, handler):
43+
"""Function to run in a separate gevent greenlet to read progress
44+
events from a unix-domain socket."""
45+
connection, client_address = sock.accept()
46+
data = b''
47+
try:
48+
while True:
49+
more_data = connection.recv(16)
50+
if not more_data:
51+
break
52+
data += more_data
53+
lines = data.split(b'\n')
54+
for line in lines[:-1]:
55+
line = line.decode()
56+
parts = line.split('=')
57+
key = parts[0] if len(parts) > 0 else None
58+
value = parts[1] if len(parts) > 1 else None
59+
handler(key, value)
60+
data = lines[-1]
61+
finally:
62+
connection.close()
63+
64+
65+
@contextlib.contextmanager
66+
def _watch_progress(handler):
67+
"""Context manager for creating a unix-domain socket and listen for
68+
ffmpeg progress events.
69+
70+
The socket filename is yielded from the context manager and the
71+
socket is closed when the context manager is exited.
72+
73+
Args:
74+
handler: a function to be called when progress events are
75+
received; receives a ``key`` argument and ``value``
76+
argument. (The example ``show_progress`` below uses tqdm)
77+
78+
Yields:
79+
socket_filename: the name of the socket file.
80+
"""
81+
with _tmpdir_scope() as tmpdir:
82+
socket_filename = os.path.join(tmpdir, 'sock')
83+
sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
84+
with contextlib.closing(sock):
85+
sock.bind(socket_filename)
86+
sock.listen(1)
87+
child = gevent.spawn(_do_watch_progress, socket_filename, sock, handler)
88+
try:
89+
yield socket_filename
90+
except:
91+
gevent.kill(child)
92+
raise
93+
94+
95+
96+
@contextlib.contextmanager
97+
def show_progress(total_duration):
98+
"""Create a unix-domain socket to watch progress and render tqdm
99+
progress bar."""
100+
with tqdm(total=round(total_duration, 2)) as bar:
101+
def handler(key, value):
102+
if key == 'out_time_ms':
103+
time = round(float(value) / 1000000., 2)
104+
bar.update(time - bar.n)
105+
elif key == 'progress' and value == 'end':
106+
bar.update(bar.total - bar.n)
107+
with _watch_progress(handler) as socket_filename:
108+
yield socket_filename
109+
110+
111+
if __name__ == '__main__':
112+
args = parser.parse_args()
113+
total_duration = float(ffmpeg.probe(args.in_filename)['format']['duration'])
114+
115+
with show_progress(total_duration) as socket_filename:
116+
# See https://ffmpeg.org/ffmpeg-filters.html#Examples-44
117+
sepia_values = [.393, .769, .189, 0, .349, .686, .168, 0, .272, .534, .131]
118+
try:
119+
(ffmpeg
120+
.input(args.in_filename)
121+
.colorchannelmixer(*sepia_values)
122+
.output(args.out_filename)
123+
.global_args('-progress', 'unix://{}'.format(socket_filename))
124+
.overwrite_output()
125+
.run(capture_stdout=True, capture_stderr=True)
126+
)
127+
except ffmpeg.Error as e:
128+
print(e.stderr, file=sys.stderr)
129+
sys.exit(1)
130+

examples/transcribe.py

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,11 @@
11
#!/usr/bin/env python
2-
from __future__ import unicode_literals
3-
2+
from __future__ import unicode_literals, print_function
43
from google.cloud import speech
54
from google.cloud.speech import enums
65
from google.cloud.speech import types
76
import argparse
87
import ffmpeg
98
import logging
10-
import subprocess
119
import sys
1210

1311

@@ -21,21 +19,17 @@
2119

2220

2321
def decode_audio(in_filename, **input_kwargs):
24-
p = subprocess.Popen(
25-
(ffmpeg
22+
try:
23+
out, err = (ffmpeg
2624
.input(in_filename, **input_kwargs)
2725
.output('-', format='s16le', acodec='pcm_s16le', ac=1, ar='16k')
2826
.overwrite_output()
29-
.compile()
30-
),
31-
stdout=subprocess.PIPE,
32-
stderr=subprocess.PIPE
33-
)
34-
out = p.communicate()
35-
if p.returncode != 0:
36-
sys.stderr.write(out[1])
27+
.run(capture_stdout=True, capture_stderr=True)
28+
)
29+
except ffmpeg.Error as e:
30+
print(e.stderr, file=sys.stderr)
3731
sys.exit(1)
38-
return out[0]
32+
return out
3933

4034

4135
def get_transcripts(audio_data):

examples/video_info.py

Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@
1111

1212
if __name__ == '__main__':
1313
args = parser.parse_args()
14-
probe = ffmpeg.probe(args.in_filename)
15-
video_info = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
16-
if video_info is None:
14+
15+
try:
16+
probe = ffmpeg.probe(args.in_filename)
17+
except ffmpeg.Error as e:
18+
print(e.stderr, file=sys.stderr)
19+
sys.exit(1)
20+
21+
video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)
22+
if video_stream is None:
1723
print('No video stream found', file=sys.stderr)
1824
sys.exit(1)
1925

20-
width = int(video_info['width'])
21-
height = int(video_info['height'])
22-
num_frames = int(video_info['nb_frames'])
26+
width = int(video_stream['width'])
27+
height = int(video_stream['height'])
28+
num_frames = int(video_stream['nb_frames'])
2329
print('width: {}'.format(width))
2430
print('height: {}'.format(height))
2531
print('num_frames: {}'.format(num_frames))

0 commit comments

Comments
 (0)
0