将 blob 保存为单个 webm 文件

Saving blobs as a single webm file

我正在通过 webrtc 录制用户屏幕,然后使用 MediaStreamRecorder 每 x 秒发布一次视频 blob。在服务器端,我在 sails 中设置了一个操作,将 blob 保存为 webm 文件。

问题是我无法让它附加数据并创建一个大的 webm 文件。当它附加时文件大小按预期增加,因此数据正在附加,但是当我播放文件时,它要么播放第一秒,根本不播放,要么播放但不显示视频。

可以将文件与 ffmpeg 合并,但我宁愿尽可能避免这种情况。

这是客户端的代码:

'use strict';


// Polyfill in Firefox.
// See https://blog.mozilla.org/webrtc/getdisplaymedia-now-available-in-adapter-js/
if (typeof adapter != 'undefined' && adapter.browserDetails.browser == 'firefox') {
  adapter.browserShim.shimGetDisplayMedia(window, 'screen');
}

io.socket.post('/processvideo', function(resData) {
    console.log("Response: " + resData);
});

function handleSuccess(stream) {
  const video = document.querySelector('video');
  video.srcObject = stream;

var mediaRecorder = new MediaStreamRecorder(stream);
mediaRecorder.mimeType = 'video/webm';
mediaRecorder.ondataavailable = function (blob) {
    console.log("Sending Data");
    //var rawIO = io.socket._raw;
    //rawIO.emit('some:event', "using native socket.io");

    io.socket.post('/processvideo', {"vidblob": blob}, function(resData) {
        console.log("Response: " + resData);
    });
};
mediaRecorder.start(3000);
}

function handleError(error) {
  errorMsg(`getDisplayMedia error: ${error.name}`, error);
}

function errorMsg(msg, error) {
  const errorElement = document.querySelector('#errorMsg');
  errorElement.innerHTML += `<p>${msg}</p>`;
  if (typeof error !== 'undefined') {
    console.error(error);
  }
}

if ('getDisplayMedia' in navigator) {
  navigator.getDisplayMedia({video: true})
    .then(handleSuccess)
    .catch(handleError);
} else {
  errorMsg('getDisplayMedia is not supported');
}

服务器上的代码:

module.exports = async function processVideo (req, res) {
    var fs          = require('fs'),
        path        = require('path'),
        upload_dir  = './assets/media/uploads',
        output_dir  = './assets/media/outputs',
        temp_dir = './assets/media/temp';

    var params = req.allParams();
    if(req.isSocket && req.method === 'POST') {
        _upload(params.vidblob, "test.webm");
        return res.send("Hi There");
    }
    else {
        return res.send("Unknown Error");
    }

    function _upload(file_content, file_name) {
        var fileRootName = file_name.split('.').shift(),
        fileExtension = file_name.split('.').pop(),
        filePathBase = upload_dir + '/',
        fileRootNameWithBase = filePathBase + fileRootName,
        filePath = fileRootNameWithBase + '.' + fileExtension,
        fileID = 2;



        /* Save all of the files as different files. */
        /*
        while (fs.existsSync(filePath)) {
            filePath = fileRootNameWithBase + fileID +  '.' + fileExtension;
            fileID += 1;
        }
        fs.writeFileSync(filePath, file_content);
        */

        /* Appends the binary data like you'd expect, but it's not playable. */
        fs.appendFileSync(upload_dir + '/' + 'test.file', file_content);

    }
}

如有任何帮助,我们将不胜感激!

我认为这将很难开发,并且不符合项目要求。所以我决定构建一个电子应用程序。只是发布这个所以我可以解决这个问题。