RecordRTC:Ondataavailable 调用了两次。只有第一个文件是正确的,其他文件已损坏或太小
RecordRTC: Ondataavailable called twice. Only first file is proper, others are corrupted or too small
我想以2秒的间隔录制本地和远程流并使用Ajax将其上传到服务器。但问题是,ondataavailable 方法被调用了两次,所以同一个视频被两次上传到服务器。第一个视频可以正常播放,而其余视频要么损坏要么非常小(不到一秒)。所有视频的大小几乎一样!
我也尝试过使用 MediaRecorder API,但问题是一样的。我试过 5 秒的间隔,但还是不行!
这是我获取本地流的方式:
navigator.mediaDevices.getUserMedia({
video: false,
audio: true
}).then(function (myStream) {
localStream = myStream;
localStream.getTracks().forEach(function (track) {
yourConn.addTrack(track, localStream);
});
}).catch(function (error) {
streamAdded = false;
console.warn('Could not detect microphone');
return false;
});
我是这样录音的:
yourConn.ontrack = function (e) {
remoteVideo.srcObject = e.streams[0];
let recorder = RecordRTC([localStream, e.streams[0]], {
mimeType: 'video/webm;codecs=h264',
type: 'video',
timeSlice: 5000,
ondataavailable: function(blob) {
uploadBlob(blob);
},
});
recorder.startRecording();
}
uploadBlob 函数:
var formData = new FormData();
formData.append('recorded_file', mp4File);
$.ajax({
url: myURL,
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (response) {
console.log(response);
}
});
如何才能毫无问题地录制两个流?
(此答案涵盖 MediaRecorder,但我怀疑它也适用于 RecordRTC JS 库。)
timeSlice: 5000
参数将录音分成 块 ,每 5 秒调用一次 dataavailable
。但是这些块不能独立播放。您需要加入他们 like this 以创建有效的媒体容器文件:
const data = [];
recorder.ondataavailable = e => data.push(e.data);
recorder.onstop = () => uploadBlob(new Blob(data, {type: data[0].type}));
如果最后上传所有内容不切实际,您可以改为尝试加入服务器上的 blob。
我已经通过停止并重新启动方法解决了这个问题。当我得到第一个 blob 时我会停止记录器,然后我上传它并再次启动记录器。以至于我每次都得到一个完整的视频。
function initRecorder(remoteStream) {
recorder = RecordRTC([stream, remoteStream], {
type: 'video',
});
recorder.startRecording();
}
// in ontrack method:
initRecorder(remoteStream); // initially start recording
let recordingInterval = setInterval(function () {
if (!callInfo.isCallActive) clearInterval(recordingInterval);
recorder.stopRecording(function () {
let blob = recorder.getBlob();
if(callInfo.isCallActive) {
initRecorder(remoteStream); // restart recording
}
if (blob.size) { // prevent empty blobs
uploadBlob(blob, roomId);
}
});
}, 5000);
我想以2秒的间隔录制本地和远程流并使用Ajax将其上传到服务器。但问题是,ondataavailable 方法被调用了两次,所以同一个视频被两次上传到服务器。第一个视频可以正常播放,而其余视频要么损坏要么非常小(不到一秒)。所有视频的大小几乎一样!
我也尝试过使用 MediaRecorder API,但问题是一样的。我试过 5 秒的间隔,但还是不行!
这是我获取本地流的方式:
navigator.mediaDevices.getUserMedia({
video: false,
audio: true
}).then(function (myStream) {
localStream = myStream;
localStream.getTracks().forEach(function (track) {
yourConn.addTrack(track, localStream);
});
}).catch(function (error) {
streamAdded = false;
console.warn('Could not detect microphone');
return false;
});
我是这样录音的:
yourConn.ontrack = function (e) {
remoteVideo.srcObject = e.streams[0];
let recorder = RecordRTC([localStream, e.streams[0]], {
mimeType: 'video/webm;codecs=h264',
type: 'video',
timeSlice: 5000,
ondataavailable: function(blob) {
uploadBlob(blob);
},
});
recorder.startRecording();
}
uploadBlob 函数:
var formData = new FormData();
formData.append('recorded_file', mp4File);
$.ajax({
url: myURL,
data: formData,
cache: false,
contentType: false,
processData: false,
type: 'POST',
success: function (response) {
console.log(response);
}
});
如何才能毫无问题地录制两个流?
(此答案涵盖 MediaRecorder,但我怀疑它也适用于 RecordRTC JS 库。)
timeSlice: 5000
参数将录音分成 块 ,每 5 秒调用一次 dataavailable
。但是这些块不能独立播放。您需要加入他们 like this 以创建有效的媒体容器文件:
const data = [];
recorder.ondataavailable = e => data.push(e.data);
recorder.onstop = () => uploadBlob(new Blob(data, {type: data[0].type}));
如果最后上传所有内容不切实际,您可以改为尝试加入服务器上的 blob。
我已经通过停止并重新启动方法解决了这个问题。当我得到第一个 blob 时我会停止记录器,然后我上传它并再次启动记录器。以至于我每次都得到一个完整的视频。
function initRecorder(remoteStream) {
recorder = RecordRTC([stream, remoteStream], {
type: 'video',
});
recorder.startRecording();
}
// in ontrack method:
initRecorder(remoteStream); // initially start recording
let recordingInterval = setInterval(function () {
if (!callInfo.isCallActive) clearInterval(recordingInterval);
recorder.stopRecording(function () {
let blob = recorder.getBlob();
if(callInfo.isCallActive) {
initRecorder(remoteStream); // restart recording
}
if (blob.size) { // prevent empty blobs
uploadBlob(blob, roomId);
}
});
}, 5000);