将音频从pyaudio与Flask流传输到HTML5

par*_*erd 6 python audio html5 flask pyaudio

我想通过Flask将麦克风的音频(通过pyaudio记录)通过流传输到任何连接的客户端。

这是音频的来源:

    def getSound(self):
        # Current chunk of audio data
        data = self.stream.read(self.CHUNK)
        self.frames.append(data)
        wave = self.save(list(self.frames))

        return data
Run Code Online (Sandbox Code Playgroud)

这是我的烧瓶代码:

@app.route('/audiofeed')
def audiofeed():
    def gen(microphone):
        while True:
            sound = microphone.getSound()
            #with open('tmp.wav', 'rb') as myfile:
            #   yield myfile.read()

            yield sound

    return Response(stream_with_context(gen(Microphone())))
Run Code Online (Sandbox Code Playgroud)

这是客户:

    <audio controls>
        <source src="{{ url_for('audiofeed') }}" type="audio/x-wav;codec=pcm">
        Your browser does not support the audio element.
    </audio>
Run Code Online (Sandbox Code Playgroud)

有时确实可以,但是大多数时候我会收到“ [Errno 32]管道坏了

当用open(“ tmp.wav”)-part取消注释时(self.save()可以选择所有先前的帧并将它们保存在tmp.wav中),我有点听不到声音,但是所有声音都来自扬声器是“咔嗒”声。

我愿意接受任何建议。如何将我的麦克风输入实时流式传输(无需预先录制!)到网络浏览器?

谢谢!

小智 2

这个问题很久以前就被问到了,但由于我花了一整天的时间来弄清楚如何实现它,所以我想给出答案。也许这会对某人有帮助。

“[Errno 32] Broken pipeline”错误来自客户端无法播放音频并关闭此流的事实。由于数据流中缺少标头,无法播放音频。您可以使用此处genHeader(sampleRate, bitsPerSample, channels, samples)代码中的函数轻松创建标头。该标头必须至少附加到发送数据的第一块 ( )。请注意,只有在客户端达到您必须在标头中指定的下载文件大小之前,才能播放音频。因此,解决方法是在标头中设置一些大文件大小,例如 2Gb。 chunck=header+data