Webm 文件无法播放
Webm File Not Playing
我创建了一个 mediaRecorder 来记录 video/audio 并将记录的数据作为属性附加到 canvas 上,如下所示:
var options = { mimeType: 'video/webm;codecs=H264' };
try {
mediaStream = video.captureStream(); //console.log(mediaStream);
mediaRecorder = new MediaRecorder(mediaStream, options);
mediaRecorder.ondataavailable = function(e) { console.log('ondataavailable:'+e.data.size);
mediaRecordedChunks.push(e.data);
cvs.setAttribute('recordedChunks', mediaRecordedChunks);
}; //console.log(mediaRecorder);
mediaRecorder.onerror = function(err) { console.log('onerror:'+err.name); };
//
mediaRecordedChunks = [];
mediaRecorder.start(1000); //1000 milliseconds per timeslice
} catch(err) {
console.log('err:'+err.name); /* return the error name */
};
};
然后我正在读取属性并创建一个 blob/file,如下所示:
if (localCanvas) {
localCanvas.getContext('2d').clearRect(0, 0, localCanvas.width, localCanvas.height);
//console.log('recordedChunks:'+localCanvas.getAttribute('recordedChunks')[0]);
var blob = localCanvas.getAttribute('recordedChunks');
//console.log('outBlob:'+outBlob);
var binaryData = [];
binaryData.push(blob);
var url = (window.URL ? URL : webkitURL).createObjectURL(new Blob(binaryData, {type: 'video/webm;codecs=H264'}));
var link = window.document.createElement('a');
link.href = url;
link.download = 'test_output.webm';
var click = document.createEvent("Event");
//click.initEvent('click', true, true);
//link.dispatchEvent(click);
link.click();
window.URL.revokeObjectURL(url);
link.remove();
console.log('downloaded');
};
这会清除 canvas 并将文件下载到我的机器上。但是文件不会播放。我尝试过不同的 mime 类型,但没有任何效果。我的最终目标是拥有一个可播放的 video/audio 文件(理想情况下,一个 .mp4 文件,但我知道 Chrome 不会那样做)。
我完全不清楚你为什么要这样做,但 HTMLAttributes 只能是字符串,不能是别的。
所以当你做cvs.setAttribute('recordedChunks', mediaRecordedChunks);
时实际上是在做cvs.setAttribute('recordedChunks', mediaRecordedChunks.toString());
,由于此时mediaRecordedChunks
只包含一个Blob对象,它会生成字符串"[object Blob]"
:
const mediaRecordedChunks = [ new Blob([]) ];
const cvs = document.createElement( "canvas" );
cvs.setAttribute( "recordedChunks", mediaRecordedChunks );
console.log( cvs.getAttribute( "recordedChunks" ) );
这就是您保存在文件中的内容(您可以尝试在文本编辑器中打开它)。
从这个字符串中,您将无法做任何与您记录的原始块相关的事情。
最好的办法是让你的保存代码能够直接访问 mediaRecordedChunks
数组,要么通过作用域,要么将它作为参数传递给保存保存部分的函数。
// refactor your saving code to be a function
const saveMedia = ( chunks ) => {
const blob = new Blob( chunks );
//...
};
然后当你想保存时,从mediaRecordedChunks
声明的部分调用它
saveMedia( mediaRecordedChunks );
如果你绝对想使用一个属性,无论它有多糟糕,然后从你的记录器部分创建 blobURI 并存储这是 canvas 属性,但请记住在每个新的 dataavailable 事件中撤销前一个属性。
//...
mediaRecorder.ondataavailable = function(e) {
mediaRecordedChunks.push( e.data );
const oldURL = cvs.getAttribute( 'recordedChunks' );
URL.revokeObjectURL( oldURL );
const newURL = URL.createObjectURL( mediaRecordedChunks );
cvs.setAttribute( 'recordedChunks', newURL );
};
//...
并且在您的保存代码中,
if( localCanvas ) {
const url = localCanvas.getAttribute( 'recordedChunks' );
const link = window.document.createElement( 'a' );
link.href = url;
link.download = 'test_output.webm';
document.body.append( link );
link.click();
link.remove();
}
我创建了一个 mediaRecorder 来记录 video/audio 并将记录的数据作为属性附加到 canvas 上,如下所示:
var options = { mimeType: 'video/webm;codecs=H264' };
try {
mediaStream = video.captureStream(); //console.log(mediaStream);
mediaRecorder = new MediaRecorder(mediaStream, options);
mediaRecorder.ondataavailable = function(e) { console.log('ondataavailable:'+e.data.size);
mediaRecordedChunks.push(e.data);
cvs.setAttribute('recordedChunks', mediaRecordedChunks);
}; //console.log(mediaRecorder);
mediaRecorder.onerror = function(err) { console.log('onerror:'+err.name); };
//
mediaRecordedChunks = [];
mediaRecorder.start(1000); //1000 milliseconds per timeslice
} catch(err) {
console.log('err:'+err.name); /* return the error name */
};
};
然后我正在读取属性并创建一个 blob/file,如下所示:
if (localCanvas) {
localCanvas.getContext('2d').clearRect(0, 0, localCanvas.width, localCanvas.height);
//console.log('recordedChunks:'+localCanvas.getAttribute('recordedChunks')[0]);
var blob = localCanvas.getAttribute('recordedChunks');
//console.log('outBlob:'+outBlob);
var binaryData = [];
binaryData.push(blob);
var url = (window.URL ? URL : webkitURL).createObjectURL(new Blob(binaryData, {type: 'video/webm;codecs=H264'}));
var link = window.document.createElement('a');
link.href = url;
link.download = 'test_output.webm';
var click = document.createEvent("Event");
//click.initEvent('click', true, true);
//link.dispatchEvent(click);
link.click();
window.URL.revokeObjectURL(url);
link.remove();
console.log('downloaded');
};
这会清除 canvas 并将文件下载到我的机器上。但是文件不会播放。我尝试过不同的 mime 类型,但没有任何效果。我的最终目标是拥有一个可播放的 video/audio 文件(理想情况下,一个 .mp4 文件,但我知道 Chrome 不会那样做)。
我完全不清楚你为什么要这样做,但 HTMLAttributes 只能是字符串,不能是别的。
所以当你做cvs.setAttribute('recordedChunks', mediaRecordedChunks);
时实际上是在做cvs.setAttribute('recordedChunks', mediaRecordedChunks.toString());
,由于此时mediaRecordedChunks
只包含一个Blob对象,它会生成字符串"[object Blob]"
:
const mediaRecordedChunks = [ new Blob([]) ];
const cvs = document.createElement( "canvas" );
cvs.setAttribute( "recordedChunks", mediaRecordedChunks );
console.log( cvs.getAttribute( "recordedChunks" ) );
这就是您保存在文件中的内容(您可以尝试在文本编辑器中打开它)。
从这个字符串中,您将无法做任何与您记录的原始块相关的事情。
最好的办法是让你的保存代码能够直接访问 mediaRecordedChunks
数组,要么通过作用域,要么将它作为参数传递给保存保存部分的函数。
// refactor your saving code to be a function
const saveMedia = ( chunks ) => {
const blob = new Blob( chunks );
//...
};
然后当你想保存时,从mediaRecordedChunks
声明的部分调用它
saveMedia( mediaRecordedChunks );
如果你绝对想使用一个属性,无论它有多糟糕,然后从你的记录器部分创建 blobURI 并存储这是 canvas 属性,但请记住在每个新的 dataavailable 事件中撤销前一个属性。
//...
mediaRecorder.ondataavailable = function(e) {
mediaRecordedChunks.push( e.data );
const oldURL = cvs.getAttribute( 'recordedChunks' );
URL.revokeObjectURL( oldURL );
const newURL = URL.createObjectURL( mediaRecordedChunks );
cvs.setAttribute( 'recordedChunks', newURL );
};
//...
并且在您的保存代码中,
if( localCanvas ) {
const url = localCanvas.getAttribute( 'recordedChunks' );
const link = window.document.createElement( 'a' );
link.href = url;
link.download = 'test_output.webm';
document.body.append( link );
link.click();
link.remove();
}