Недавно я пытался создать видео в браузере и, таким образом, играл с двумя подходами:
- Использование js-библиотеки whammy для объединения кадров webp в видео webm. Подробнее здесь.
- Использование
MediaRecorder
иcanvas.captureStream
. Подробнее здесь.
Подход whammy работает хорошо, но поддерживается только в Chrome, так как это единственный браузер, который в настоящее время поддерживает кодировку webp (canvas.toDataURL("image/webp")
). Поэтому я использую подход captureStream
в качестве резервной копии для Firefox (и использую libwebpjs для Сафари).
Итак, теперь на мой вопрос: есть ли способ контролировать качество видео потока холста? А если нет, то рассматривалось ли что-то подобное браузерами/w3c?
Вот скриншот одного из кадров видео, сгенерированного whammy:
А вот тот же кадр, сгенерированный подходом MediaRecorder/canvas.captureStream
:
Моя первая мысль — искусственно увеличить разрешение холста, который я транслирую, но я не хочу, чтобы выходное видео было больше.
Я пытался увеличить частоту кадров, передаваемую методу captureStream
(думая, что могут происходить какие-то странные интерполяции кадров), но это не помогает. На самом деле это ухудшает качество, если я делаю его слишком высоким. Моя текущая теория заключается в том, что браузер определяет качество потока на основе того, к какой вычислительной мощности он имеет доступ. В этом есть смысл, потому что, если он будет поддерживать заданную мной частоту кадров, то что-то должно уступить.
Итак, следующая мысль состоит в том, что я должен замедлить скорость, с которой я загружаю холст изображениями, а затем пропорционально снизить значение FPS, которое я передаю в captureStream
, но проблема в том, что хотя я, вероятно, решил проблему качества, я получил бы видео, которое работает медленнее, чем должно.
Изменить: вот грубый набросок кода, который я использование, если это поможет кому-то в подобной ситуации.
if(MediaRecorder)
должно бытьif(window.MediaRecorder)
, иначе вы выдаете ReferenceError, и вместо цикла setTimeout 1 мс вам лучше запустить запросAnimationFrame один (я не думаю, что вы все равно можете записывать со скоростью более 60 кадров в секунду ) - person Kaiido   schedule 18.09.2018MeidiaRecorder
улов. Причина, по которой я выбралsetTimeout
, а неrequestAnimationFrame
, заключается в том, что я решил, что последний более склонен к дросселированию браузером в случае задержки - я бы предпочел, чтобы браузер пользователя зависал, чем риск пропуска кадров. Я также не устанавливал тайм-аут на1/opts.fps
, потому что решил, что в идеале я должен обновлять холст намного быстрее, чем частота кадровcaptureStream
, иначе я рискую чем-то вроде эффект временного сглаживания. Хотя могу ошибаться. - person   schedule 18.09.2018requestAnimationFrame
. Я провел несколько тестов, и ни один из подходов, кажется, не регулируется в Chrome или Firefox, когда вкладка/браузер не сфокусированы. Немного смущен этим. - person   schedule 19.09.2018