大家好。目前我正在开发一个函数,可以通过使用 RecordRTC 中的 dataonavailable 函数在缓冲区数组上记录每个块,而不是停止记录并将其发送回服务器。然而,当我通过 socket.emit 将其作为编码的 64 数据或 bufferArray 发送到服务器时,最终的视频在三个扩展名下被损坏:x-matroska(MKV)、mp4、webM。因此,我可以询问文件最终损坏的原因以及如何解决此问题吗?
有关 webRTC 的信息:以下是您可以阅读更多相关信息的文档:https://github.com/muaz-khan/RecordRTC
P/S:我使用了1000次的拼接,并从5-10秒提前停止,仍然无法录制为短视频。
服务器 - 代码:
socket.on("SEND BLOB",buffer=>{
function writeOrAppendData(data){
var filePath = './'
const fileExtension = '.webm'
if (!fs.existsSync(filePath+'finalresult' + fileExtension)){
console.log('write Original file')
fs.writeFileSync(filePath+'finalresult' + fileExtension,data)
}
else {
fs.appendFileSync(filePath+'finalresult' + fileExtension,data)
}
}
console.log(buffer)
if (buffer instanceof Buffer)
writeOrAppendData(buffer)
})
客户-代码:
const config = ({video:true,audio:true})
this.setState({RTCStatus:"pending"})
navigator.mediaDevices.getUserMedia(config).then( async stream=>{
const candidateURL = this.candidateID
const socketIO = io.connect(baseURL,{query: {candidateID:candidateURL }})
//this.socketRef = io.connect(baseURL);
this.stream = stream;
this.socketRef.current = socketIO;
//this.candidateVideoRef.current.srcObject = stream;
this.screenSharingStream = await navigator.mediaDevices.getDisplayMedia(config);
this.videoRecorder = new RecordRTC(this.screenSharingStream, {
type: 'video',
mimeType:"video/webm;codecs=avc1",
//disableLogs: true,
timeSlice: 1000,
bitsPerSecond: 128000,
ondataavailable:async function(blob) {
console.log(blob)
//var candidateVideo = document.getElementById('candidate-video')
//candidateVideo.src =URL.createObjectURL(blob)
console.log(candidateVideo)
// this.candidateVideoRef.current.srcObject = URL.createObjectURL(blob)
var reader = new FileReader();
reader.readAsArrayBuffer(blob)
reader.onloadend = function(){
var buffer = reader.result;
console.log(buffer)
socketIO.emit('SEND BLOB',buffer)
}
//let blobData = await fetch(blob).then(r => r.blob()).then(blobFile => new File([blobFile], "record", { type: "video/mp4" }))
//console.log(blobData)
},
});
console.log('hey')
this.videoRecorder.startRecording();
this.setState({RTCStatus:this.videoRecorder.getState()})
///const sleep = m => new Promise(r => setTimeout(r, m));
//await sleep(3000);
//this.videoRecorder.stopRecording(async function(){
//
// socketIO.emit('END BLOB')
//})//
}
RTCStop = () =>{
if (this.stream && this.screenSharingStream){
const candidateURL = this.candidateID
const socketIO = io.connect(baseURL,{query: {candidateID:candidateURL }})
this.stream.getTracks().forEach((track)=>{
if (track.readyState==='live') {
track.stop()
this.candidateVideoRef.current.style.display='none';
this.videoRecorder.stopRecording(async function(){
socketIO.emit('END BLOB')
//let blob = await fetch(this.videoRecorder.getBlob()).then(r => r.blob()).then(blobFile => new File([blobFile], "record", { type: "video/mp4" }))
//let blobDuration = await getBlobDuration(blob);
//console.log(blobDuration+'seconds')
//let data = new FormData()
//console.log(blob);
//data.append("videoDuration",blobDuration)
//data.append(this.candidateID, blob)
//console.log('axios not run');
//await request().post('/c/video', data)
//console.log('axios run');
//let rest = await
//this.setState({submitVideo: true})
})
}})
我在使用 recordRTC 时遇到了类似的问题。我很确定文件损坏的原因是因为在发送已记录的块时,分块的视频文件需要特定的元数据才能进行解码。该元数据可在记录的第一个块上找到。因此,当尝试播放视频时,如果它们没有合并成一个视频文件,它们将显示为已损坏。我通过将所有块合并成一个斑点来解决这个问题。
async function mergeChunksAndPlay() {
console.log(chunks, "vid chuncks");
const blobs = chunks.map(chunk => chunk.blob);
const mergedBlob = new Blob(blobs, { type: 'video/webm' });
const blobUrl = URL.createObjectURL(mergedBlob);
downloadBlob(mergedBlob, `merged-video-${Date.now()}.webm`);
}
function downloadBlob(blob, filename) {
const blobUrl = URL.createObjectURL(blob);
const downloadLink = document.createElement('a');
downloadLink.href = blobUrl;
downloadLink.download = filename; // Provide a filename for the download
// Append the link to the document and trigger the download
document.body.appendChild(downloadLink);
downloadLink.click();
// Clean up by revoking the blob URL and removing the link
URL.revokeObjectURL(blobUrl);
document.body.removeChild(downloadLink);
}
如果您已将所有块保存到名为“chunks”的数组中,那么这将起作用,并且它将把合并的文件下载到您的浏览器。您应该可以从那里播放它。