音频流、NextJS、Flask Socket.IO

Audio streaming, NextJS, Flask, Socket.IO

提问人:Anıl Eren Göçer 提问时间:11/2/2023 更新时间:11/2/2023 访问量:51

问:

我正在 nextjs 应用程序中从麦克风捕获语音,并在 socket.io 上以 1 秒长的块发送它们。在后端服务中,我将它们保存为 wav 文件以供测试。虽然,我可以成功播放第一个块,但其余块不知何故损坏了,我无法播放它。

这是我的前端和后端代码。

'use client';

import { getServiceURL } from "@/services/getServiceURL";
import socketIOClient from 'socket.io-client';
import { useEffect, useState } from 'react';

export default function Meeting() {
    const [recording, setRecording] = useState(false);
    var transcriptionSocket;
    // var diarizationSocket;
    var mediaRecorder;

    useEffect(() => {
        transcriptionSocket = socketIOClient(getServiceURL("transcriptionService"));
        // diarizationSocket = socketIOClient(getServiceURL("diarizationService"));
    }, []);

    const startRecording = () => {
        if (!recording) {
            navigator.mediaDevices
                .getUserMedia({ audio: true })
                .then((stream) => {
                    mediaRecorder = new MediaRecorder(stream);
                    mediaRecorder.ondataavailable = (e) => {
                        if (e.data.size > 0) {
                            transcriptionSocket.emit("audioChunk", e.data);
                            // diarizationSocket.emit("audioChunk", e.data);
                        }
                    };
                    mediaRecorder.start(1000); // 1-second chunks
                })
                .catch((error) => {
                    console.error('Error accessing microphone:', error);
                });
            setRecording(true);
        }
    };

    const stopRecording = () => {
        if (recording) {
            mediaRecorder.stop();
            setRecording(false);
        }
    };

    return (
        <div>
            <h1>PenAI Meeting Page</h1>
            <button onClick={recording ? stopRecording : startRecording}>
                {recording ? 'Stop Recording' : 'Start Recording'}
            </button>
        </div>
    );
}
from flask import Flask, jsonify
from flask_socketio import SocketIO, emit
import os

app = Flask(__name__)
socketio = SocketIO(app, cors_allowed_origins="*")

# Directory to store audio chunks
audio_chunk_dir = "./penai-backend/transcription-service/audio_chunks"

if not os.path.exists(audio_chunk_dir):
    os.makedirs(audio_chunk_dir)

# Counter to keep track of the incoming order index
chunk_counter = 0

@app.route("/")
def index():
    return jsonify({"status": "Transcription service is up and running!"})

@socketio.on("audioChunk")
def onAudioChunk(audio_chunk):
    global chunk_counter
    print("Server received an audio chunk!")

    # Generate a filename based on the incoming order index
    file_name = f"chunk_{chunk_counter}.wav"
    file_path = os.path.join(audio_chunk_dir, file_name)

    with open(file_path, "wb") as audio_file:
        audio_file.write(audio_chunk)
        print("chunk saved")

    chunk_counter += 1

@socketio.on('connect')
def onConnect(auth):
    print("A socket-io client is connected!")

@socketio.on('disconnect')
def onDisconnect():
    print('A socket-io client is disconnected!')

if __name__ == '__main__':
    app.run(debug=True, port=8001)

我怀疑第一个之后的块在等待前一个保存时已损坏。然后,我将块大小增加到 5 秒,但这无济于事。我不知道问题的确切原因。所以,我需要你的帮助。

有什么想法可以解决这个问题吗?

提前致谢。

ReactJS Flask socket.io 音频流

评论


答:

0赞 ArShAm 11/2/2023 #1

在前端,您需要每秒请求一次数据,以便使用 SetInterval 每 1000 毫秒调用一次函数 (requestData)。

setInterval(() => {
  mediaRecorder.requestData()
}, 1000)