/ya-media

Primary LanguageJavaScript

Домашнее задание по мультимедиа

Сначала опишу функционал, поскольку может возникнуть недопонимание в некоторых моментах. Далее опишу реализацию техник, которые использовались, для получения желаемого эффекта кино.

Я немного изменил макет 😁. Надеюсь, это не критично.

Функционал

Первый раз попадая на страницу, можно ввести ссылки на музыку и на субтитры, но не на видео. Это сделано потому, что CORS proxy не всегда хорошо работает. Иногда может оборвать скачивание видео в процессе просмотра. Дабы не возникало таких трудностей, я решил оставить видео жестко привязанным.

Когда ввели все ссылки которые хотели, можно нажимать кнопку "Купить билет". При этом страница изменится, переходя в режим просмотра видео. Но тут есть особый момент: видео только загружается, поэтому, пока не появится надпись "Приятного просмотра", видео не будет проигрываться. На устройствах с медленной сетью может придется подождать подольше.

Если увидели, что видео загрузилось, то можно нажимать на него. Начнется воспроизведение. Также можно поставить на паузу, нажав снова на видео. На паузу можно также ставить и на субтитрах.

Реализация

Здесь опишу техники, которые позволили добиться эффекта немого ч/б кино.

Видео

Для достижение реалистичного эффекта используются три элеменат canvas:

  • Первый отображает видеопоток из <video>, преобразованный посредствам WebGL (grayscale filter).
  • Второй показывает субтитры
  • Третий показывает дополнительные эффекты (зернистость, вертикальные царапины, произвольные царапины, пятна)

Все элементы расположены друг над другом, при этом canvas с субтитрами имеет свойство opacity, которая изменяется в зависимости от того нужно ли показывать субтитры в данный момент или нет. Субтитры отрисовываются один раз, а не каждый фрейм, что экономит ресурсы.

Эффекты рисуются на одном canvas, при этом зернистость имеет особенность. Для ее создания используется промежуточный canvas, в котором создается шум с заданной прозрачностью. Дальше этот элемент используется как pattern для заполнения canvas с эффектами. При этом элемент шаблона растягивается при помощи функции scale, что позволяет создать эффект крупного зерна. Остальные эффекты - это произвольно нарисованные линии и круги.

Еще одна особенность слоя с эффектами - отрисовка не на каждом фрейме. Есть значение промежутка, через который нужно отрисовать эффекты снова. Это позволяет добиться реалистичного эффекта старой пленки (ну, это мое сугубо личное мнение 😃).

Аудио

Для того, чтобы "испортить" запись, используется Audio API.

Поскольку я не звукорежиссер, и понятия не имею как можно придать эффект старой записи, пришлось отталкиваться от следующих соображений: раньше записи "шипели", а также у них практически не было низких частот.

Исходя из этого, я применил filter highpass для обрезания нужных верхних частот, а также createScriptProcessor для создания эффекта белого шума.

Производительность

Я проводил тесты на нескольких устройствах. Все имеют разные характеристики. На самом производительном постоянно было 60 fps, а также практически никакой нагрузки на CPU. На самом фиговом менее производительном ощущались проседания до 30 fps, в связи с нагрузкой на CPU. Такое поведение обусловлено скорее всего тем, что рисовать эффекты без использования WebGL было затратнее.