forked from egao1980/PyAV
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathaudio.py
More file actions
101 lines (82 loc) · 3.09 KB
/
Copy pathaudio.py
File metadata and controls
101 lines (82 loc) · 3.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
from __future__ import print_function
import array
import argparse
import sys
import pprint
import subprocess
from PIL import Image
import av
def print_data(frame):
for i, plane in enumerate(frame.planes or ()):
data = plane.to_bytes()
print('\tPLANE %d, %d bytes' % (i, len(data)))
data = data.encode('hex')
for i in xrange(0, len(data), 128):
print('\t\t\t%s' % data[i:i + 128])
arg_parser = argparse.ArgumentParser()
arg_parser.add_argument('path')
arg_parser.add_argument('-p', '--play', action='store_true')
arg_parser.add_argument('-d', '--data', action='store_true')
arg_parser.add_argument('-f', '--format')
arg_parser.add_argument('-l', '--layout')
arg_parser.add_argument('-r', '--rate', type=int)
arg_parser.add_argument('-s', '--size', type=int, default=1024)
arg_parser.add_argument('-c', '--count', type=int, default=5)
args = arg_parser.parse_args()
ffplay = None
container = av.open(args.path)
stream = next(s for s in container.streams if s.type == 'audio')
fifo = av.AudioFifo() if args.size else None
resampler = av.AudioResampler(
format=av.AudioFormat(args.format or stream.format.name).packed if args.format else None,
layout=int(args.layout) if args.layout and args.layout.isdigit() else args.layout,
rate=args.rate,
) if (args.format or args.layout or args.rate) else None
read_count = 0
fifo_count = 0
sample_count = 0
for i, packet in enumerate(container.demux(stream)):
for frame in packet.decode():
read_count += 1
print('>>>> %04d' % read_count, frame)
if args.data:
print_data(frame)
frames = [frame]
if resampler:
for i, frame in enumerate(frames):
frame = resampler.resample(frame)
print('RESAMPLED', frame)
if args.data:
print_data(frame)
frames[i] = frame
if fifo:
to_process = frames
frames = []
for frame in to_process:
fifo.write(frame)
while frame:
frame = fifo.read(args.size)
if frame:
fifo_count += 1
print('|||| %04d' % fifo_count, frame)
if args.data:
print_data(frame)
frames.append(frame)
if frames and args.play:
if not ffplay:
cmd = ['ffplay',
'-f', frames[0].format.packed.container_name,
'-ar', str(args.rate or stream.rate),
'-ac', str(len(resampler.layout.channels if resampler else stream.layout.channels)),
'-vn', '-',
]
print('PLAY', ' '.join(cmd))
ffplay = subprocess.Popen(cmd, stdin=subprocess.PIPE)
try:
for frame in frames:
ffplay.stdin.write(frame.planes[0].to_bytes())
except IOError as e:
print(e)
exit()
if args.count and read_count >= args.count:
exit()