JavaScript Mediarecorder DataVailable可空数据(大小0)仅在Safari中[在Chrome和Firefox中工作正常]

发布于 2025-01-20 19:25:50 字数 4259 浏览 4 评论 0原文

问题是关于 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文