如何从客户端录制麦克风然后发送到服务器

Posted

技术标签:

【中文标题】如何从客户端录制麦克风然后发送到服务器【英文标题】:How to record mic from client then send to server 【发布时间】:2021-04-23 12:07:59 【问题描述】:

我想录制来自客户端的麦克风输入,然后当他停止时,将数据发送到服务器,然后将录制的音频输出到特定文件夹。

到目前为止,我已经在我关注的客户端上录制了 this

mediaRecorder.onstop = function(e) 
   console.log("recorder stopped");

   const blob = new Blob(chunks,  'type' : 'audio/ogg; codecs=opus' );

   chunks = [];

   const formData = new FormData();
   formData.append('audio-file', blob);

   return fetch('http://localhost:3000/notes', 
      method: 'POST',
      body: formData
   );


客户端上的console.log(blob)返回一个对象

Blob  size: 35412, type: "audio/ogg; codecs=opus" 

在服务器端我使用 Node.js

app.post("/notes",function(req,res)
  console.log(req);
);

服务器收到formData但body为空

我也尝试过 XMLHttpRequest,结果相同。

【问题讨论】:

【参考方案1】:

我以前玩过这种类型的项目。我创建了一个简单的表单,允许您从麦克风录制,然后上传到服务器。

声音文件将保存在 ./sound_files

只需像这样运行节点服务器

节点服务器.js

然后去localhost:3000查看页面。

节点代码(server.js)

const express = require('express');
const multer = require('multer');
    
const storage = multer.diskStorage(
    
        destination: './sound_files/',
        filename: function (req, file, cb ) 
            cb( null, file.originalname);
        
    
);

const upload = multer(  storage: storage  );

const app = express();
const port = 3000;

app.use(express.static('./'));

app.post("/notes", upload.single("audio_data"), function(req,res)
    res.status(200).send("ok");
);

app.listen(port, () => 
    console.log(`Express server listening on port: $port...`);
);

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Speech to text test</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <link rel="stylesheet" type="text/css" href="https://bootswatch.com/4/cerulean/bootstrap.min.css">
</head>
<body style="padding:50px;">
    <h1>Speech to text test</h1>
    <div id="controls">
    <button id="recordButton">Record</button>
    <button id="transcribeButton" disabled>Stop and upload to server</button>
    </div>
    <div id="output"></div>
    <script src="https://cdn.rawgit.com/mattdiamond/Recorderjs/08e7abd9/dist/recorder.js"></script>
    <script>
                
        let rec = null;
        let audiostream = null;

        const recordButton = document.getElementById("recordButton");
        const transcribeButton = document.getElementById("transcribeButton");

        recordButton.addEventListener("click", startRecording);
        transcribeButton.addEventListener("click", transcribeText);

        function startRecording() 

            let constraints =  audio: true, video:false 

            recordButton.disabled = true;
            transcribeButton.disabled = false;

            navigator.mediaDevices.getUserMedia(constraints).then(function(stream) 
                const audioContext = new window.AudioContext();
                audioStream = stream;
                const input = audioContext.createMediaStreamSource(stream);
                rec = new Recorder(input,  numChannels: 1 )
                rec.record()
                document.getElementById("output").innerHTML = "Recording started..."
            ).catch(function(err) 
                recordButton.disabled = false;
                transcribeButton.disabled = true;
            );
        

        function transcribeText() 
            document.getElementById("output").innerHTML = "Converting audio to text..."
            transcribeButton.disabled = true;
            recordButton.disabled = false;
            rec.stop();
            audioStream.getAudioTracks()[0].stop();
            rec.exportWAV(uploadSoundData);
        

        function uploadSoundData(blob) 
            const filename = "sound-file-" + new Date().getTime() + ".wav";
            const formData = new FormData();
            formData.append("audio_data", blob, filename);
            
            fetch('http://localhost:3000/notes', 
                method: 'POST',
                body: formData
            ).then(async result =>  
                document.getElementById("output").innerHTML = await result.text();
            ).catch(error =>  
                document.getElementById("output").innerHTML = "An error occurred: " + error;
            )
        

    </script>
</body>
</html>

【讨论】:

以上是关于如何从客户端录制麦克风然后发送到服务器的主要内容,如果未能解决你的问题,请参考以下文章

使用 POST 表单发送 Blob 对象

如何将音频 blob 从 javascript 发送到 java spring 服务器?

将连续字节[]数据发送到Java中的DatagramSocket,DatagramPacket

FFmpeg 录制桌面麦克风摄像头

FFmpeg 录制桌面麦克风摄像头

从 MIC 录制并流式传输到 TCP 服务器; MediaRecorder:启动失败:-38