В Chrome. Я использую MediaRecorder и canvas.captureStream() для создания webm-файла холста.Как редактировать .webm Blobs, захваченные Chrome MediaRecorder
let recorder = new MediaRecorder(document.querySelector('canvas').captureStream(), {mimeType: 'video/webm'});
let chunks = [];
let blob;
recorder.ondataavailable = function(event) {
if (event.data.size > 0) {
chunks.push(event.data);
}
};
recorder.onstop = function() {
blob = new Blob(chunks, {type: 'video/webm'});
let url = URL.createObjectURL(blob);
let a = document.createElement('a');
document.body.appendChild(a);
a.href = url;
a.download = Date.now()+'.webm';
a.click();
window.URL.revokeObjectURL(url);
a.parentNode.removeChild(a);
}
recorder.onstart = function() {
chunks = [];
}
Это основная запись и загрузка кода вместе с вызовом recorder.start()
, чтобы начать запись и recorder.stop()
до конца.
Выходной файл webm в порядке, проблема, с которой я сталкиваюсь, состоит в том, что из-за дерьмового компьютера/накладных расходов я не всегда могу сделать холст достаточно быстрым, чтобы сделать его полным 60 кадров в секунду. На самом холсте я не возражаю против более низкой частоты кадров, но отставание при рисовании на холсте переходит в веб-интерфейс, и у меня остается видео с частотой x0.9.
Я попытался исправить это, используя canvas.captureStream(0)
, чтобы фиксировать только один кадр за раз и сопоставлять это с каждым рендерингом холста. Но это терпит неудачу, потому что я не могу указать продолжительность, в которой должен длиться каждый кадр, и размер файла становится огромным, поскольку каждый отдельный фрейм имеет всю информацию заголовка.
В моем блоке blob видно, что первые 131 капли постоянны, а blob 132 имеет очень большой объем данных. После этого обычно имеется ~ 7 спейсерных блоков с 1 байтом каждый, а затем один блок, содержащий некоторое большее количество данных. Я знаю, что первые 132 капли - это информация заголовка + мой первый кадр. И я думаю, что капли с большим количеством данных - это каждый кадр. Я также предполагаю, что 1-байтовые спейсерные капли имеют какое-то отношение к длительности кадра или паузе в течение установленного промежутка времени.
Что я хотел бы сделать, так это иметь возможность изменять эти пробелы spacer, чтобы указать точную продолжительность кадра. Я попытался сделать это вручную, скопировав 7 спейсеров между 2 кадрами, где я знал, что частота кадров идеальна, а затем удаляет все остальные разделители и вставляет в эти идеальные спейсерные капли между каждым фреймом, но выходной файл не воспроизводится.
Я не понимаю данные о блобе? Есть ли способ вручную указать продолжительность, в которой длится кадр, изменяя данные о блобе, или я придерживаюсь любой частоты кадров, которую я могу нарисовать на холсте?
Не уверен, что то, что я собираюсь сказать сейчас, на 100% верно, но я думаю, что вы не можете контролировать кадр записанного видео. Параметр fps предназначен только для captureStream, но это не настройка для MediaRecorder. Единственный вариант, который у вас есть: 'videoBitsPerSecond' в [MediaRecorder Constructor] (https://developer.mozilla.org/en-US/docs/Web/API/MediaRecorder/MediaRecorder). Вы могли бы попытаться сыграть с ним. – Kaiido
@ Kaiido К сожалению, это не поможет. У MediaRecorder на самом деле есть временный листок, который я могу разместить в MediaRecorder.start (timeslice), который, если установлен в 1000/fps, приведет к захвату кадров в fps, который я хочу. Я также могу вручную .requestData() после рисования кадра. Проблема в том, что узким местом является источник видео (например, обновление холста). Представьте, если бы я рисовал свой холст раз в секунду, поэтому моя анимация составляла 1 fps.Я хочу, чтобы иметь возможность записывать этот холст, а затем генерировать .webm, где каждый кадр этой анимации холста длится по моему выбору, независимо от холста 1 fps. – Bobby
Как я уже сказал, я не был уверен в предыдущем комментарии. У меня не было много времени, чтобы провести тесты, и мой VLC никогда не возвращает метаданные FPS из видеороликов, записанных в браузере ... Но у моего FF, похоже, одинаковое количество «mozDecodedFrames», чем fps, установленное в captureStream, когда установлено до <30 кадров в секунду. (10 кадров для 10-секундного видео с частотой 1 кадра в секунду и 297 кадров для видео с разрешением 10 сек при скорости 60 кадров в секунду). Не уверен, что он надежен. – Kaiido