发送与发送保存MediaRecorder数据会产生极其刺眼的结果吗? [英] Sending & Saving MediaRecorder Data Producing Extremely Glitchy Results?
问题描述
我有一个脚本,当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屋!