Веб-разработчики всегда хотели использовать аудио и видео в Интернете, но раньше традиционные веб-технологии не могли встраивать аудио и видео в сеть, поэтому некоторые запатентованные технологии, такие как Flash и Silverlight, стали очень популярными.
Эти технологии работают хорошо, но имеют ряд проблем, включая плохую поддержку функций HTML/CSS, проблемы с безопасностью и проблемы с осуществимостью.
К счастью, когда стандарт HTML5 был опубликован, он содержал много новых функций, в том числе<video>
а также<audio>
теги и некоторые API-интерфейсы JavaScript для управления им. С непрерывным развитием коммуникационных и сетевых технологий аудио и видео стали неотъемлемой частью жизни каждого человека. Кроме того, с постепенной популяризацией технологии 5G появится больше простора для фантазии в области аудио и видео в реальном времени.
Далее эта статья начнется с восьми аспектов и позволит вам всесторонне изучить интерфейсные видеоплееры и основные технологии потокового мультимедиа. Прочитав эту статью, вы будете знать следующее:
- Почему исходный адрес видео элемента Video на некоторых веб-страницах представлен в виде URL-адреса BLOB-объекта;
- Что такое запрос диапазона HTTP и связанные с ним концепции технологии потокового мультимедиа;
- Понимать концепцию HLS, DASH, технологии потоковой передачи с адаптивной скоростью передачи данных и технологии шифрования потокового мультимедиа;
- Понимать структуру файла FLV, функциональные характеристики и ограничения использования flv.js и внутренний принцип работы;
- Понимание MSE (Media Source Extensions) API и связанного с ним использования;
- Понимать принцип видеоплеера, формат пакета мультимедиа и разницу между форматом пакета MP4 и Fragmented MP4;
напоследок"Апо есть что сказать"На этом занятии брат Абао расскажет, как делать снимки экрана проигрывателя, как создавать GIF-файлы на основе снимков экрана, как использовать Canvas для воспроизведения видео, а также как реализовать хроматический ключ и другие функции.
Прочитайте последние популярные статьи брата А Бао (спасибо за вашу поддержку и поддержку 🌹🌹🌹):
- [13 000 слов] Играйте с интерфейсным двоичным кодом(328+ 👍)
- Как работать с документами Word во внешнем интерфейсе(225+ 👍)
- 1.2W Words | Удивительное вводное руководство по TypeScript(1348+ 👍)
- 10 лучших проектов TS, которые ослепляют ваши глаза(699+ 👍)
- Одна статья для понимания дженериков и приложений TypeScript (7,8 тыс. слов)(581+ 👍)
- Не беспокойтесь об обработке изображений, я дам вам десять маленьких помощников.(485+ 👍)
1. Традиционный режим воспроизведения
Большинство веб-разработчиков<video>
знакомы, в следующем HTML-фрагменте мы объявляем<video>
элемент и установите соответствующие атрибуты, затем передайте<source>
Вкладка для установки источника видео и формата видео:
<video id="mse" autoplay=true playsinline controls="controls">
<source src="https://h5player.bytedance.com/video/mp4/xgplayer-demo-720p.mp4" type="video/mp4">
你的浏览器不支持Video标签
</video>
После того, как приведенный выше код будет обработан браузером, на странице отобразится видеоплеер, как показано на следующем рисунке:
(Источник изображения: https://h5player.bytedance.com/examples/)
С помощью инструментов разработчика Chrome мы можем узнать, когда воспроизведение"xgplayer-demo-720p.mp4"видеофайл, было сделано 3 HTTP-запроса:
Кроме того, из рисунка видно, что коды состояния первых двух ответов HTTP-запроса"206". Здесь мы анализируем заголовки запроса и ответа первого HTTP-запроса:
В заголовке запроса выше естьrange: bytes=0-
Информация заголовка, которая используется для определения того, поддерживает ли сервер запросы Range. если присутствует в ответеAccept-Ranges
заголовок (и его значение не "none"), то сервер поддерживает запросы диапазона.
В заголовке ответа выше,Accept-Ranges: bytes
Единицей для ограничения диапазона являетсяbytes
. здесьContent-Length
Также достоверная информация, поскольку она дает полный размер видео для загрузки.
1.1 Запрос определенного диапазона с сервера
Если сервер поддерживает запросы диапазона, вы можете использовать заголовок диапазона для создания таких запросов. Этот заголовок указывает, какую часть или части файла должен вернуть сервер.
1.1.1 Единая область применения
Мы можем запросить определенную часть ресурса. Здесь мы используемVisual Studio CodeсерединаREST Clientрасширение для тестирования, в этом примере мы используем заголовок Range для запросаwww.example.comПервые 1024 байта домашней страницы.
Для использованияREST Clientинициированный"запрос одного диапазона", сервер вернет код состояния как"206 Partial Content"ответ на. в то время как заголовок ответа"Content-Length"Заголовок теперь используется для указания размера ранее запрошенного диапазона (а не размера всего файла)."Content-Range"Заголовок ответа указывает на расположение этой части контента во всем ресурсе.
1.1.2 Несколько областей применения
Заголовок Range также поддерживает одновременный запрос нескольких частей документа. Диапазоны запросов разделяются запятой. Например:
$ curl http://www.example.com -i -H "Range: bytes=0-50, 100-150"
На этот запрос возвращается следующая информация ответа:
Поскольку мы запрашиваем несколько частей документа, каждая часть будет иметь свой собственный"Content-Type"а также"Content-Range"информацию и используйте параметр границы для разделения тела ответа.
1.1.3 Запросы условного диапазона
При перезапуске для запроса дополнительных фрагментов ресурсов необходимо убедиться, что ресурс не был изменен с момента получения последнего фрагмента.
"If-Range"Заголовок запроса можно использовать для генерации запроса условного диапазона: если условие выполнено, условный запрос вступит в силу, и сервер вернет ответ с кодом состояния 206 Partial и соответствующим телом сообщения. Если условие не выполняется, возвращается код состояния"200 OK", возвращая при этом весь ресурс. Этот заголовок можно комбинировать с"Last-Modified"валидатор или"ETag"использоваться вместе, но не оба одновременно.
1.1.4 Ответы на запросы диапазона
Есть три состояния, связанные с запросами диапазона:
- В случае успешного выполнения запроса сервер вернет"206 Partial Content"код состояния.
- В случае, когда запрошенный диапазон выходит за пределы (значение диапазона превышает размер ресурса), сервер вернет"416 Requested Range Not Satisfiable"(Запрошенный диапазон не может быть удовлетворен) Код состояния.
- В случаях, когда запросы диапазона не поддерживаются, сервер возвращает"200 OK"код состояния.
Что касается оставшихся двух просьб, брат Абао не будет подробно разбирать их. Заинтересованные друзья, вы можете использовать инструменты разработчика Chrome для просмотра конкретного сообщения запроса.
Из 3-го запроса мы можем узнать, что размер всего видео составляет около 7,9 МБ. Если воспроизводимый видеофайл слишком велик или сеть нестабильна, воспроизведение займет много времени, что серьезно ухудшит работу пользователя.
Итак, как решить эту проблему? Чтобы решить эту проблему, мы можем использовать технологию потокового мультимедиа, а затем мы представим потоковое мультимедиа.
2. Потоковое мультимедиа
Потоковое мультимедиа относится к сжатию серии мультимедийных данных, передает данные через онлайн-сегментацию, мгновенно передает аудио и видео онлайн для просмотра, что позволяет отправлять пакет данных как поток; если эта технология не используется, вы должны загрузить весь медиафайл перед использованием.
Потоковое мультимедиа фактически относится к новому методу передачи мультимедиа, включая звуковой поток, видеопоток, текстовый поток, поток изображения, поток анимации и т. д., а не к новому мультимедиа. Основной технической особенностью потокового мультимедиа является потоковая передача, которая позволяет передавать данные как поток. Потоковая передача — это общий термин для технологии доставки мультимедиа по сети. Существует два основных способа реализации потоковой передачи: последовательная потоковая передача (Progressive Streaming) и потоковая передача в реальном времени (Real Time Streaming).
Общие протоколы потокового мультимедиа в текущей сети:
Как видно из приведенной выше таблицы, разные протоколы имеют разные преимущества и недостатки. В процессе реального использования мы обычно выбираем оптимальный протокол передачи потокового мультимедиа при условии, что платформа совместима. Например, для прямой трансляции в браузере хорошо использовать протокол HTTP-FLV, производительность выше, чем у RTMP+Flash, а задержка может быть такой же или лучше, чем у RTMP+Flash.
Из-за большой задержки HLS, как правило, подходит только для сценариев видео по запросу, однако, поскольку он имеет хорошую совместимость с мобильным терминалом, его также можно использовать в сценариях прямого вещания при условии принятия высокой задержки.
Говоря об этом, я думаю, некоторым друзьям будет любопытно, в чем интуитивно понятная разница между использованием технологии потокового мультимедиа и традиционным режимом воспроизведения для элемента «Видео». Давайте возьмем в качестве примера распространенный протокол потоковой передачи HLS, чтобы кратко сравнить различия между ними.
Глядя на приведенный выше рисунок, мы ясно видим, что при использовании сетевого транспортного протокола потоковой передачи HLS,<video>
элементsrc
свойство используетblob://
протокол. Говоря об этом протоколе, мы должны поговорить о BLOB-объектах и URL-адресах BLOB-объектов.
2.1 Blob
Blob (Binary Large Object) представляет собой большой объект двоичного типа. В системе управления базами данных двоичные данные хранятся как набор одного объекта. Блобы обычно представляют собой изображения, звуковые или мультимедийные файлы."Он представляет собой исходный файл данных, аналогичный неизменяемым объектам в теме в виде JavaScript Blob."
Blob
опциональной строкойtype
(обычно тип MIME) иblobParts
сочинение:
❝MIME (многоцелевые расширения почты Интернета) — это тип многоцелевого расширения почты Интернета, который представляет собой способ установить файл с определенным расширением для открытия приложением.При доступе к файлу расширения браузер будет автоматически использовать указанный расширение приложение для открытия. В основном он используется для указания некоторых определяемых клиентом имен файлов, а также некоторых методов открытия медиафайлов.
Общие типы MIME: язык гипертекстовой разметки text .html text/html, изображение PNG .png image/png, обычный текст .txt text/plain и т. д.
❞
Чтобы более интуитивно чувствовать объект Blob, давайте сначала воспользуемся конструктором Blob для создания объекта myBlob, как показано на следующем рисунке:
Как видите, объект myBlob имеет два свойства: размер и тип. вsize
атрибут используется для представления размера данных в байтах,type
является строкой типа MIME. Большие двоичные объекты не обязательно представляют данные в собственном формате JavaScript. НапримерFile
интерфейс на основеBlob
, который наследует функциональные возможности BLOB-объектов и расширяет их для поддержки файлов в системе пользователя.
2.2 Blob URL/Object URL
URL-адрес BLOB URL / Object - это псевдо- протокол, который позволяет BLOB и файловые объекты, которые будут использоваться в качестве источников URL для изображений, ссылки для загрузки двоичных данных и многое другое. В браузере мы используемURL.createObjectURL
метод создания URL-адреса BLOB-объекта, который принимаетBlob
объекта и создать для него уникальный URL видаblob:<origin>/<uuid>
, соответствующий пример выглядит следующим образом:
blob:https://example.org/40a5fb5a-d56d-4a33-b4e2-0acf6a8e5f641
Внутри браузера для каждого проходаURL.createObjectURL
Сгенерированный URL-адрес сохраняет URL-адрес → Карта BLOB-объектов. Поэтому такие URL короче, но к ним можно получить доступBlob
. Сгенерированный URL-адрес действителен только в том случае, если текущий документ открыт. Но если вы посетите URL-адрес большого двоичного объекта, который больше не существует, вы получите ошибку 404 в своем браузере.
Вышеуказанный URL-адрес кажется очень хорошим, но на самом деле он имеет побочные эффекты. Хотя URL → Картина BLOB хранится, сам BLOB все еще находится в памяти, и браузер не может его отпустить. Отображение автоматически очищается при удалении документа, поэтому объект Blob затем выделяется. Однако, если приложение длинное, это не произойдет очень быстро. Следовательно, если мы создадим URL-адрес BLOB, даже если он больше не нужен, оно будет существовать в памяти.
Для этой проблемы мы можем вызватьURL.revokeObjectURL(url)
удаляет ссылку из внутренней карты, позволяя удалить большой двоичный объект, если нет других ссылок, и освобождает память.
2.3 Blob vs ArrayBuffer
На самом деле, в передней части, кроме"Объект большого двоичного объекта"Кроме того, вы также можете столкнуться"Объект ArrayBuffer". Он используется для представления универсального буфера фиксированной длины необработанных двоичных данных. Вы не можете управлять содержимым ArrayBuffer напрямую, вместо этого вам нужно создать объект TypedArray или объект DataView, представляющий буфер в определенном формате, и использовать этот объект для чтения и записи содержимого буфера.
Объекты Blob и объекты ArrayBuffer имеют свои особенности. Различия между ними заключаются в следующем:
- Если вам не нужно использовать возможности записи/редактирования, предоставляемые ArrayBuffer, формат Blob, вероятно, является лучшим.
- Объекты BLOB-объектов являются неизменяемыми, а ArrayBuffers можно манипулировать с помощью TypedArrays или DataViews.
- ArrayBuffer хранится в памяти, и им можно манипулировать напрямую. Принимая во внимание, что большие двоичные объекты могут находиться на диске, в кэш-памяти и в других местах, которые недоступны.
- Хотя BLOB-объекты можно передавать напрямую в качестве аргументов другим функциям, например
window.URL.createObjectURL()
. Однако для работы с большими двоичными объектами вам по-прежнему могут понадобиться файловые API, такие как FileReader. - Объекты Blob и ArrayBuffer можно преобразовать друг в друга:
- Использование FileReader
readAsArrayBuffer()
метод, который может преобразовать объект Blob в объект ArrayBuffer; - Используйте конструктор Blob, например
new Blob([new Uint8Array(data]);
, вы можете преобразовать объект ArrayBuffer в объект Blob.
- Использование FileReader
Во внешних сценариях AJAX, в дополнение к общему формату JSON, мы также можем использовать объекты Blob или ArrayBuffer:
function GET(url, callback) {
let xhr = new XMLHttpRequest();
xhr.open('GET', url, true);
xhr.responseType = 'arraybuffer'; // or xhr.responseType = "blob";
xhr.send();
xhr.onload = function(e) {
if (xhr.status != 200) {
alert("Unexpected status code " + xhr.status + " for " + url);
return false;
}
callback(new Uint8Array(xhr.response)); // or new Blob([xhr.response]);
};
}
В приведенном выше примере, задав разные типы данных для xhr.responseType, мы можем получить соответствующий тип данных в соответствии с фактическими потребностями. После представления вышеуказанного контента давайте сначала представим протокол потоковой передачи мультимедиа HLS, который широко используется в настоящее время.
3. ЗОЖ
3.1 Введение в HLS
HTTP Live Streaming (сокращенно HLS) — это основанный на HTTP протокол сетевой передачи потокового мультимедиа, предложенный Apple, который является частью программных систем Apple QuickTime X и iPhone. Он работает, разделяя весь поток на небольшие файлы на основе HTTP для загрузки по несколько за раз. Во время воспроизведения медиапотока клиент может выбрать загрузку одного и того же ресурса с разной скоростью из множества различных альтернативных источников, позволяя сеансу потоковой передачи адаптироваться к разным скоростям передачи данных.
Кроме того, когда уровень сигнала пользователя колеблется, видеопоток динамически настраивается для обеспечения превосходного воспроизведения.
(Источник изображения: https://www.wowza.com/blog/hls-streaming-protocol)
Изначально HLS поддерживался только на iOS. Но сейчас HLS — проприетарный формат, и почти все устройства его поддерживают. Как следует из названия, протокол HLS (HTTP Live Streaming) доставляет видеоконтент через стандартный веб-сервер HTTP. Это означает, что вам не нужно интегрировать какую-либо специальную инфраструктуру для распространения содержимого HLS.
HLS имеет следующие особенности:
- HLS будет воспроизводить видео, закодированные с помощью кодеков H.264 или HEVC/H.265.
- HLS будет воспроизводить звук, закодированный с помощью кодеков AAC или MP3.
- Видеопотоки HLS обычно нарезаются на 10-секундные сегменты.
- Транспортный формат/инкапсуляция HLS — MPEG-2 TS.
- HLS поддерживает DRM (управление цифровыми правами).
- HLS поддерживает различные рекламные стандарты, такие как VAST и VPAID.
Почему Apple предложила протокол HLS, на самом деле, это в основном решение некоторых проблем, существующих в протоколе RTMP. Например, протокол RTMP не использует стандартный HTTP-интерфейс для передачи данных, поэтому он может быть заблокирован брандмауэрами в некоторых особых сетевых средах. Однако, поскольку HLS использует протокол HTTP для передачи данных, он обычно не блокируется брандмауэрами. Кроме того, также легко передавать мультимедиа через CDN (сеть доставки контента).
3.2 Адаптивный битовый поток HLS
HLS — это протокол потоковой передачи с адаптивным битрейтом. Таким образом, потоковая передача HLS может динамически адаптировать разрешение видео к условиям сети каждого пользователя. Если вы используете высокоскоростной Wi-Fi, вы можете транслировать HD-видео на свой телефон. Однако, если вы находитесь в автобусе или метро с ограниченным подключением к данным, вы можете смотреть то же видео с более низким разрешением.
При запуске сеанса потоковой передачи клиент загружает файл расширенного списка воспроизведения M3U (m3u8), содержащий метаданные, для поиска доступных медиапотоков.
(Источник изображения: https://www.wowza.com/blog/hls-streaming-protocol)
Для простоты понимания мы используемhls.jsЭтот реализованный на JavaScript клиент HLS, предоставленныйОнлайн-пример, взгляните на конкретный файл m3u8.
#EXTM3U
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=2149280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=1280x720,NAME="720"
url_0/193039199_mp4_h264_aac_hd_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=246440,CODECS="mp4a.40.5,avc1.42000d",RESOLUTION=320x184,NAME="240"
url_2/193039199_mp4_h264_aac_ld_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=460560,CODECS="mp4a.40.5,avc1.420016",RESOLUTION=512x288,NAME="380"
url_4/193039199_mp4_h264_aac_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=836280,CODECS="mp4a.40.2,avc1.64001f",RESOLUTION=848x480,NAME="480"
url_6/193039199_mp4_h264_aac_hq_7.m3u8
#EXT-X-STREAM-INF:PROGRAM-ID=1,BANDWIDTH=6221600,CODECS="mp4a.40.2,avc1.640028",RESOLUTION=1920x1080,NAME="1080"
url_8/193039199_mp4_h264_aac_fhd_7.m3u8
Наблюдая за файлом m3u8, соответствующим основному списку воспроизведения, мы можем узнать, что видео поддерживает следующие 5 различных разрешений:
- 1920x1080 (1080P)
- 1280x720 (720P)
- 848x480 (480P)
- 512x288
- 320x184
Списки воспроизведения мультимедиа, соответствующие видео с разным разрешением, будут определены в соответствующих файлах m3u8. Здесь мы берем видео 720P в качестве примера для просмотра соответствующего файла m3u8:
#EXTM3U
#EXT-X-VERSION:3
#EXT-X-PLAYLIST-TYPE:VOD
#EXT-X-TARGETDURATION:11
#EXTINF:10.000,
url_462/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_463/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
url_464/193039199_mp4_h264_aac_hd_7.ts
#EXTINF:10.000,
...
url_525/193039199_mp4_h264_aac_hd_7.ts
#EXT-X-ENDLIST
Когда пользователь выбирает видео определенного разрешения, будет загружен список воспроизведения мультимедиа (файл m3u8), соответствующий определению, и информация о каждом клипе будет указана в списке. Форматом передачи/инкапсуляции HLS является MPEG-2 TS (MPEG-2 Transport Stream), который является стандартным форматом для передачи и хранения различных данных, включая видео, аудио и протоколы связи, и используется в системах цифрового телевизионного вещания, таких как DVB, ATSC, IPTV и др.
"Следует отметить, что с помощью некоторых готовых инструментов мы можем объединить несколько файлов TS в видеофайлы формата mp4."Если вы хотите защитить авторские права на видео, мы можем рассмотреть возможность использования алгоритма симметричного шифрования, такого как AES-128, для симметричного шифрования фрагмента. Когда клиент играет, он сначала получает симметричный ключ шифрования в соответствии с адресом сервера ключей, настроенным в файле m3u8, а затем загружает осколки.После того, как осколки загружены, они используют соответствующий алгоритм симметричного шифрования для расшифровки и воспроизведения.
Друзья, которые заинтересованы в описанном выше процессе, могут обратиться к Github.video-hls-encryptЭтот проект, этот проект представляет решение для шифрования видео на основе протокола потокового мультимедиа HLS на простом языке и предоставляет полный пример кода.
(Источник изображения: https://github.com/hauk0101/video-hls-encrypt)
После представления технологии HLS (HTTP Live Streaming), запущенной Apple, давайте представим еще одну динамическую адаптивную потоковую передачу на основе HTTP — DASH.
4. ДЭШ
4.1 Введение в DASH
"Dynamic Adaptive Streaming over HTTP (англ. Dynamic Adaptive Streaming over HTTP, сокращенно DASH, также известная как MPEG-DASH) — это технология потоковой передачи с адаптивным битрейтом, которая позволяет передавать высококачественные потоковые медиаданные через Интернет через традиционные веб-серверы HTTP."Подобно схеме HTTP Live Streaming (HLS) Apple, MPEG-DASH разбивает контент на серию небольших фрагментов файлов на основе HTTP, каждый из которых содержит короткий фрагмент воспроизводимого контента, который может длиться в общей сложности несколько часов.
Контент будет разделен на сегменты с альтернативными битрейтами, чтобы предоставить версии с несколькими битрейтами для выбора. Когда контент воспроизводится клиентом MPEG-DASH, клиент автоматически выбирает альтернативу для загрузки и воспроизведения в зависимости от текущих сетевых условий. Клиент будет выбирать клипы с самым высоким битрейтом, которые могут быть загружены вовремя для воспроизведения, что позволяет избежать заиканий или повторной буферизации событий. Благодаря этому клиенты MPEG-DASH могут легко адаптироваться к изменяющимся условиям сети и обеспечивать высококачественное воспроизведение с меньшими задержками и повторной буферизацией.
MPEG-DASH — это первое решение для потоковой передачи с адаптивным битрейтом на основе HTTP и международный стандарт. MPEG-DASH не следует путать с транспортным протоколом — MPEG-DASH использует транспортный протокол TCP."В отличие от HLS, HDS и Smooth Streaming, DASH не заботится о кодеках, поэтому может принимать контент, закодированный в любом формате кодирования, таком как H.265, H.264, VP9 и т. д."
Хотя HTML5 напрямую не поддерживает MPEG-DASH, существуют некоторые реализации MPEG-DASH на JavaScript, которые позволяют использовать MPEG-DASH в веб-браузерах через расширения HTML5 Media Source Extensions (MSE). Существуют и другие реализации JavaScript, такие как проигрыватель bitdash, который поддерживает воспроизведение MPEG-DASH с DRM с использованием расширения мультимедиа с шифрованием HTML5. В сочетании с WebGL потоковая передача с адаптивным битрейтом на основе MPEG-DASH HTML5 также обеспечивает эффективную потоковую передачу 360-градусного видео в реальном времени и по требованию.
4.2 Важные концепции DASH
- MPD: файл описания (манифест) медиафайла, который действует как файл m3u8 HLS.
- Представление: соответствует необязательному выходу (альтернативному). Например, видео 480p, видео 720p, аудио сэмпла 44100 и т. д. описываются с помощью представления.
- Сегмент: каждое представление разделено на несколько сегментов. Сегменты разделены на 4 категории, из которых наиболее важными являются: Сегмент инициализации (каждое Представление содержит 1 Сегмент инициализации), Сегмент мультимедиа (медиаконтент каждого Представления содержит несколько сегментов Медиа).
(Источник изображения: https://blog.csdn.net/yue_huang/article/details/78466537)
одомашненныйBilibiliЯ начал использовать технологию DASH в 2018 году, поэтому я выбрал технологию DASH. Заинтересованные друзья могут прочитатьПочему мы используем DASHЭта статья.
Поговорите так много, я считаю, что какой-то маленький партнер любопытный файл MPD выглядит? Здесь мы посмотрим на пример примерной арбуз видеоплеерMPDдокумент:
<?xml version="1.0"?>
<!-- MPD file Generated with GPAC version 0.7.2-DEV-rev559-g61a50f45-master at 2018-06-11T11:40:23.972Z-->
<MPD xmlns="urn:mpeg:dash:schema:mpd:2011" minBufferTime="PT1.500S" type="static" mediaPresentationDuration="PT0H1M30.080S" maxSegmentDuration="PT0H0M1.000S" profiles="urn:mpeg:dash:profile:full:2011">
<ProgramInformation moreInformationURL="http://gpac.io">
<Title>xgplayer-demo_dash.mpd generated by GPAC</Title>
</ProgramInformation>
<Period duration="PT0H1M30.080S">
<AdaptationSet segmentAlignment="true" maxWidth="1280" maxHeight="720" maxFrameRate="25" par="16:9" lang="eng">
<ContentComponent id="1" contentType="audio" />
<ContentComponent id="2" contentType="video" />
<Representation id="1" mimeType="video/mp4" codecs="mp4a.40.2,avc3.4D4020" width="1280" height="720" frameRate="25" sar="1:1" startWithSAP="0" bandwidth="6046495">
<AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"/>
<BaseURL>xgplayer-demo_dashinit.mp4</BaseURL>
<SegmentList timescale="1000" duration="1000">
<Initialization range="0-1256"/>
<SegmentURL mediaRange="1257-1006330" indexRange="1257-1300"/>
<SegmentURL mediaRange="1006331-1909476" indexRange="1006331-1006374"/>
...
<SegmentURL mediaRange="68082016-68083543" indexRange="68082016-68082059"/>
</SegmentList>
</Representation>
</AdaptationSet>
</Period>
</MPD>
(Источник файла: https://h5player.bytedance.com/examples/)
При воспроизведении видео арбузный видеоплеер автоматически запрашивает воспроизведение соответствующего сегмента в соответствии с файлом MPD.
Мы упоминали ранееBilibili, а потом я должен упомянуть известный проект с открытым исходным кодом его открытого исходного кода -flv.js, но прежде чем представить его, нам нужно понять формат потоковой передачи FLV.
5. FLV
5.1 Структура файла FLV
FLV — это аббревиатура от FLASH Video, а формат потокового мультимедиа FLV — это формат видео, разработанный с появлением Flash MX. Благодаря чрезвычайно маленькому размеру файла и чрезвычайно высокой скорости загрузки он позволяет просматривать видеофайлы в Интернете.Его внешний вид эффективно решает проблему, заключающуюся в том, что после импорта видеофайла во Flash экспортируемый SWF-файл становится громоздким и не может быть хорошо используется в Интернете.И другие вопросы.
Файл FLV состоит из двух частей: заголовка FLV и тела FLV, а тело FLV состоит из ряда тегов:
5.1.1 Заголовочный файл FLV
Заголовочный файл FLV: (9 байт)
- 1-3: Первые 3 байта — это идентификатор формата файла (FLV 0x46 0x4C 0x56).
- 4-4: 4-й байт — это версия (0x01).
- 5-5: Первые 5 бит 5-го байта зарезервированы и должны быть равны 0.
- 6-й бит 5-го байта — это флаг типа аудио (TypeFlagsAudio).
- 7-й бит 5-го байта также зарезервирован и должен быть равен 0.
- 8-битный флаг типа видео (TypeFlagsVideo) из 5-го байта.
- 6-9: Четыре байта 6-9 все еще зарезервированы, и его данные равны 00000009.
- Длина всего заголовка файла обычно равна 9 (3+1+1+4).
5.1.2 Базовый формат тегов
информация о типе тега, фиксированная длина 15 байт:
- 1-4: Длина предыдущего тега (4 байта), первый тег равен 0.
- 5-5: тип тега (1 байт); 0x8 аудио; 0x9 видео; 0x12 данные сценария.
- 6-8: Размер содержимого тега (3 байта).
- 9-11: Отметка времени (3 байта, миллисекунды) (всегда 0 для первого тега, 0, если это тег скрипта).
- 12-12: Расширение метки времени (1 байт) делает метку времени равной 4 байтам (для хранения более длинной информации о времени FLV), и этот байт используется как старший бит метки времени.
Во время воспроизведения FLV порядок воспроизведения соответствует временным меткам тегов. Любая установка формата данных, добавленная в файл, будет игнорироваться.
- 13-15: streamID (3 байта) всегда равен 0.
Подробная структурная схема формата FLV показана на следующем рисунке:
HTML5 в браузере<video>
Не поддерживает прямое воспроизведение видеоформата FLV, необходимо использоватьflv.jsЭта библиотека с открытым исходным кодом реализует функцию воспроизведения видео формата FLV.
5.2 Введение в flv.js
flv.jsЭто проигрыватель HTML5 Flash Video (FLV), написанный на чистом JavaScript, основанный на базовомMedia Source Extensions. В процессе фактической работы он автоматически анализирует файл формата FLV и передает собственный тег HTML5 Video для воспроизведения аудио- и видеоданных, что позволяет браузеру воспроизводить FLV без Flash.
5.2.1 Возможности flv.js
- Поддержка воспроизведения FLV-файлов в формате H.264 + AAC/MP3;
- Поддерживает воспроизведение нескольких сегментированных видео;
- Поддерживает воспроизведение прямых потоков HTTP FLV с малой задержкой;
- Поддержка воспроизведения потока FLV в реальном времени на основе передачи WebSocket;
- Совместимость с Chrome, FireFox, Safari 10, IE11 и Edge;
- Очень низкие накладные расходы, поддерживает аппаратное ускорение браузера.
5.2.2 Ограничения flv.js
- Аудиокодек MP3 не работает в IE11/Edge;
- Прямая трансляция HTTP FLV поддерживается не всеми браузерами.
5.2.3 Использование flv.js
<script src="flv.min.js"></script>
<video id="videoElement"></video>
<script>
if (flvjs.isSupported()) {
var videoElement = document.getElementById('videoElement');
var flvPlayer = flvjs.createPlayer({
type: 'flv',
url: 'http://example.com/flv/video.flv'
});
flvPlayer.attachMediaElement(videoElement);
flvPlayer.load();
flvPlayer.play();
}
</script>
5.3 Как работает flv.js
Works flv.js - это FLV File Stream преобразуется в фрагменты ISO BMFF (фрагментированный MP4), затем через расширения исходных средств массовой информации API MP4 сегмент будет подавать HTML5<video>
элемент. Архитектура дизайна flv.js показана ниже:
(Источник изображения: https://github.com/bilibili/flv.js/blob/master/docs/design.md)
Связанныйflv.jsДля более подробного ознакомления с принципом работы, интересующиеся могут прочитатьИнтерактивный потоковый медиаплеер в реальном времени проекта с открытым исходным кодом перецЭта статья. Теперь, когда мы представилиhls.jsа такжеflv.jsЭти два основных решения для потокового мультимедиа, на самом деле, их успех неотделим от молчаливой поддержки закулисного героя Media Source Extensions. Поэтому далее брат Абао расскажет вам о MSE (расширения источника мультимедиа).
6. МСЭ
6.1 MSE API
API Media Source Extensions (Media Source Extensions) предоставляет функциональные возможности для реализации потокового мультимедиа через Интернет без подключаемых модулей. Используя MSE, медиапотоки могут быть созданы с помощью JavaScript и могут быть созданы с помощьюaudio
а такжеvideo
элемент для игры.
Уже несколько лет мы можем воспроизводить видео и аудио в веб-приложениях без плагинов. Однако существующая архитектура слишком проста и может удовлетворить потребности только в воспроизведении всей дорожки за один раз и не может обеспечить разделение/объединение нескольких буферных файлов. Ранние потоковые медиа в основном использовали Flash для сервисов и медиа-серверы Flash для потоковой передачи видео по протоколу RTMP.
С реализацией Media Source Extensions (MSE) все обстоит иначе. MSE позволяет нам конвертировать обычный одиночный медиафайлsrc
Замените значение ссылкойMediaSource
объект (контейнер, содержащий такую информацию, как состояние готовности медиафайла для воспроизведения) и ссылки на несколькоSourceBuffer
Объекты (элементы, которые представляют несколько отдельных фрагментов мультимедиа, составляющих весь поток).
Для простоты понимания давайте взглянем на основной поток данных MSE:
MSE позволяет нам иметь более точный контроль на основе размера и частоты выборки контента или сведений об объеме памяти, таких как время восстановления кэша. Это основа для создания клиентов потоковой передачи с адаптивным битрейтом, таких как клиенты DASH или HLS, на основе расширяемого API.
Создание MSE-совместимых носителей в современных браузерах требует много времени, трудозатрат и потребляет много компьютерных ресурсов и энергии. Кроме того, необходимо использовать внешнюю утилиту для преобразования содержимого в подходящий формат. Хотя браузеры поддерживают различные медиа-контейнеры, совместимые с MSE, форматы, использующие кодирование видео H.264, кодирование аудио AAC и контейнеры MP4, очень распространены, поэтому MSE должен быть совместим с этими основными форматами. Кроме того, MSE также предоставляет API для разработчиков, чтобы определить, поддерживаются ли контейнер и кодек во время выполнения.
6.2 Интерфейс MediaSource
MediaSource — это интерфейс API расширений источников мультимедиа для представления объектов HTMLMediaElement медиаресурсов. Объект MediaSource можно прикрепить к HTMLMediaElement для воспроизведения на стороне клиента. Прежде чем представить интерфейс MediaSource, давайте взглянем на его структурную схему:
(Источник изображения - https://www.w3.org/TR/media-source/)
Чтобы понять структуру MediaSource, мы должны сначала представить основной процесс воспроизведения видеопотока клиентским аудио- и видеоплеером:
Получить потоковое мультимедиа -> депротокол -> деинкапсуляция -> декодирование аудио и видео -> воспроизведение аудио и рендеринг видео (необходима обработка синхронизации аудио и видео).
Поскольку собранные необработанные аудио- и видеоданные относительно велики, для облегчения передачи по сети мы обычно используем кодировщик, такой как обычный H.264 или AAC, для сжатия исходного мультимедийного сигнала. Наиболее распространенными мультимедийными сигналами являются видео, аудио и субтитры. Например, фильмы в повседневной жизни состоят из различных медиасигналов.В дополнение к движущимся изображениям большинство фильмов также содержат звук и субтитры.
Распространенными видеокодеками являются: H.264, HEVC, VP9 и AV1. И аудиокодеки: AAC, MP3 или Opus. Каждый медиасигнал имеет множество различных кодеков. Давайте возьмем демонстрацию видеоплеера «арбуз» в качестве примера, чтобы интуитивно понять звуковую дорожку, видеодорожку и дорожку субтитров:
Теперь давайте начнем представлять соответствующий контент интерфейса MediaSource.
6.2.1 Статус
enum ReadyState {
"closed", // 指示当前源未附加到媒体元素。
"open", // 源已经被媒体元素打开,数据即将被添加到SourceBuffer对象中
"ended" // 源仍附加到媒体元素,但endOfStream()已被调用。
};
6.2.2 Исключение завершения потока
enum EndOfStreamError {
"network", // 终止播放并发出网络错误信号。
"decode" // 终止播放并发出解码错误信号。
};
6.2.3 Конструкторы
[Constructor]
interface MediaSource : EventTarget {
readonly attribute SourceBufferList sourceBuffers;
readonly attribute SourceBufferList activeSourceBuffers;
readonly attribute ReadyState readyState;
attribute unrestricted double duration;
attribute EventHandler onsourceopen;
attribute EventHandler onsourceended;
attribute EventHandler onsourceclose;
SourceBuffer addSourceBuffer(DOMString type);
void removeSourceBuffer(SourceBuffer sourceBuffer);
void endOfStream(optional EndOfStreamError error);
void setLiveSeekableRange(double start, double end);
void clearLiveSeekableRange();
static boolean isTypeSupported(DOMString type);
};
6.2.4 Свойства
-
MediaSource.sourceBuffers
-- только для чтения: возвращает объект SourceBufferList, содержащий список объектов SourceBuffer для этого MediaSource. -
MediaSource.activeSourceBuffers
- Только для чтения: возвращает объект SourceBufferList, содержащий подмножество SourceBuffer этого объекта MediaSource.sourceBuffers, т. е. предоставляющий текущую выбранную видеодорожку (видеодорожку), включенную звуковую дорожку (аудиодорожки) и отображение/скрытие списка объектов для текстовых дорожек. -
MediaSource.readyState
-- только для чтения: возвращает коллекцию, содержащую текущее состояние MediaSource, даже если она в данный момент не присоединена к элементу мультимедиа (закрыта), или присоединена и готова к приему объекта SourceBuffer (открыта), или присоединена, но поток уже используется MediaSource.endOfStream() закрывается. -
MediaSource.duration
: Получает и задает продолжительность передаваемого в данный момент потокового мультимедиа. -
onsourceopen
: установите обработчик события, соответствующий событию sourceopen. -
onsourceended
: Установите обработчик событий, соответствующий исходному событию. -
onsourceclose
: установите обработчик события, соответствующий событию sourceclose.
6.2.5 Методы
-
MediaSource.addSourceBuffer()
: создает новый SourceBuffer с заданным типом MIME и добавляет его в список SourceBuffers MediaSource. -
MediaSource.removeSourceBuffer()
: удаляет указанный SourceBuffer из списка SourceBuffers в этом объекте MediaSource. -
MediaSource.endOfStream()
: указывает на конец потока.
6.2.6 Статические методы
-
MediaSource.isTypeSupported()
: возвращает логическое значение, указывающее, поддерживается ли данный тип MIME текущим браузером — это означает, что было возможно успешно создать объект SourceBuffer этого типа MIME.
6.2.7 Пример использования
var vidElement = document.querySelector('video');
if (window.MediaSource) { // (1)
var mediaSource = new MediaSource();
vidElement.src = URL.createObjectURL(mediaSource);
mediaSource.addEventListener('sourceopen', sourceOpen);
} else {
console.log("The Media Source Extensions API is not supported.")
}
function sourceOpen(e) {
URL.revokeObjectURL(vidElement.src);
var mime = 'video/mp4; codecs="avc1.42E01E, mp4a.40.2"';
var mediaSource = e.target;
var sourceBuffer = mediaSource.addSourceBuffer(mime); // (2)
var videoUrl = 'hello-mse.mp4';
fetch(videoUrl) // (3)
.then(function(response) {
return response.arrayBuffer();
})
.then(function(arrayBuffer) {
sourceBuffer.addEventListener('updateend', function(e) { (4)
if (!sourceBuffer.updating && mediaSource.readyState === 'open') {
mediaSource.endOfStream();
}
});
sourceBuffer.appendBuffer(arrayBuffer); // (5)
});
}
В приведенном выше примере описано, как использовать MSE API, давайте проанализируем основной рабочий процесс:
- (1) Определите, поддерживает ли текущая платформа API расширений источника мультимедиа, и если да, создайте объект MediaSource и привяжите обработчик события sourceopen.
- (2) Создает новый SourceBuffer с заданным типом MIME и добавляет его в список SourceBuffers MediaSource.
- (3) Загрузите видеопоток с удаленного сервера потоковой передачи и преобразуйте его в объект ArrayBuffer.
- (4) Добавьте обработчик события updateend в объект sourceBuffer, чтобы закрыть поток после передачи видеопотока.
- (5) Добавьте преобразованные данные видеопотока в формате ArrayBuffer в объект sourceBuffer.
Брат Абао только что кратко представил MSE API выше. Для тех, кто хочет узнать больше о его практическом применении, вы можете узнать о нем больше."hls.js"или"flv.js"проект. Далее Brother Abao представит формат мультимедийного контейнера на основе аудио и видео.
7. Формат инкапсуляции мультимедиа
Как правило, полный видеофайл состоит из аудио и видео. Распространенные файлы AVI, RMVB, MKV, ASF, WMV, MP4, 3GP, FLV и другие можно рассматривать только как формат пакета. H.264, HEVC, VP9 и AV1 — это форматы кодирования видео, а MP3, AAC и Opus — форматы кодирования аудио."Например, после инкапсулирования файла кодирования видео H.264 и файл кодирования аудио AAC в соответствии со стандартом инкапсуляции MP4, получен видеофайл с суффиксом MP4, который является нашим общим видеофайлом MP4."
Основной целью кодирования аудио и видео является сжатие объема исходных данных, а формат инкапсуляции (также известный как мультимедийный контейнер), такой как MP4, MKV, используется для хранения/передачи закодированных данных и организации аудио, видео, субтитры и другие данные по определенным правилам.В то же время он также будет содержать некоторую метаинформацию, например, какие типы кодирования, временные метки и т. д. содержатся в текущем потоке.Проигрыватель может сопоставлять декодер и синхронизировать аудио и видео согласно этой информации.
Чтобы лучше понять формат мультимедийного пакета, давайте рассмотрим принцип работы видеоплеера.
7.1 Принцип видеоплеера
Видеоплеер относится к программному обеспечению, которое может воспроизводить видео, хранящееся в виде цифровых сигналов, а также относится к электронным устройствам с функцией воспроизведения видео. Большинство видеоплееров (за исключением нескольких волновых файлов) содержат кодеки для восстановления сжатых медиафайлов, а видеоплееры также имеют набор встроенных алгоритмов преобразования частоты и буферизации. Большинство видеоплееров также поддерживают воспроизведение аудиофайлов.
Базовый поток обработки воспроизведения видео примерно включает следующие этапы:
(1) Соглашение о решении
Удалены из исходных данных сигнализации протокола передачи данных потока данных, оставляя только аудио- и видеоданные данные, такие как данные в протоколе передачи RTMP, протокол после формата выходных данных FLV решения.
(2) Декапсуляция
Раздельное аудио и видео сжатие кодирования данных, общие форматы пакетов MP4, MKV, RMVB, FLV, AVI этих форматов. Таким образом, сжатые и закодированные видео- и аудиоданные объединяются. Например, данные в формате FLV декапсулируются для вывода видеопотока в кодировке H.264 и аудиопотока в кодировке AAC.
(3) Декодирование
Видео, данные кодирования со сжатием звука, восстановление несжатого видео, необработанные аудиоданные, стандарты кодирования со сжатием звука включают AAC, MP3, AC-3 и т. д., стандарты кодирования со сжатием видео включают H.264, MPEG2, VC-1 и т. д. декодирование Получите несжатые цветовые видеоданные, такие как YUV420P, RGB, и несжатые аудиоданные, такие как PCM.
(4) Аудио и видео синхронизация
Отправьте синхронно декодированные аудио- и видеоданные на системную звуковую карту и графическую карту для воспроизведения.
После понимания принципа работы видеоплеера следующим шагом будет представление формата мультимедийного пакета.
7.2 Формат инкапсуляции мультимедиа
Для цифровых мультимедийных данных контейнер — это вещь, которая может хранить мультимедийные данные вместе, точно так же, как упаковочная коробка.Он может упаковывать аудио- и видеоданные и объединять две исходные независимые части мультимедийных данных в один. Конечно, также возможно хранить только один тип мультимедийных данных.
"Иногда мультимедийный контейнер также называют форматом инкапсуляции, он просто обеспечивает «оболочку» для закодированных мультимедийных данных, то есть все обработанные аудио, видео или субтитры упаковываются в файловый контейнер и представляются аудитории. упаковки называется упаковкой."Обычно используемые форматы пакетов: MP4, MOV, TS, FLV, MKV и т. д. Здесь мы представляем формат пакета MP4, с которым вы более знакомы.
7.2.1 Формат пакета MP4
MPEG-4 Part 14 (MP4) — один из наиболее часто используемых форматов контейнеров, обычно заканчивающийся файлом .mp4. Он используется для динамической адаптивной потоковой передачи через HTTP (DASH), а также может использоваться для потоковой передачи HLS от Apple. MP4 основан на базовом формате медиафайлов ISO (MPEG-4, часть 12), который основан на формате файлов QuickTime. MPEG расшифровывается как Группа экспертов по движущимся изображениям и является продуктом сотрудничества Международной организации по стандартизации (ISO) и Международной электротехнической комиссии (IEC). MPEG был создан, чтобы установить стандарт сжатия и передачи аудио и видео.
MP4 поддерживает различные кодеки, обычно используемые видеокодеки — H.264 и HEVC, а широко используемые аудиокодеки — AAC, преемник известного аудиокодека MP3.
MP4 состоит из набора блоков, и его наименьшая единица — блок. Все данные в файле MP4 установлены в блоке, то есть файл MP4 состоит из нескольких блоков, каждый блок имеет тип и длину, и блок можно понимать как блок объекта данных. Коробка может содержать другую коробку, которая называется коробкой-контейнером.
Файл MP4 будет иметь один и только одинftype
тип коробки, как признак формата MP4 и содержит некоторую информацию о файле, после чего будет один и только одинmoov
Тип бокса (кинобокс), это бокс-контейнер, их может быть несколько или нет, а структура медиаданных описывается метаданными.
Я полагаю, что у некоторых читателей возникнут вопросы: какова реальная структура файла MP4? используяmp4box.jsПредоставляя онлайн-сервисы, мы можем легко просмотреть внутреннюю структуру локальных или онлайн-файлов MP4:
❝Онлайн-адрес mp4box.js: https://gpac.github.io/mp4box.js/test/filereader.html
❞
Из-за сложной структуры файлов MP4 (пожалуйста, посмотрите на картинку ниже, если вы мне не верите), мы не будем продолжать здесь, а заинтересованные читатели могут самостоятельно прочитать соответствующие статьи.
Далее давайте представим формат контейнера Fragmented MP4.
7.2.2 Фрагментированный формат пакета MP4
Стандарт формата файлов MP4 ISO Base Media позволяет организовывать блоки фрагментированным образом, что означает, что файлы MP4 могут быть организованы в структуру, состоящую из серии коротких пар метаданных/блоков данных вместо одной длинной пары метаданных/данных. Структура файла Fragmented MP4 показана на рисунке ниже, который содержит только два фрагмента:
(Источник изображения — https://alexzambelli.com/blog/2009/02/10/smooth-streaming-architecture/)
В файле Fragmented MP4 есть три очень важных поля:moov
,moof
а такжеmdat
.
- moov (окно метаданных фильма): используется для хранения метаданных мультимедийного файла.
- mdat (поле мультимедийных данных): и обычные файлы MP4
mdat
То же самое, используется для хранения медиаданных, разница в том, что есть только один обычный файл MP4mdat
box и фрагментированные файлы MP4, каждый фрагмент будет иметьmdat
тип коробки. - moof (окно фрагмента фильма): используется для хранения метаинформации на уровне фрагмента. Этот тип поля не существует в обычных файлах MP4, но в файлах Fragmented MP4 каждый фрагмент будет иметь один
moof
тип коробки.
Фрагменты в файлах Fragmented MP4 создаютсяmoof
а такжеmdat
Он состоит из двух частей, каждый фрагмент может содержать звуковую дорожку или видеодорожку, а также содержит достаточно метаинформации для того, чтобы эту часть данных можно было декодировать отдельно. Структура Фрагмента показана на следующем рисунке:
(Источник изображения — https://alexzambelli.com/blog/2009/02/10/smooth-streaming-architecture/)
Точно так же, используя онлайн-сервис, предоставляемый mp4box.js, мы также можем четко просмотреть внутреннюю структуру файла Fragmented MP4:
Мы уже представили два формата контейнеров, MP4 и Fragmented MP4, и резюмируем основные различия между ними на диаграмме:
8. Брату А Бао есть что сказать
8.1 Как реализовать локальный предварительный просмотр видео
В основном используется функция локального предварительного просмотра видео.URL.createObjectURL()
метод достижения. Статический метод URL.createObjectURL() создает DOMString, содержащую URL-адрес, представляющий объект, указанный в параметре. Время жизни этого URL-адреса привязано к документу в окне, которое его создало. Этот новый объект URL представляет указанный объект File или Blob.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>视频本地预览示例</title>
</head>
<body>
<h3>阿宝哥:视频本地预览示例</h3>
<input type="file" accept="video/*" onchange="loadFile(event)" />
<video
id="previewContainer"
controls
width="480"
height="270"
style="display: none;"
></video>
<script>
const loadFile = function (event) {
const reader = new FileReader();
reader.onload = function () {
const output = document.querySelector("#previewContainer");
output.style.display = "block";
output.src = URL.createObjectURL(new Blob([reader.result]));
};
reader.readAsArrayBuffer(event.target.files[0]);
};
</script>
</body>
</html>
8.2 Как реализовать скриншоты плеера
В основном используется функция скриншота плеераCanvasRenderingContext2D.drawImage()
API для реализации. Метод CanvasRenderingContext2D.drawImage() в Canvas 2D API предоставляет несколько способов рисования изображений на Canvas.
Синтаксис API drawImage следующий:
❝void ctx.drawImage(image, dx, dy); void ctx.drawImage(image, dx, dy, dWidth, dHeight); void ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
❞
где параметр изображения представляет элемент, который нужно отрисовать в контексте. Допускается любой источник изображения холста (CanvasImageSource), например: CSSImageValue, HTMLImageElement, SVGImageElement, HTMLVideoElement, HTMLCanvasElement, ImageBitmap или OffscreenCanvas.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>播放器截图示例</title>
</head>
<body>
<h3>阿宝哥:播放器截图示例</h3>
<video id="video" controls="controls" width="460" height="270" crossorigin="anonymous">
<!-- 请替换为实际视频地址 -->
<source src="https://xxx.com/vid_159411468092581" />
</video>
<button onclick="captureVideo()">截图</button>
<script>
let video = document.querySelector("#video");
let canvas = document.createElement("canvas");
let img = document.createElement("img");
img.crossOrigin = "";
let ctx = canvas.getContext("2d");
function captureVideo() {
canvas.width = video.videoWidth;
canvas.height = video.videoHeight;
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
img.src = canvas.toDataURL();
document.body.append(img);
}
</script>
</body>
</html>
Теперь, когда мы знаем, как получить каждый кадр видео, мы фактически объединяемgif.jsС функцией кодирования GIF, предоставляемой этой библиотекой, мы можем быстро реализовать функцию перехвата видеокадров для создания анимации GIF. Брат Абао не будет продолжать знакомить здесь, заинтересованные друзья могут прочитатьИспользуйте JS для прямого перехвата видеоклипов для создания GIF-анимаций.Эта статья.
8.3 Как реализовать Canvas для воспроизведения видео
Использование Canvas для воспроизведения видео в основном предназначено для использованияctx.drawImage(video, x, y, width, height)
для отрисовки изображения текущего кадра видео, где параметром видео является видеообъект на странице. Следовательно, если мы непрерывно получаем текущее видеоизображение с определенной частотой и визуализируем его на холст Canvas, мы можем реализовать функцию использования Canvas для воспроизведения видео.
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>使用 Canvas 播放视频</title>
</head>
<body>
<h3>阿宝哥:使用 Canvas 播放视频</h3>
<video id="video" controls="controls" style="display: none;">
<!-- 请替换为实际视频地址 -->
<source src="https://xxx.com/vid_159411468092581" />
</video>
<canvas
id="myCanvas"
width="460"
height="270"
style="border: 1px solid blue;"
></canvas>
<div>
<button id="playBtn">播放</button>
<button id="pauseBtn">暂停</button>
</div>
<script>
const video = document.querySelector("#video");
const canvas = document.querySelector("#myCanvas");
const playBtn = document.querySelector("#playBtn");
const pauseBtn = document.querySelector("#pauseBtn");
const context = canvas.getContext("2d");
let timerId = null;
function draw() {
if (video.paused || video.ended) return;
context.clearRect(0, 0, canvas.width, canvas.height);
context.drawImage(video, 0, 0, canvas.width, canvas.height);
timerId = setTimeout(draw, 0);
}
playBtn.addEventListener("click", () => {
if (!video.paused) return;
video.play();
draw();
});
pauseBtn.addEventListener("click", () => {
if (video.paused) return;
video.pause();
clearTimeout(timerId);
});
</script>
</body>
</html>
8.4 Как реализовать хроматический ключ (эффект зеленого экрана)
В предыдущем примере мы представили использование Canvas для воспроизведения видео, поэтому у некоторых друзей могут возникнуть вопросы, зачем вам рисовать видео через Canvas?Разве тег Video не "милый"? Это потому, что Canvas предоставляетgetImageData
а такжеputImageData
Метод позволяет разработчикам динамически изменять отображаемое содержимое каждого кадра изображения. Таким образом, мы можем манипулировать видеоданными в режиме реального времени, чтобы синтезировать различные визуальные эффекты в воспроизводимом видео.
Например на МДН"Работа с видео с холстомУчебное пособие демонстрирует, как выполнить хроматическую рирпроекцию (эффект зеленого экрана или синего экрана) с помощью кода JavaScript.Хромакей, также известный как цветная инкрустация, представляет собой метод последовательного синтеза. Chroma означает чистый цвет, а Key означает извлечение цвета. Поместите человека или объект, который нужно сфотографировать, перед зеленым экраном и переместите его на задний план, заменив его другим фоном. Эта технология широко используется в производстве фильмов, телесериалов и игр, а хромакей также является важной частью виртуальной студии и визуальных эффектов.
Давайте посмотрим на код ключа:
processor.computeFrame = function computeFrame() {
this.ctx1.drawImage(this.video, 0, 0, this.width, this.height);
let frame = this.ctx1.getImageData(0, 0, this.width, this.height);
let l = frame.data.length / 4;
for (let i = 0; i < l; i++) {
let r = frame.data[i * 4 + 0];
let g = frame.data[i * 4 + 1];
let b = frame.data[i * 4 + 2];
if (g > 100 && r > 100 && b < 43)
frame.data[i * 4 + 3] = 0;
}
this.ctx2.putImageData(frame, 0, 0);
return;
}
НадcomputeFrame()
Метод отвечает за выборку кадра данных и выполнение эффекта хроматической рирпроекции. Используя технологию хроматического кеинга, мы также можем реализовать чистое заграждение масок на стороне клиента в реальном времени. Брат Абао не будет подробно рассказывать об этом здесь.Заинтересованные друзья могут прочитать интерфейс Chuangyu.Шквал не останавливает людей! Чистый заградительный огонь маски клиента в реальном времени на основе технологии хроматического ключаЭта статья.
9. Справочные ресурсы
- Байке - Потоковое
- MDN - Video_and_audio_content
- MDN - Range_requests
- MDN - Media_Source_Extensions_API
- Wiki - MPEG-DASH
- w3.org - Media Source Extensions
В этой статье используетсяmdniceнабор текста