обслуживание файла m3u8 через nginx для стриминга

Вопрос или проблема

Пытаюсь наладить работающий поток с использованием чанков. Но не уверен, как завершить последние шаги.

Вот суть проекта:

1 – загрузить 30-секундные чанки на Cloudflare (работает хорошо)

2 – при запросе потока из веб-приложения попросить экземпляр node+nginx сгенерировать манифест (работает хорошо)

3 – обслуживать сгенерированный манифест через nginx и начать поток (работает не очень хорошо).

Замечу, что веб-приложение и nginx работают локально:
http://127.0.0.1:8888/request-manifest?manifest_id=123

Другие детали:

файлы в формате mkv,

файлы mkv воспроизводятся с помощью стандартного html5-видеоплеера при прямом запросе файла

манифест не воспроизводится, когда URL загружается в VLC

возможно, один из чанк-файлов отсутствует, и фронтенду нужно это учесть (перейти к следующему чанку или обслужить отсутствующий кадр)

поскольку VLC тоже не может его воспроизвести, я могу предположить, что проблема в nginx или в самом манифесте. Вот конфигурация:

Текстовое содержание манифеста возвращается при выполнении запроса


worker_processes  1;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    sendfile            on;
    keepalive_timeout   65;

    # Логирование
    access_log  /var/log/nginx/access.log;
    error_log   /var/log/nginx/error.log;

    server {
        listen       80;
        # listen       443 ssl;
        server_name  localhost;

        # Конфигурация SSL
        # ssl_certificate     /path/to/your/fullchain.pem;
        # ssl_certificate_key /path/to/your/privkey.pem;
        # ssl_protocols       TLSv1.2 TLSv1.3;
        # ssl_ciphers         HIGH:!aNULL:!MD5;

        location / {
            return 403;
        }

        location /generate-manifest {
            add_header 'Access-Control-Allow-Origin' 'http://localhost:8100';
            add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Content-Type';
            
            if ($request_method = 'OPTIONS') {
                return 204;
            }

            proxy_pass http://127.0.0.1:3000;
            proxy_http_version 1.1;
            proxy_set_header Upgrade $http_upgrade;
            proxy_set_header Connection 'upgrade';
            proxy_set_header Host $host;
            proxy_cache_bypass $http_upgrade;
            proxy_set_header X-Query-String $query_string;
        }

        location /request-manifest {
            add_header 'Access-Control-Allow-Origin' 'http://localhost:8100';
            add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
            add_header 'Access-Control-Allow-Headers' 'Content-Type';
            
            if ($request_method = 'OPTIONS') {
                return 204;
            }

            set $manifest_id $arg_manifest_id;

            alias /var/nginx/manifests/;
            
            try_files $manifest_id.m3u8 =404;
        }
    }
}

Просто простой тест с html5-видеоплеером


<video 
  id="player" 
  width="640" 
  height="268" 
>
  <source src="http://127.0.0.1:8888/request-manifest?manifest_id=123" type="application/vnd.apple.mpegurl">
</video>

пример манифеста


#EXTM3U
#EXT-X-VERSION:3
#EXT-X-TARGETDURATION:30
#EXT-X-MEDIA-SEQUENCE:0

#EXTINF:30,
https://[secret].cloudflarestorage.com/video-streams/7ea3cbef-4da0-11ed-bdcc-baf70a43c072/1728953187133.mkv
#EXTINF:30,
https://[secret].cloudflarestorage.com/video-streams/7ea3cbef-4da0-11ed-bdcc-baf70a43c072/1728953217133.mkv
#EXTINF:1,
https:/[secret].cloudflarestorage.com/video-streams/MISSING_FOOTAGE.mkv
#EXT-X-ENDLIST

Также пробовал с стандартными примерами из hls.js и video.js, но не думаю, что проблема на фронтенде, так как я ожидал, что это будет воспроизводиться в VLC.

Определенно не хватает ключевого знания, просто не знаю, что попробовать или почитать дальше.

Есть идеи? Спасибо.

Ответ или решение

Для успешного обслуживания m3u8-файла через Nginx с целью потоковой передачи необходимо учесть несколько ключевых моментов. Основными аспектами проблемы являются генерирование манифеста, его правильное обслуживание и обеспечение совместимости с воспроизведением через HTML5 видео плееры и VLC. Давайте рассмотрим каждый из шагов подробно.

1. Проверьте конфигурацию Nginx

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

a. Правильная настройка location /request-manifest

Ваша директива location /request-manifest имеет правильный подход с использованием alias и try_files. Однако, проверьте, чтобы каталог /var/nginx/manifests/ действительно содержал файлы с соответствующими именами манифестов. Также обратите внимание на права доступа к этому каталогу. Nginx пользователь (обычно www-data или nginx) должен иметь доступ к этому каталогу и файлам внутри него.

location /request-manifest {
    add_header 'Access-Control-Allow-Origin' 'http://localhost:8100';
    add_header 'Access-Control-Allow-Methods' 'GET, OPTIONS';
    add_header 'Access-Control-Allow-Headers' 'Content-Type';

    if ($request_method = 'OPTIONS') {
        return 204;
    }

    set $manifest_id $arg_manifest_id;

    alias /var/nginx/manifests/;    
    try_files $manifest_id.m3u8 =404;
}

b. Убедитесь в правильности формата m3u8

Ваш пример манифеста выглядит корректно, однако необходимо проверить следующие моменты:

  • Убедитесь, что ссылки на сегменты (например, 1728953187133.mkv) являются корректными и доступны из вашей сети.
  • Проверьте, имеете ли вы доступ к файлам сегментов из любого устройства, подключенного к вашей сети.
  • Для проверки используйте метод CURL либо через браузер, чтобы убедиться в доступности файлов.

2. Проверка файлов сегментов

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

3. Тестирование с помощью VLC

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

  • Проверьте, поддерживается ли ваш формат файла VLC. Хотя MKV поддерживается, стоит проверить, не требует ли он специального кодека.
  • Используйте VLC для открытия вашего m3u8 файла напрямую и проверьте наличие ошибок в логе VLC (View → Messages).

4. Воспроизведение на HTML5 плеере

Ваш HTML5 плеер должен корректно обрабатывать CORS заголовки. Убедитесь, что заголовки Access-Control-Allow-Origin настроены правильно и клиент имеет доступ к вашему манифесту и файлам сегмента.

5. Дополнительные рекомендации

  • Если вы используете Cloudflare, убедитесь, что настройки кэширования и проксирования не мешают прямому доступу к вашим ресурсам. Вы можете временно отключить Cloudflare для тестирования.
  • Рассмотрите использование инструмента для HLS (например, HLS.js или Video.js) для лучшего управления потоком и для возможностей с воспроизведением.

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...