Webm файл не воспроизводится - PullRequest
0 голосов
/ 25 февраля 2020

Я создаю mediaRecorder для записи видео / аудио и прикрепляю записанные данные в качестве атрибута на холст, например:

    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-объект / файл, как это:

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');
};

Это очищает холст и загружает файл на мою машину. Но файл не будет воспроизводиться. Я пробовал разные типы пантомимы, но ничего не получалось. Моя конечная цель - получить воспроизводимый видео / аудио файл (в идеале - файл .mp4, но я понимаю, что Chrome этого не сделает).

1 Ответ

0 голосов
/ 25 февраля 2020

Мне совершенно непонятно, почему вы это делаете, но 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();
}
...