Как можно воспроизвести видео в браузере, когда байты видео подгружаются вручную?

Какой оптимальный формат видео следует использовать, чтобы каждый кусок содержал всю необходимую информацию для бесшовного воспроизведения, когда проигрываются независимые аудио- и видео-фрагменты? Какую технологию в браузере лучше использовать для проигрывания таких видео-фрагментов? Можно ли на лету кодировать в нужный формат видео, если исходный формат байтов будет неподходящим?
  • 20 января 2024 г. 4:58
Ответы на вопрос 2
Воспроизведение видео в браузере, когда байты видео подгружаются вручную, можно осуществить с помощью Media Source Extensions (MSE). Это API в HTML5 позволяет динамически создавать медиа-потоки для воспроизведения видео. Оно позволяет воспроизведение видео по мере загрузки его частей через JavaScript.

Оптимальный формат для таких задач – это тот, который поддерживает разделение на сегменты, например, MPEG-DASH (Dynamic Adaptive Streaming over HTTP) или Apple HLS (HTTP Live Streaming). Эти форматы состоят из небольших файлов-сегментов, которые можно загружать и воспроизводить независимо друг от друга. Метаданные в каждом сегменте позволяют проигрывателю синхронизировать аудио и видео и обеспечить бесшовное воспроизведение.

Использование MSE для воспроизведения видео-фрагментов обычно выглядит следующим образом:

1. Определение поддержки MSE:
```javascript
if ('MediaSource' in window) {
  // MediaSource доступен
}
```

2. Создание объекта MediaSource и получение URL для него:
```javascript
var mediaSource = new MediaSource();
var video = document.querySelector('video');
video.src = URL.createObjectURL(mediaSource);
```

3. Ожидание события, когда MediaSource будет готов для буферизации:
```javascript
mediaSource.addEventListener('sourceopen', sourceOpen);
```

4. Добавление видео-буфера и передача данных в него:
```javascript
function sourceOpen(e) {
  var mime = 'video/mp4; codecs="avc1.4d401e"';
  var sourceBuffer = mediaSource.addSourceBuffer(mime);
  
  // Загрузка видео данных по частям и передача их в sourceBuffer
  // sourceBuffer.appendBuffer(data);
}
```

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

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

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

p.s. вполне возможно что сейчас лучше/удобнее формировать .m3u8 плейлист, javascript там продвинутый у html video, но если что его можно формировать и прописывать с помощью data uri.
Похожие вопросы