JavaScript Mediarecorder DataVailable可空数据(大小0)仅在Safari中[在Chrome和Firefox中工作正常]
问题是关于 safari 中的 mediaRecorder 和 event.data 0 大小,但在 chrome 或 firefox 中则不然。
我做了一个简单的 navigator.mediaDevices.getUserMedia 在视频标签中预览它。然后使用 mediarecorder 将数据发送到服务器==>一切都在 Chrome 和 Firefox 中运行。
但在 safari 中,当我 console.log(event.data.size) 时,它在 safari 中始终为 0。
是因为编解码器还是有什么方法可以处理数据?
********** 这里的所有代码在 chrome 和 firfox 上都可以 100% 工作,但在 safari 中不行
HTML
<button id="record" onclick="startRecording();" >start</button>
<video id="gum" autoplay loop playsinline="true" ></video>
JAVASCRIPT
let order = 0;
var mediaRecorder;
var sourceBuffer;
var gumVideo = document.querySelector("video#gum");
var constraints = { audio: true, video: true };
// DEFAULT VP8 AND TEST BROWSER CODEC
stubstream_codec = "video/webm;codecs=vp8,opus";
if ( MediaRecorder.isTypeSupported("video/mp4;codecs=h264") === true ) { stubstream_codec = "video/mp4;codecs=h264"; }
if ( MediaRecorder.isTypeSupported("video/mp4;codecs=avc1") === true ) { stubstream_codec = "video/mp4;codecs=avc1"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=av1,opus") === true ) { stubstream_codec = "video/webm;codecs=av1,opus"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=avc1,opus") === true ) { stubstream_codec = "video/webm;codecs=avc1,opus"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=vp9,opus") === true ) { stubstream_codec = "video/webm;codecs=vp9,opus"; }
console.log(stubstream_codec);
// GET CAMERA
navigator.mediaDevices.getUserMedia( constraints ).then( successCallback, errorCallback );
// SEND STREAM TO VIDEO TAG
function successCallback(stream) { console.log("stream ok", stream); window.stream = stream; gumVideo.srcObject = stream; }
function errorCallback(error) { console.log(error); }
// SEND TO SERVER
function handleDataAvailable(event) {
console.log(event); console.log(event.data);
if (event.data && event.data.size > 0) {
var reader = new FileReader();
reader.readAsArrayBuffer(event.data);
reader.onloadend = async function(event) {
let arrayBuffer = reader.result; let uint8View = new Uint8Array(arrayBuffer);
let response = await fetch("/receiver.php", { method: "POST", body: JSON.stringify({ chunk: uint8View, order: order, snowi: "test" }) });
order += 1;
}
}
}
function startRecording() {
var options = {mimeType: stubstream_codec, bitsPerSecond: 100000};
try { mediaRecorder = new MediaRecorder(window.stream, options); }
catch (e0) { console.log("Unable to create MediaRecorder with codec"); return false; }
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(3000);
console.log("MediaRecorder started");
}
function stopRecording() { mediaRecorder.stop(); }
PHP
$request = json_decode(file_get_contents("php://input"), true);
$chunk = $request['chunk'] ?? '';
$order = $request['order'] ?? '';
$snowi = $request['snowi'] ?? '';
$instream_path = 'path_to_save/';
$filePath = $instream_path.$snowi.'.webm';
// ARRAY TO BINARY FORMAT
$binarydata = pack("C*", ...$chunk);
// APPEND RECEIVED CHUNKS TO MAKE 1 PLAYABLE .WEBM ;)
$out = fopen("{$filePath}", $order == 0 ? "wb" : "ab");
if ($out) { fwrite($out, $binarydata); fclose($out); }
控制台登录 Chrome
object=> Blob {size: 140261, type: 'video/webm;codecs=vp9,opus'}
控制台日志ON SAFARI
[Log] object=> – BlobEvent {isTrusted: true, data: Blob, timecode: 0, …} (recookies.js, line 7)
BlobEvent {isTrusted: true, data: Blob, timecode: 0, type: "dataavailable", target: MediaRecorder, …}
[Log] object=> – Blob {size: 0, type: "", slice: function, …} (recookies.js, line 7)
Blob {size: 0, type: "", slice: function, stream: function, text: function, …}
Blobsize: 0type: ""
Blob Prototypearray
Buffer()constructor: function()sizeslice([start], [end], [contentType])
stream()text()typeSymbol(Symbol.toStringTag): "Blob"Object Prototype
** 对于流编解码器我尝试了其他值,但我总是得到 0 大小的数据(在 safari 中),为什么?
---------- 编辑 1 ---------------
当我更改为 new MediaRecorder(window.stream);
而不指定编解码器时=>它有效,但仅适用于第一个块(3秒),之后它会发送另一个块:(
The question is about mediaRecorder and event.data 0 size in safari but not in chrome or firefox.
I doing a simple navigator.mediaDevices.getUserMedia to preview it in a video tag. Then with mediarecorder I send data to the server => ALL is working in chrome AND firefox.
But in safari when I console.log(event.data.size) it's always 0 on in safari.
Is it because of the codec or what could a way to work with the data ?
********** ALL THE CODE HERE IS WORKING 100% on chrome and firfox, but NOT in safari
HTML
<button id="record" onclick="startRecording();" >start</button>
<video id="gum" autoplay loop playsinline="true" ></video>
JAVASCRIPT
let order = 0;
var mediaRecorder;
var sourceBuffer;
var gumVideo = document.querySelector("video#gum");
var constraints = { audio: true, video: true };
// DEFAULT VP8 AND TEST BROWSER CODEC
stubstream_codec = "video/webm;codecs=vp8,opus";
if ( MediaRecorder.isTypeSupported("video/mp4;codecs=h264") === true ) { stubstream_codec = "video/mp4;codecs=h264"; }
if ( MediaRecorder.isTypeSupported("video/mp4;codecs=avc1") === true ) { stubstream_codec = "video/mp4;codecs=avc1"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=av1,opus") === true ) { stubstream_codec = "video/webm;codecs=av1,opus"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=avc1,opus") === true ) { stubstream_codec = "video/webm;codecs=avc1,opus"; }
if ( MediaRecorder.isTypeSupported("video/webm;codecs=vp9,opus") === true ) { stubstream_codec = "video/webm;codecs=vp9,opus"; }
console.log(stubstream_codec);
// GET CAMERA
navigator.mediaDevices.getUserMedia( constraints ).then( successCallback, errorCallback );
// SEND STREAM TO VIDEO TAG
function successCallback(stream) { console.log("stream ok", stream); window.stream = stream; gumVideo.srcObject = stream; }
function errorCallback(error) { console.log(error); }
// SEND TO SERVER
function handleDataAvailable(event) {
console.log(event); console.log(event.data);
if (event.data && event.data.size > 0) {
var reader = new FileReader();
reader.readAsArrayBuffer(event.data);
reader.onloadend = async function(event) {
let arrayBuffer = reader.result; let uint8View = new Uint8Array(arrayBuffer);
let response = await fetch("/receiver.php", { method: "POST", body: JSON.stringify({ chunk: uint8View, order: order, snowi: "test" }) });
order += 1;
}
}
}
function startRecording() {
var options = {mimeType: stubstream_codec, bitsPerSecond: 100000};
try { mediaRecorder = new MediaRecorder(window.stream, options); }
catch (e0) { console.log("Unable to create MediaRecorder with codec"); return false; }
mediaRecorder.ondataavailable = handleDataAvailable;
mediaRecorder.start(3000);
console.log("MediaRecorder started");
}
function stopRecording() { mediaRecorder.stop(); }
PHP
$request = json_decode(file_get_contents("php://input"), true);
$chunk = $request['chunk'] ?? '';
$order = $request['order'] ?? '';
$snowi = $request['snowi'] ?? '';
$instream_path = 'path_to_save/';
$filePath = $instream_path.$snowi.'.webm';
// ARRAY TO BINARY FORMAT
$binarydata = pack("C*", ...$chunk);
// APPEND RECEIVED CHUNKS TO MAKE 1 PLAYABLE .WEBM ;)
$out = fopen("{$filePath}", $order == 0 ? "wb" : "ab");
if ($out) { fwrite($out, $binarydata); fclose($out); }
CONSOLE LOG IN CHROME
object=> Blob {size: 140261, type: 'video/webm;codecs=vp9,opus'}
CONSOLE LOG ON SAFARI
[Log] object=> – BlobEvent {isTrusted: true, data: Blob, timecode: 0, …} (recookies.js, line 7)
BlobEvent {isTrusted: true, data: Blob, timecode: 0, type: "dataavailable", target: MediaRecorder, …}
[Log] object=> – Blob {size: 0, type: "", slice: function, …} (recookies.js, line 7)
Blob {size: 0, type: "", slice: function, stream: function, text: function, …}
Blobsize: 0type: ""
Blob Prototypearray
Buffer()constructor: function()sizeslice([start], [end], [contentType])
stream()text()typeSymbol(Symbol.toStringTag): "Blob"Object Prototype
** for stream codec I tried other values, but I always get 0 sized data (on in safari), why ?
---------- EDIT 1 ---------------
When I change to new MediaRecorder(window.stream);
without specifying the codec => it works but ONLY for the first chunk (3 seconds) it does send the other after that :(
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论