我尝试开发低延迟的音频流。 在服务器端具有龙卷风的Python,在客户端具有HTML5或/和JavaScript。
从我实际的python代码中提取的内容,它模拟了wav
文件的发送:
Wavframes = []
flagWavstart = False
class loadWavdata(Thread):
def __init__(self):
global flagWavstart
Thread.__init__(self)
self.streamRX = p.open(format=pyaudio.paInt16, channels=1,
rate=44100, input=True,input_device_index=1,
frames_per_buffer=512)
flagWavstart = True
def run(self):
global Wavframes, flagWavstart
while flagWavstart:
data = self.streamRX.read(512, exception_on_overflow = False)
Wavframes.append(data)
self.streamRX.close()
class AudioHandler(tornado.web.RequestHandler):
def genHeader(self,sampleRate, bitsPerSample, channels):
datasize = 2000*10**6
o = bytes("RIFF",'ascii') # (4byte) Marks file as RIFF
o += (datasize + 36).to_bytes(4,'little') # (4byte) File size in bytes excluding this and RIFF marker
o += bytes("WAVE",'ascii') # (4byte) File type
o += bytes("fmt ",'ascii') # (4byte) Format Chunk Marker
o += (16).to_bytes(4,'little') # (4byte) Length of above format data
o += (1).to_bytes(2,'little') # (2byte) Format type (1 - PCM)
o += (channels).to_bytes(2,'little') # (2byte)
o += (sampleRate).to_bytes(4,'little') # (4byte)
o += (sampleRate * channels * bitsPerSample // 8).to_bytes(4,'little') # (4byte)
o += (channels * bitsPerSample // 8).to_bytes(2,'little') # (2byte)
o += (bitsPerSample).to_bytes(2,'little') # (2byte)
o += bytes("data",'ascii') # (4byte) Data Chunk Marker
o += (datasize).to_bytes(4,'little') # (4byte) Data size in bytes
return o
def on_connection_close(self):
global Wavframes, flagWavstart
Wavframes = []
flagWavstart = False
@gen.coroutine
def get(self):
global Wavframes, flagWavstart
try:
threadloadWavdata = loadWavdata()
threadloadWavdata.start()
except:
pass
print('new connection on RX socket')
wav_header = self.genHeader(44100, 16, 1)
print("recording...")
while len(Wavframes)<5:
time.sleep(0.005)
self.write(wav_header + Wavframes[0])
del Wavframes[0]
while True:
while len(Wavframes)<5:
time.sleep(0.005)
data = Wavframes[0]
del Wavframes[0]
self.write(data)
self.flush(callback=(yield gen.Callback('flush')))
yield gen.Wait('flush')
在客户端:
var audioRX=document.createElement('audio');
audioRX.preload="none";
audioRX.src="/audio?"+(Math.floor(Math.random() * Math.floor(10000)));
audioRX.play();
我的问题是音频元素似乎有1s
的缓冲区。
我正在搜索以减少此缓冲区...很不幸,音频元素似乎不允许这样做。
所以我搜索是否可以在阵列中对这些音频块进行充电并直接播放它们,而无需通过此缓冲区...
你有个主意吗?
谢谢!