Возникла задача получить из SDI сигнала трансляцию с субтитрами и отдать её на CDN в формате RTMP потока. Пару недель мучения и мытарств изложу в кратком содержании всех серий для коллекции. Возможно, кому пригодится.
Начнем с того какое оборудование было использовано для решения данной задачи:
Для захвата потока с SDI и транскодирования использовался сервер со следующей конфигурацией:
-
Плата захвата, тестировалось две платы, Blackmagic DeckLink Duo 2 и DeckLink Quad 2, обе оправдали наши ожидания.
-
Видеокарта с аппаратной поддержкой х264 кодека Nvidia Quadro P4000
-
Сервер на базе процессора Intel(R) Xeon(R) Silver 4114
-
Память 64Гб
Для отправки потока в сторону CDN использовался:
Wowza Streaming Engine сервер версии не ниже 8.5.
Сам захват с карты и передачу потока на Wowza было решено
осуществлять средствами опенсорц проекта FFmpeg.
Данный продукт хорошо себя зарекомендовал ранее и одно неоспоримое
преимущество среди прочих он бесплатен.
Но для того чтобы все заработало нам необходимо собрать FFmpeg с
необходимым перечнем модулей, а именно:
-
Поддержка DeckLink.
Для этого необходимо скачать с сайта производителя Blackmagic_DeckLink_SDK желательно версии не ниже 10.7, на текущий момент присутствует версия 12. https://blackmagicdesign.com Blackmagic_DeckLink_SDK_12.0.zip
Скачиваем распаковываем в дальнейшем нам потребуется указать путь к библиотекам при сборке нашего FFmpeg. -
Поддержка аппаратного декодирования
Необходимо зайти на сайт Nvidia и в разделе для разработчиков скачать CUDA под свою операционную систему.
wget https://developer.download.nvidia.com/compute/cuda/11.2.0/local_installers/cuda_11.2.0_460.27.04_linux.runsudo sh cuda_11.2.0_460.27.04_linux.run
-
Декодирование Subtitles из SDI потока ZVBI
В большинстве репозиториев уже присутствует данная библиотека в случае отсутствия её можно взять на https://sourceforge.net/projects/zapping/files/zvbi/0.2.35/
-
По необходимости другие библиотеки в частности, поддержка кодирования аудио в acc формат libfdk-aac и др.
С остальными модулями необходимыми для конкретных случаем можно ознакомится на странице проекта FFmpeg.
Скачиваем, устанавливаем, согласно инструкциям к библиотекам.
Собрали до кучи все необходимые библиотеки и можем приступить к сборке самого FFmpeg со всеми необходимыми нам модулями.
В моем случае это примерно выглядело следующим образом:
--enable-cuda --enable-cuvid --enable-nvenc --enable-nonfree --enable-libnpp --extra-cflags=-I//cuda/include --extra-ldflags=-L//cuda/lib64 --enable-libfdk-aac --extra-cflags=-I//BlackmagicSDK/Linux/include --extra-ldflags=-L//BlackmagicSDK/Linux/include --enable-decklink --enable-libzvbi
Более подробно о том что и зачем, можно посмотреть на странице проекта FFmpeg, но это необходимый и достаточный минимум для сборки FFmpeg с требуемым функционалом под нашу задачу.
После сборки тщательно обработать напильником, чем мы и займемся
Для захвата потока запустим FFmpeg со следующими ключами:
ffmpeg
-hwaccel cuvid использовать аппаратное
кодирование (задействовать видеокарту)
-f decklink подключить драйвера для
работы с картой захвата
-thread_queue_size 16384 задаем длину
очереди потока по умолчанию 8 у Вас может
отличаться
-teletext_lines all
указываем где искать телетекст
-i DeckLink Quad
(1) используем первый вход с платы
захвата
-c:v h264_nvenc устанавливаем
аппаратный кодек
-aspect 16:9 -s 1024x576 -filter:v yadif
-profile:v main -level 3.1 -preset llhq
-gpu any -rc cbrldhq
-g 50 -r 25 -minrate 2000k -b:v 2000k -maxrate 2000k -bufsize 4000k
-pixfmt yuv420p
-c:a libfdk-aac -ar 44100 -ac 2 -ab 128k -af volume=10dB -loglevel
warning
-metadata:s:s:0 language=rus если при
захвате потока не идентифицируется язык то необходимо, обязательно,
его прописать, в моем случае это был единственны субтитрированный
поток и он не идентифицировался - имел язык
und
-f mpegts
udp://ХХХ.ХХХ.ХХ.12:6970?pkt_size=1316 таргетируем
захваченный поток по направлению к серверу в формате
mpegts (данный формат позволяет передавать
несколько субпотоков и он поддерживается FFmpeg), так же
возможно использование мультикаст адресов в случае необходимости
одновременной обработки с одного потока.
В результате мы получим поток с тремя субпотоками (Video, Audio, Subtitles) что мы и добивались!
Теперь для захвата и отправки данного потока на стороне WOWZA
сервера необходимо в нужном приложении создать Stream File со
следующим содержимым:
по средствам веб или руками в [wowza]/content/
{uri: udp://XXX.XXX.XXX.12:6970?pkt_size=1316, адрес потока mpegtsDVBTeletextType: 1,2,3,4,5, типы субтитров, я указал все, но можно указать только 2 и 5 если не ошибаюсь.mpegtsDVBTeletextPageNumber: 88, страница субтитров 888 (здесь нет опечатки)reconnectWaitTime: 3000, время через которое необходимо осуществить переподключение в мсstreamTimeout: 5000 время ожидания при обрыве потока в мс}
Далее подключаемся к данному потоку и если все сделали правильно, то увидим его в Incoming Streams вашего приложения.
После чего можем перейти в Stream Targets вашего приложения и отправить поток по назначению, в формате RTMP в котором будет три субпотока (Video, Audio и Data).
На этом все пинайте, не сильно, за объективную критику, Спасибо!