发送与发送保存MediaRecorder数据会产生极其刺眼的结果吗? [英] Sending & Saving MediaRecorder Data Producing Extremely Glitchy Results?

查看:35
本文介绍了发送与发送保存MediaRecorder数据会产生极其刺眼的结果吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a script that sends MediaRecorder data over Websockets to the backend when the MediaStream is running. The backend then saves this data to a file to be replayed.

我遇到了这样的问题:结果如下所示:

I am running into an issue where the result is coming out like this

该视频非常毛刺(有时会出现一些平滑现象,但大多数情况下会出现毛刺),我不知道为什么.

The video is extremely glitchy (sometimes it comes out somewhat smooth but mostly it comes out glitchy) and I do not know why.

我已经在Chrome(最新版本)和Microsoft Edge上进行了测试,并且都产生了相同的故障结果.我确实注意到Firefox似乎更流畅,但是我在Firefox上进行了有限的测试.

I have tested this on Chrome (latest version) and Microsoft Edge and both produce the same glitchy results. I did notice though that Firefox seems to be smoother but i did limited tests on 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请求来解决,但是我知道Websocket在TCP上运行,因此数据包必须按顺序排列,我每次都将其发送出去2秒,因此应该有时间在下一个请求到来之前发送数据并将其保存到磁盘(虽然不确定,只是我的猜测)

I am thinking the issue is because they may be received out of order, which I guess i can solve by making continuous POST requests but I know Websockets run on TCP so the packets have to come in order and I am sending it every 2 seconds so it should have time to send the data and save to the disk before the next request comes in (not sure though, just my guess)

我的实现中有什么问题吗?

Is there something wrong in my implementation?

编辑:由O. Jones解决.我以为有一个更好的时机会更好,但似乎我需要的时间很少.非常感谢!

Solved by O. Jones. I thought having a bigger timing is better but it seems that I need a really small time. Thank you so much!

推荐答案

每次 MediaRecorder 调用您的 ondataavailable 处理程序,它会在 event.data中为您提供一个Blob.该Blob包含所有累积的编码数据.以每秒2.6兆位的组合数据速率,三秒钟几乎是一个兆字节.对于POST请求和 appendFile 来说,这是非常大的负载.

Each time MediaRecorder calls your ondataavailable handler it gives you a Blob in event.data. That Blob contains all the accumulated encoded data. At a combined datarate of 2.6 megabits per second, three seconds of that is almost a megabyte. That's a very large payload for a POST request, and for appendFile.

较少拨打 ondataavailble 的电话.使用 .start(20)代替 .start(3000).您仍然在移动大量数据,但是将数据分成较小的块可以使事情变得混乱或丢失一些数据的可能性降低.

Call ondataavailble less often. Use .start(20) instead of .start(3000). You're still moving a lot of data, but moving it in smaller chunks makes it less likely that things will get out of order, or that you'll lose some.

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

And, consider using nodejs streams to write your files.

这篇关于发送与发送保存MediaRecorder数据会产生极其刺眼的结果吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆