Тянем ролик с YouTube и раздаем по WebRTC в реалтайме
Задача следующая. Провести совместный просмотр ролика с YouTube в реальном времени несколькими пользователями. Зрители должны получать видео одновременно, с минимальной задержкой.
Ролик как стрим
Понятно, что если каждый из зрителей просто начнет играть ролик, цель не будет достигнута, т.к. один будет получать видео быстрее, другой медленнее. Возникнет неконтролируемый разброс.
Для того, чтобы разброса не было, нужно раздавать этот ролик всем одновременно. Это можно реализовать, если обернуть ролик в Live-stream. Покажем как это сделать с помощью связки этой библиотеки с ffmpeg.
Нам нужно реализовать схему, описанную выше. А именно, ydl подключается к YouTube и начинает скачивать ролик. FFmpeg подхватывает скачивающийся ролик, оборачивает его в RTMP поток и отправляет на сервер. Сервер раздает полученный поток как WebRTC в реальном времени.
Установка youtube-dl
Начинаем с установки youtube-dl. Процесс установки на Linux предельно простой и подробно описан в Readme под Lin и под Win.
2. Даем права на запуск
На этом все. YouTube скачивалка готова к работе.
Возьмем ролик с YouTube и посмотрим на его мета-данные:
Результат будет таким:
Установка ffmpeg
Далее устанавливаем ffmpeg стандартными заклинаниями:
Проверяем что получилось
Теперь самое интересное. Библиотека youtube-dl предназначена для скачивания. Она так и называется YouTube Download. Т.е. Можно скачать youtube ролик полностью и уже после этого застримить его через ffmpeg как файл.
Но представим такой юзеркейс. Сидят в веб-конференции маркетолог, менеджер и программист. Маркетолог хочет показать всем в реальном времени ролик с YouTube, который весит, скажем 300 мегабайт. Согласитесь, возникнет некая неловкость, если нужно будет выкачать весь ролик перед тем, как начать его показ.
- Маркетолог говорит — «А теперь, коллеги, давайте посмотрим этот ролик с котиками, он полностью отвечает нашей стратегии выхода на рынок», и жмет кнопку «показать всем ролик».
- На экране появляется прелоадер: «Подождите, ролик с котиками скачивается. Это займет не более 10 минут».
- Менеджер идет пить кофе, а программист — читать хабр.
Передача данных из youtube-dl в ffmpeg
Граббер youtube-dl сохраняет поток в файловой системе. Нужно подключиться к этому потоку и организовать зачитку из файла ffmpeg-ом по мере его скачивания с помощью youtube-dl.
Чтобы объединить эти два процесса: скачивание и стриминг ffmpeg, нам потребуется небольшой связывающий скрипт.
Этот питон-скрипт делает следующее:
- Создает подпроцесс _youtube_process зачитки ролика библиотекой youtube-dl
- Создает второй подпроцесс _ffmpeg_process, которому передаются данные из первого через pipe. Этот процесс уже создает RTMP поток и отправляет его на сервер по указанному адресу.
Тестирование скрипта
Для запуска скрипта нужно установить python. Скачать можно здесь.
Мы при тестировании использовали версию 2.6.6. Скорее всего подойдет любая версия, т.к. скрипт достаточно простой и его задача — передать из одного процесса в другой.
Как видите, передается три аргумента:
- Адрес youtube ролика. www.youtube.com/watch?v=9cQT4urTlXM
- Имя потока, с которым будет проходить RTMP-трансляция. stream1
- Адрес RTMP-сервера. rtmp://192.168.88.59:1935/live
Схема тестирования с Web Call Server:
Ниже мы задействуем для теста один из демо-серверов:
Это RTMP адрес, который нужно передать скрипту streamer.py чтобы быстро протестировать трансляцию с нашим демо-сервером.
Запуск должен выглядеть так:
В консоли stdout увидим следующий вывод:
Если бегло пробежать по этому логу, то можно понять, что происходит следующее:
- Открывается страница с видеороликом.
- Извлекаются данные о видео форматах.
- Скачивается mp4 ролик 1280x720, H.264+AAC
- Запускается ffmpeg, подхватывает скачиваемые данные и стримит по RTMP с битрейтом 421 kbps. Такой скудный битрейт объясняется выбранным роликом с таймером. Нормальный видеоролик даст на порядок большее значение битрейта.
Мы специально взяли именно этот ролик на YouTube, чтобы иметь возможность протестировать реалтаймовость потока, ведь нашей конечной целью было доставить поток с YouTube ко всем зрителям одновременно, с минимальной задержкой и разбросом во времени. Ролик с миллисекундным таймером, как нельзя более подходит для такого теста.
Сам тест очень простой. Открываем две вкладки браузера (моделируем двух зрителей), играем этот поток с таймером по нашей схеме, и делаем несколько скриншотов, чтобы запечатлеть разницу во времени прибытия видео. Далее сравниваем миллисекунды и видим кто получил видео раньше, а кто позже и на сколько.
Получаем следующие результаты:
Как видите, каждый из зрителей видит одно и то же видео, с разбросом не более 130 миллисекунд.
Таким образом задача реалтаймовой трансляции ролика с YouTube на WebRTC решена. Зрители получили поток практически одновременно. Менеджер не ушел пить кофе, программист — читать хабр, а маркетолог успешно показал всем ролик с котиками.