web-dev-qa-db-ja.com

Flaskを使用してpyaudioからHTML5にオーディオをストリーミングする

マイクのオーディオ(pyaudioを介して録音されている)をFlaskを介して、接続しているすべてのクライアントにストリーミングしたい。

これがオーディオの出所です。

    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

これが私のフラスココードです:

@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())))

そしてこれはクライアントです:

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

時々動作しますが、ほとんどの場合、「[Errno 32]パイプが壊れています "

Open( "tmp.wav")-part(self.save()はオプションで前のすべてのフレームを取得し、それらをtmp.wavに保存します)でコメントを外すと、ストリームを取得しますが、スピーカーからすべてが出力されます「カチッ」という音です。

私はどんな提案も受け付けています。マイクの入力をウェブブラウザにライブストリーミング(事前録音なし!)するにはどうすればよいですか?

ありがとう!

6
paranerd

これを試してみてください。シェルコマンド「cat」は完全に機能しています。FLASKを使用してコードiamを参照してください。

import subprocess
import os
import inspect
from flask import Flask
from flask import Response

@app.route('/playaudio')
    def playaudio():
        sendFileName=""
        def generate():

            #  get_list_all_files_name this function gives all internal files inside the folder

   filesAudios=get_list_all_files_name(currentDir+"/streamingAudios/1")

            # audioPath is audio file path in system 
            for audioPath in filesAudios:
                data=subprocess.check_output(['cat',audioPath])
                yield data
        return Response(generate(), mimetype='audio/mp3')
2
Shantanu Sharma

この質問はずっと前に聞かれましたが、私は一日中同じことを実装する方法を考え出したので、答えたいと思います。多分それは誰かのために役立つでしょう。

"[Errno 32]パイプの破損"エラーは、クライアントがオーディオを再生できず、このストリームを閉じるという事実に起因します。データストリームにヘッダーがないため、オーディオを再生できません。コードからgenHeader(sampleRate, bitsPerSample, channels, samples)関数を使用してヘッダーを簡単に作成できます ここ 。このヘッダーは、少なくとも送信データの最初のチャンクに添付する必要があります(chunck=header+data)。クライアントがダウンロードで指定する必要のあるファイルサイズに達するまで、オーディオを再生できることに注意してください[〜#〜]のみ[〜#〜]ヘッダー。したがって、回避策は、ヘッダーにいくつかの大きなファイルサイズを設定することです。 2Gb。

2

ヘッダー関数のdatasize = len(samples) * channels * bitsPerSampleの代わりにdatasize = 2000*10**6

def gen_audio():

    CHUNK = 512
    sampleRate = 44100
    bitsPerSample = 16
    channels = 2
    wav_header = genHeader(sampleRate, bitsPerSample, channels)

    audio = AudioRead()
    data = audio.get_audio_chunck()
    chunck = wav_header + data
    while True:
        yield (chunck)
        data = audio.get_audio_chunck()
        chunck = data
2

たくさんの研究といじくり回しの後、私はついに解決策を見つけました。

基本的には、FlaskのSocketIO実装を使用してWebSocketを介してpyaudio.paFloat32オーディオデータを提供し、HTML5のAudioContextを使用してJavaScriptでデータを受信/再生することになりました。

これにはかなりのコードが必要なので、すべてをここに投稿するのは良い考えではないと思います。代わりに、私が使用しているプロジェクトを自由にチェックしてください: simpleCam

関連するコードは次のとおりです。-noise_detector.py(記録)-server.py(WebSocket転送)-static/js/player.js(受信/再生)

皆様のご支援ありがとうございました!

1
paranerd