发送和保存 MediaRecorder 数据会产生极其错误的结果?

2024-01-01

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

I am running into an issue where the result is coming out like this enter image description here

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

我已经在 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 请求来解决这个问题,但我知道 Websockets 在 TCP 上运行,因此数据包必须按顺序发送,并且我每 2 秒发送一次,所以在下一个请求到来之前它应该有时间发送数据并保存到磁盘(但不确定,只是我的猜测)

我的实现有问题吗?

Edit:由 O. Jones 解决。我认为有一个更大的时间更好,但似乎我需要一个非常小的时间。太感谢了!


每一次MediaRecorder打电话给你的ondataavailablehandler 它给你一个 Blobevent.data。该 Blob 包含所有累积的编码数据。以每秒 2.6 兆位的组合数据速率计算,三秒几乎相当于 1 兆字节。对于 POST 请求来说这是一个非常大的有效负载,并且对于appendFile.

Call ondataavailable不经常。使用.start(20)代替.start(3000)。您仍然在移动大量数据,但是将其分成较小的块可以降低出现混乱或丢失一些数据的可能性。

并且,考虑使用 Nodejs 流来写入文件。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

发送和保存 MediaRecorder 数据会产生极其错误的结果? 的相关文章

随机推荐