发送和保存 MediaRecorder 数据会产生极其不稳定的结果?

Sending & Saving MediaRecorder Data Producing Extremely Glitchy Results?

我有一个脚本,可以在 MediaStream 运行ning 时通过 Websockets 将 MediaRecorder 数据发送到后端。后端然后将此数据保存到要重播的文件中。

我正在 运行 遇到这样的问题

该视频非常有问题(有时它有点流畅,但大多数情况下会出现问题),我不知道为什么。

我已经在 Chrome(最新版本)和 Microsoft Edge 上对此进行了测试,两者都产生了相同的故障结果。我注意到虽然 Firefox 似乎更流畅,但我在 Firefox 上做了有限的测试。

我的前端代码:

const socket = io('/')

document.querySelector("#startReccy").addEventListener('click', async () => {

    socket.emit('recID', ROOM_ID)


    let screenStream = await navigator.mediaDevices.getDisplayMedia({
        video: {
            cursor: "never"
        },
        audio: true
    })

    let vidId = document.querySelector("#myLiveVid")
    vidId.srcObject = screenStream;

    let videoMediaRecObj = new MediaRecorder(screenStream, {
        audioBitsPerSecond: 128000,
        videoBitsPerSecond: 2500000
      });

    //Send to server
    videoMediaRecObj.addEventListener('dataavailable', (e) => {
        //console.log(e.data)
        //socket.emit('writeInfoData', ROOM_ID, e.data)
        e.data.arrayBuffer().then ( buf => {
            socket.emit('writeInfoData', ROOM_ID, buf) 
        })
    })
    videoMediaRecObj.start(3000)

    //When we stop
    screenStream.addEventListener('ended', () => {
        videoMediaRecObj.stop();
        //screenStream.getTracks().forEach(track => track.stop());
      })

    

})

后端

const express = require('express')
const app = express()
server = require('http').Server(app)
const io = require('socket.io')(server)


var fs = require('fs');


const { v4: uuidV4 } = require('uuid')

app.set('view engine', 'ejs')
app.use(express.static("public"))

app.get("/", (req, res) => {
    res.redirect(`${uuidV4()}`)
})

app.get('/:room', (req, res) => {
    res.render('room', {roomId: req.params.room})
})

io.on('connection', socket => {
    socket.on('screen-rec', (roomId)=> {
      /* Seems to get room ID with no problem*/
        console.log(`${roomId}`)
        /* We join a room*/
        socket.join(roomId)

        socket.roomId = path.join(__dirname, 'media', roomId + '.webm')

        socket.emit('startRecording')
    })

    /* Write media file to disk*/
    socket.on('writeInfoData', (roomId, data) => {
        /* trying to read the data */
        //console.log(data) - This works

        fs.appendFile(`file-${roomId}.webm`, data, function (err) {
            if (err) {
                throw err;
            }
            console.log(`${Date().toLocaleString()} - ${roomId} - Saved!`);
          }); 
    })
})

server.listen(3000, () => {
    console.log("Listening")
})

我认为问题是因为它们可能被乱序接收,我想我可以通过发出连续的 POST 请求来解决,但我知道 TCP 上的 Websockets 运行 所以数据包有按顺序来,我每 2 秒发送一次,所以它应该有时间发送数据并在下一个请求进入之前保存到磁盘(虽然不确定,只是我的猜测)

我的实现有问题吗?

编辑: 由 O. Jones 解决。我认为时间越长越好,但似乎我需要的时间真的很短。非常感谢!

每次 MediaRecorder 调用您的 ondataavailable 处理程序时,它都会在 event.data 中为您提供一个 Blob。该 Blob 包含所有累积的编码数据。以每秒 2.6 兆比特的组合数据速率计算,其中的三秒几乎是一兆字节。对于 POST 请求和 appendFile.

来说,这是一个非常大的有效负载

减少 ondataavailable 的调用频率。使用 .start(20) 而不是 .start(3000)。您仍在移动大量数据,但以较小的块移动它们可以降低出现问题或丢失一些数据的可能性。

并且,考虑使用 nodejs 流来编写文件。