JavaScript перехватывает первый кадр видео

JavaScript
JavaScript перехватывает первый кадр видео

JavaScript перехватывает первый кадр видео

1. Предпосылки

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

В результате проблема:

Поэтому родилась сложность перехвата JS первого кадра видео, но, просмотрев информацию, я обнаружил, что в Интернете представлено не более двух видов информации.wasm + ffmpegСотрудничайте с бэкендом для перехвата, а второй — для перехвата JS. Плюсы и минусы тоже очевидны: первый имеет относительно высокую стоимость согласования и не очень гибок, второй можно использовать в обычных условиях, но будут проблемы с совместимостью (пока IE) и проблема перехвата черный экран.

Во-вторых, wasm + ffmpeg

Достоинства и недостатки этого метода также очевидны.Стоимость сотрудничества относительно высока, и это вызовет резкое увеличение веб-памяти.Однако количество кадров, которые были перехвачены поддерживаемыми типами видео, очень гибкое, т.к. это связано с сервером, вы можете обратиться к деталям.wasm + ffmpeg для захвата видео.

3. Перехват интерфейса JavaScript

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

1. Знание канвы здесь не будет слишком большим, давайте в основном посмотрим на события ответа тега видео:

video响应事件执行结果1.png

Результаты video响应事件执行结果.png

Согласно приказу, первыми на срабатывание оказалисьtimeupdateСобытие, согласно предположению, должно быть выполнено первымloadedmetadata, метаданные загружены. В MDN нет явного заявления об этом, но это можно обосновать:

когдаcurrentTimeСрабатывает при обновленииtimeupdateмероприятие

В заключение: Хотя он срабатывает первым, видеофайл еще не загружен, а содержимое самого холста перехвачено. Примечание. Событие timeupdate запускается от 4 до 66 раз в секунду в зависимости от используемой системы, и из-за высокой частоты срабатывания единица измерения слишком мала (уровень миллисекунды), а реакцию на событие необходимо отложить, ее нельзя контролировать. полностью и точно.

  • loadmetadata Как упоминалось выше, он срабатывает после загрузки метаданных, но данные не включают в себя сам видеофайл. Вывод: Если видеофайл большой и время загрузки долгое, все равно невозможно захватить первый загруженный кадр. Дополнение: метод URL.createObjectURL() может быть в основном неосведомленным, но он небезопасен.

  • loadeddata Текущий номер кадра (первый кадр) срабатывает после загрузки, без проблем. Вывод: имеется. Дополнение: Что делать, если первый кадр черный экран и хотите использовать следующий кадр, извините, количество оставшихся кадров плюс загрузка не входит в его рамки рассмотрения, и это событие не имеет значения.

  • Canplay Срабатывает, когда видео может начать воспроизводиться, то есть количество кадров для загрузки (24/25/30/60 и т. д.) определяется в зависимости от количества загруженных видеокадров после того, как экран воспроизведения будет удовлетворен. Резюме: Поскольку загрузка больше, чем событие loaddata (немного больше), это обычно возможно. Дополнение: его можно удовлетворить, контролируя currentTime (но он не может быть таким точным, как второй кадр), который можно рассматривать как «текущий воспроизводимый кадр».

  • Воспроизведение будет запущено только тогда, когда оно начнет воспроизводиться, что не очень соответствует требованию загрузки быстрого перехвата.

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

2. Разобравшись с приведенными выше ответными событиями, давайте взглянем на следующую операцию перехвата:

js截取视频.png

Каков результат вышеизложенного?Xnip20200901_190817.png

Видно, что первый кадр видео успешно снят, на данном этапе требования в основном выполнены, но пока неизвестно, валидна ли картинка, поэтому нужно делать дальнейшие выводы.

3. Действителен ли первый кадр?

На самом деле, первый кадр захваченного изображения, иногда из-за плохого качества видео или некоторых других факторов, захваченное изображение часто не очень соответствует ожиданиям, и всегда будут чисто черные изображения, прозрачные изображения, белые изображения и т. д. Недопустимое изображение. Поэтому нам необходимо определить достоверность изображения. Итак, как определить подлинность картины?

На этом этапе вам нужно распознать новое свойство:Uint8ClampedArray

Uint8ClampedArray (фиксированный массив 8-битных целых чисел без знака) Типизированный массив представляет собой массив 8-битных целых чисел без знака, значения которых фиксированы в диапазоне 0-255; если вы укажете значение вне диапазона [0,255], он will заменяется на 0 или 255; если вы укажете нецелое число, то оно будет установлено на ближайшее целое число. (массив) содержимое инициализируется 0. После создания (массива) вы можете ссылаться на элементы массива, используя методы объекта или используя стандартный синтаксис индексации массива (т. е. помеченный квадратными скобками).

если правильноUint8ClampedArrayЗаинтересованные, вы можете изучить дальше асинхронно здесьUint8ClampedArray.

Вы нашли что-то? Является ли 0~255 общим значением, значением, соответствующим шестнадцатеричному значению цвета. Хорошо, тогда следующий шаг — реализовать его в соответствии с тем, что мы подумали, и посмотреть, соответствует ли он такому принципу.video响应事件执行结果2.png

Код реализован, а как насчет результатов? Я использую белые картинки, прозрачные картинки и черные картинки для сравнения результатов. Соответствует ли результат тому, что мы себе представляли: Сначала давайте посмотрим на прозрачное изображение:Xnip20200901_194504.pngКак видите, в результирующем массиве все равно 0;

Белая картинка:Xnip20200901_194615.pngОй, это все 255, так что черный должен быть 0, не волнуйтесь, давайте посмотрим

Черное изображение:Xnip20200901_194728.png

Появилось неожиданное число 238, что является значением цвета, смещенным в сторону белого 255. Почему это происходит? На самом деле это потому, что белый и прозрачный цвета не избыточны, а черный избыточен. Эта проблема возникает, когда холст рисуется. , но может быть проигнорировано.

Я знаю цветное значение этих трех, то следующее суждение также хорошо, просто добавить условие.xxxx.png

Почему 200 и 0? На самом деле, вы можете судить разумное диапазон этих двух значений в соответствии с фактической ситуацией. Значение цвета, соответствующее 200, представляет собой # C8C8C8, который является серым, а 0 - прозрачный цвет, поэтому он оценивается недействительным Изображение здесь. Пока нет значения в массиве BRR, это означает, что это неверное изображение.

Так какова реальная ситуация? Вот реальная сравнительная таблица:Xnip20200901_200227.png

Видно, что в брр есть ценность, и ее все еще много, так что эта положительная картина — верная картина.

4. Наконец

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

4. Резюме

JavaScript перехватывает первый кадр видео, процесс сложный, и он включает в себя большое количество циклов данных, что приведет к некоторому увеличению объема памяти, но он действительно может решить эту проблему, и он был использован в корпоративных данных. , который использует трюк.Метод оптимизации заключается в прямом разрыве, если в него вставлено только одно значение массива brr, что может значительно оптимизировать производительность.Если у вас есть лучшее решение, поделитесь с нами!

5. Ссылка

Видеосъемка первого кадра

wasm + ffmpeg для захвата видео

MDN Uint8ClampedArray