Не удается записать HTMLCanvasElement, когда вкладка размыта, даже если происходит рендеринг

Я пытаюсь записать видео с холста, даже когда пользователь переходит с вкладки (либо щелкнув другую вкладку, либо свернув окно). Я использую таймер, который запускается даже тогда, когда у пользователя размыта вкладка для рендеринга холста (я знаю, что этот таймер срабатывает, когда вкладка размыта, потому что я тестировал его). Но когда я присоединяю MediaStream из canvas.captureStream() к объекту MediaRecorder, BlobEvent из обратного вызова ondataavailable имеет длину 0.

Ниже приведен пример того, что я пытаюсь сделать.

let canvas = document.getElementById('canvas');

// ...Assume that I'm rendering some kind of video/animation to the canvas here...

let stream = canvas.captureStream();

let mediaRecorder = new MediaRecorder(stream, { mimeType: 'video/webm; codecs="opus,vp8"' });
mediaRecorder.start();

mediaRecorder.ondataavailable = (event) => {
  // This event's data is length 0 when the tab is blurred
  console.log(event);
}

Я понимаю, что ondataavailable обычно не срабатывает, когда вкладка находится в фоновом режиме, я получил это с помощью функции requestData на MediaRecorder, предположим, что это так.


person Jacob Greenway    schedule 29.06.2019    source источник
comment
Но с оптимизатором происходит так много всего, что даже если мы можем взломать наш скрипт, чтобы он срабатывал с нормальной скоростью при размытии, холст все равно может не прорисоваться, а рекордеру нечего будет пережевывать (это случай текущего FF на наименее).   -  person Kaiido    schedule 30.06.2019
comment
@Kaiido Значит, нет возможности получить данные с холста, когда вкладка размыта? Кроме того, это не дубликат, другой связанный вами вопрос касается конкретно requestAnimationFrame и рендеринга. Я пытаюсь записать медиапоток с captureCanvas.   -  person Jacob Greenway    schedule 30.06.2019
comment
Ну, вы можете получить данные холста (например, getImageData будет работать), но они не передаются в медиапоток, поэтому ни в MediaRecorder ... Существует открытая ошибка для FF, хотя я не могу ее найти rn.   -  person Kaiido    schedule 30.06.2019
comment
Как бы я мог использовать getImageData, разве это не специально для рендеринга части холста в другую часть? Редактировать: если вы используете закадровый холст, вы можете использовать функцию transferToImageBitmap и получить полное растровое изображение с холста.   -  person Jacob Greenway    schedule 30.06.2019
comment
Нет, ты меня не понимаешь. Мы можем запустить событие js, даже если оно размыто, как показано в понравившемся ответе. Мы также можем рисовать это на холсте и использовать его методы для захвата кадра, например, getImageData, который возвращает ImageData со всей информацией о пикселях, или toBlob и toDataURL, которые будут генерировать файл изображения. Однако внутренняя механика подачи MediaStream не будет работать. И, таким образом, у вас тоже ничего не будет записано. Разрыв где-то там, где мы не можем его контролировать: между холстом и MediaStream.   -  person Kaiido    schedule 30.06.2019