-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathpyaudio_player.py
59 lines (47 loc) · 1.5 KB
/
pyaudio_player.py
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
from time import sleep
import ffmpegio
import pyaudio
from contextlib import contextmanager
from testfile_generator import testfiles
@contextmanager
def pyaudio_stream(
rate, channels, width=None, unsigned=False, format=None, *args, **kwargs
):
p = pyaudio.PyAudio()
if format is None:
if width is None:
raise ValueError("Either width or format must be specified.")
format = p.get_format_from_width(width, unsigned)
try:
stream = p.open(rate, channels, format, *args, **kwargs)
try:
stream.start_stream()
yield stream
stream.stop_stream()
finally:
stream.close()
finally:
p.terminate()
ar = 44100 # playback sampling rate
ac = 2 # number of channels
width = 2 # signed 2-byte integer format
sample_fmt = "s16"
with testfiles(1) as files:
file = files[0]
# open ffmpegio's stream-reader
with ffmpegio.open(file, "ra", sample_fmt=sample_fmt, ac=ac, ar=ar) as f:
# define callback (2)
def callback(_, nblk, *__):
# read nblk samples from the ffmpeg and pass it onto pyaudio
data = f.read(nblk)["buffer"]
return (data, pyaudio.paContinue)
with pyaudio_stream(
rate=ar,
channels=ac,
width=width,
output=True,
stream_callback=callback,
) as stream:
# wait for stream to finish
while stream.is_active():
sleep(0.1)