javascript - MediaRecorder.ondataavailable 数据返回 0

标签 javascript html5-canvas html5-video mediarecorder

我正在屏幕外的 Canvas 上录制图像流,然后尝试下载录制的数据。每当我下载生成的视频时,它都是零字节。

当我调用 mediaRecorder.stop() 时,mediaRecorder.ondataavailable 会触发,但数据属性为空 — 它记录为 Blob(0) {大小:0,类型:“video/webm”}

我读了littlebird's answer to this issue ,他建议需要启用 Chrome 的实验性 Web 平台功能。在 chrome://flags 中启用此功能后,我仍然遇到问题。

我的代码粘贴在下面。这在我最初编写它时于 2017 年 3 月起作用,但现在我试图再次运行它时出现错误。我认为 Chrome 中一定发生了某些变化,但我无法追踪到任何东西。

this._createMediaRecorder = function(frame) {
  var newMediaRecorder;

  // Create hidden canvas to draw to
  newHiddenCanvas = document.createElement("canvas");
  newHiddenCanvas.setAttribute('id', frame + Date.now());

  newHiddenCanvas.width = DEPTHWIDTH;
  newHiddenCanvas.height = DEPTHHEIGHT;

  newHiddenContext = hiddenCanvas.getContext("2d");
  newHiddenContext.fillRect(0, 0, newHiddenCanvas.width, newHiddenCanvas.height);

  // Add canvas to hidden div
  myDiv.appendChild(newHiddenCanvas);

  // Create media recorder, add canvas to recorder
  newMediaRecorder = new MediaRecorder(newHiddenCanvas.captureStream());
  newMediaRecorder.canvas = newHiddenCanvas;

  var mediaChunks = [];

  newMediaRecorder.onstop = function (e) {

      // The video as a blob
      var blobVideo = new Blob(mediaChunks, { 'type' : 'video/webm' });

      // Download the video 
      var url = URL.createObjectURL(blobVideo);
      var a = document.createElement('a');
      document.body.appendChild(a);
      a.style = 'display: none';
      a.href = url;
      a.download = frame + Date.now() + '.webm';
      a.click();
      window.URL.revokeObjectURL(url);

      // Reset media chunks
      mediaChunks.length = 0;    

  }.bind(this);

  // When video data is available
  newMediaRecorder.ondataavailable = function(e) {
    mediaChunks.push(e.data); // This returns Blob(0) {size: 0, type: "video/webm"}
  };

  // Start recording
  newMediaRecorder.start();
  return newMediaRecorder;
};

最佳答案

在 mac chrome 浏览器上面临同样的问题 (MediaRecorder.ondataavailable Blob(0) {size: 0, type: "video/webm"})。

但是,相同的代码在 windows chrome 上运行得非常好。

尝试在 chrome 上启用 Chrome 的实验性 Web 平台功能,但没有成功。 无法确定为什么相同的代码不能在使用 chrome 的 mac OS 上运行。

const mediaSource = new MediaSource();
mediaSource.addEventListener('sourceopen', handleSourceOpen, false);
let mediaRecorder;
let recordedBlobs;
let sourceBuffer;
const errorMsgElement = document.querySelector('span#errorMsg');
const recordedVideo = document.querySelector('video#recorded');
const recordButton = document.querySelector('button#record');
recordButton.addEventListener('click', () => {
    if (recordButton.textContent === 'Start Recording') {
        startRecording();
    } else {
        stopRecording();
        recordButton.textContent = 'Start Recording';
        downloadButton.disabled = false;
    }
});
const downloadButton = document.querySelector('button#download');
downloadButton.addEventListener('click', () => {
    const blob = new Blob(recordedBlobs, { type: 'video/mp4; "codecs=vp9,opus"' });
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.style.display = 'none';
    a.href = url;
    a.download = 'recordedvideo.mp4';
    document.body.appendChild(a);
    a.click();
    setTimeout(() => {
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
    }, 100);
});
function handleSourceOpen() {
    sourceBuffer = mediaSource.addSourceBuffer('video/webm;codecs=vp9,opus');
}
function handleDataAvailable(event) {
    if (event.data && event.data.size > 0) {
        recordedBlobs.push(event.data);
    }
}
function startRecording() {
    recordedBlobs = [];
    let options = {
        mimeType: 'video/webm;codecs=vp9,opus',
        bitsPerSecond: 1421000
    };
    if (window.stream) {
        if (!MediaRecorder.isTypeSupported(options.mimeType)) {
            console.error(`${options.mimeType} is not Supported`);
            errorMsgElement.innerHTML = `${options.mimeType} is not Supported`;
            options = { mimeType: 'video/webm;codecs=vp9,opus' };
            if (!MediaRecorder.isTypeSupported(options.mimeType)) {
                console.error(`${options.mimeType} is not Supported`);
                errorMsgElement.innerHTML = `${options.mimeType} is not Supported`;
                options = { mimeType: 'video/webm;codecs=vp9,opus' };
                if (!MediaRecorder.isTypeSupported(options.mimeType)) {
                    console.error(`${options.mimeType} is not Supported`);
                    errorMsgElement.innerHTML = `${options.mimeType} is not Supported`;
                    options = { mimeType: '' };
                }
            }
        }
    }
    try {
        mediaRecorder = new MediaRecorder(window.stream, options);
        let constraints = {
            frameRate: 25,
            width: 1280,
            height: 720
        };
        mediaRecorder.stream.getVideoTracks()[0].applyConstraints(constraints);
    } catch (e) {
        console.error('Exception while creating MediaRecorder:', e);
        errorMsgElement.innerHTML = `Exception while creating MediaRecorder: ${JSON.stringify(e)}`;
        return;
    }
    recordButton.textContent = 'Stop Recording';
    downloadButton.disabled = true;
    mediaRecorder.onstop = (event) => {
    };
    mediaRecorder.ondataavailable = handleDataAvailable;
    mediaRecorder.start(); 
}
function stopRecording() {
    mediaRecorder.stop();
}
function handleSuccess(stream) {
    recordButton.disabled = false;
    window.stream = stream;
}
async function init() {
    try {
        var vi = document.querySelector('iframe[#xyz_iframe]').contentDocument.body.querySelector('video[autoplay]');
        var stream;
        stream = vi.captureStream();
        handleSuccess(stream);
    } catch (e) {
        console.error('navigator.getUserMedia error:', e);
        errorMsgElement.innerHTML = `navigator.getUserMedia error:${e.toString()}`;
    }
}
document.querySelector('button#start').addEventListener('click', async () => {
    await init();
});

关于javascript - MediaRecorder.ondataavailable 数据返回 0,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51292675/

相关文章:

javascript - 此IPC代码有什么问题?它不发出事件

javascript - HTML 在所有设备上响应

javascript - 如何制作 HTML5 Canvas "Press/Click to play"开始屏幕

javascript - 我的 HTML5 Canvas 游戏在帧之间不断闪烁

ios7 - 隐藏 Safari Mobile 上的播放按钮 - iOS 7

javascript - 用于了解 HTML5 视频何时准备好在没有黑色背景的情况下播放的事件

javascript - 如何按经纬度设置谷歌地图标记并提供信息气泡

javascript - 异常 : Error: Uncaught (in promise): TypeError: Cannot read property '0' of null any suggestion please?

java - 将动态 BufferedImage 流式传输到网站

html - 没有用于 HTML5 <video> 的标准全屏按钮?