Меняется качество MediaRecorder и canvas.captureStream?

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

Подход Whammy работает хорошо, но поддерживается только в Chrome, поскольку это единственный браузер, который в настоящее время поддерживает кодировку webp (canvas.toDataURL("image/webp")). Итак, я использую подход captureStream в качестве резервной копии для Firefox (и использую libwebpjs для Safari).

Итак, теперь перейдем к моему вопросу: есть ли способ контролировать качество видео в потоке холста? А если нет, то рассматривали ли браузеры / w3c что-то подобное?

Вот скриншот одного из кадров видео, созданного whammy:

Меняется качество MediaRecorder и canvas.captureStream?

А вот тот же кадр, сгенерированный подходом MediaRecorder/canvas.captureStream:

Меняется качество MediaRecorder и canvas.captureStream?

Моя первая мысль - искусственно увеличить разрешение холста, который я транслирую, но я не хочу, чтобы выходное видео было больше.

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

Итак, следующая мысль заключается в том, что я должен снизить скорость, с которой я загружаю холст изображениями, а затем пропорционально снизить значение FPS, которое я передаю в captureStream, но проблема в том, что, хотя я, вероятно, решив проблему качества, я бы получил видео, которое работает медленнее, чем должно.

Редактировать:Вот грубый набросок кода, который я использую, на случай, если он поможет кому-нибудь в подобной ситуации.

Вы можете поделиться своим кодом?

Helder Sepulveda 17.09.2018 21:25

Это артефакты сжатия, и я боюсь, что таких опций нет ... Итак, во-первых, это не из-за captureStream. Вы можете проверить это, передав свой поток напрямую srcObject объекта videoElement, и вы не заметите столько артефактов. Основная проблема заключается в том, что наиболее распространенные видеокодеки не предназначены для отображения такой графики, воспринимайте это как то, что делает JPEG. В MediaRecorder есть опция videoBitsPerSecond, но она, вероятно, здесь не поможет. (Я пробовал, но этого не произошло). В Chrome у меня были чуть менее ужасные результаты с использованием кодека vp8, чем с любым другим.

Kaiido 18.09.2018 04:22

@HelderSepu Я попытался удалить ненужные части моего кода, поэтому в нем может быть пара ошибок: gist.github.com/josephrocca/ec073b3a90f936bec87bbd8e3e4c3486

user993683 18.09.2018 05:39

Просто примечание о вашей сути: if (MediaRecorder) должен быть if (window.MediaRecorder), иначе вы выбросите ReferenceError, и вместо цикла setTimeout 1 мс вам лучше запустить requestAnimationFrame one (я не думаю, что вы все равно можете записывать со скоростью более 60 кадров в секунду )

Kaiido 18.09.2018 07:30

Ах, спасибо за ловушку MeidiaRecorder. Причина, по которой я выбрал setTimeout, а не requestAnimationFrame, заключается в том, что я полагал, что последний более подвержен дросселированию браузером в случае задержки - я бы предпочел, чтобы браузер пользователя зависал, чем рисковал пропускать кадры. Я также не установил тайм-аут на 1/opts.fps, потому что решил, что в идеале мне следует обновлять холст намного быстрее, чем частота кадров captureStream, иначе я бы рискнул получить своего рода эффект временное алиасинг. Хотя я могу ошибаться.

user993683 18.09.2018 08:25

setTimeout будет регулироваться так же, как rAF ... См. этот вопрос / ответ для альтернативного метода синхронизации, который не должен регулироваться. Но учтите, что это регулирование применяется только тогда, когда окно размыто. Если это происходит из-за занятости браузера, даже ваши рисунки на холсте все равно будут заблокированы.

Kaiido 19.09.2018 03:59

Хорошо, переключил суть на requestAnimationFrame. Я провел несколько тестов, и, похоже, ни один из подходов не ограничен в Chrome или Firefox, когда вкладка / браузер не сфокусированы. Немного смущен этим.

user993683 19.09.2018 07:21
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
4
7
3 881
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это артефакты сжатия, и пока что вы мало что можете сделать ...

Видеокодеки созданы в основном для отображения реальных цветов и форм, что немного похоже на JPEG с очень низким качеством. Они также сделают все возможное, чтобы хранить как можно меньше информации между ключевыми кадрами (некоторые используют алгоритм обнаружения движения), чтобы им нужно было хранить меньше данных.

Эти кодеки обычно имеют некоторые настраиваемые параметры, которые позволяют нам улучшить постоянное качество кодирования, но спецификации MediaRecorder не зависят от кодеков, они не предоставляют (пока) возможность в API для нас, веб-разработчиков, для установки любых других вариант, чем фиксированный битрейт (который нам здесь больше не поможет).

Однако есть это предложение, который требует такой функции.

Спасибо, что изучили это! Приятно видеть, что этот материал обсуждается людьми w3c.

user993683 18.09.2018 05:38

Мне любопытно, почему фиксированная скорость передачи данных (например, параметр videoBitsPerSecond в конструкторе MediaRecorder) не помогает улучшить качество здесь? Разве это не то, что предназначена для управления битрейтом? У меня должно быть какое-то недоразумение.

user10898116 25.02.2019 12:21

@Joe, во-первых, нет опции CBR, videoBitsPerSecond - это только целевая скорость любого режима (я думаю, обычно это VBR). Тогда я предполагаю, что качество видео в VP8 зависит от другого варианта: webmproject.org/docs/encoder-parameters

Kaiido 25.02.2019 16:54

На самом деле, увеличение videoBitsPerSecond улучшает внешний вид

Max 08.08.2019 14:00

Другие вопросы по теме