RTMP – это протокол передачи потокового видео, например с камеры на стриминговый сервис. Расшифровывается как Real Time Messaging Protocol. Разработан компанией Adobe изначально для Flash Media Server. Обобщенно всё стриминговое производство описывается так:

- Capture – создать потоки на источниках (камерах, кодерах)
- Contribution – собрать потоки с источников, доставить их в микшер
- Processing – обработка, линейный монтаж, титрование, кодирование для стриминга, управление источниками
- Distribution – отправить выходной поток (программу) на платформу, с нее раздать зрителям.
- Consuming – получение зрителями потоков со стриминговой платформы.
RTMP изначально предназначался для потоковой передачи мультимедиа с помощью Adobe Flash Player, но Flash перестал поддерживаться браузерами в 2020 году.
И, хотя потоковые протоколы вроде HLS и MPEG-DASH, теперь используются для отправки выходного потока с платформы зрителям (distribution), RTMP по-прежнему играет важную роль в отправке потока на стриминговую платформу (Contribution).
RTMP - это протокол L7 (прикладного уровня), который работает поверх TCP и по умолчанию использует порт 1935. Существует также несколько разновидностей протокола, таких как:
- RTMPE (которая зашифрована с использованием механизмов безопасности Adobe),
- RTMPT (инкапсулированный в HTTP для обхода брандмауэров),
- RTMPS - это тот же RTMP, но через соединение TLS/ SSL.
RTMP инкапсулирует и может передавать несколько мультиплексированных медиапотоков FLV. Но обычно он используется для потоковой передачи одного видеопотока H.264 (AVC) и одного аудиопотока AAC. Кодеки, поддерживаемые RTMP, ограничены форматом медиаконтейнера FLV. В контейнер FLV бывают упакованы видеопотоки: FLV1 (Sorenson Spark), VP6, H.264, а аудиопотоки: MPEG Layer-3 или HE-AAC.
RTMP не поддерживает современные кодеки. Если вы захотите транслировать H.265 (HEVC) или VP8/9, то такая возможность не предусмотрена.
Как работает потоковая передача RTMP?
Основная идея RTMP заключается в установлении и поддержании постоянного соединения между источником и устройством воспроизведения. Сначала клиент инициирует TCP-соединение с сервером. Как правило, прежде чем начать потоковую передачу, вы должны сначала получить URL RTMP. Он имеет следующую структуру: rtmp://host:port/app/stream-key. В случае RTMPS URL-адрес будет начинаться с rtmps://. Клиентское приложение будет обрабатывать URL и подключаться к соответствующему хосту и порту, предоставляя серверу RTMP "имя приложения" и "ключ потока". "Ключ потока" используется для уникального выделения вашей сессии прямой трансляции среди других.
После процедуры рукопожатия клиент и сервер обмениваются данными, отправляя друг другу RTMP-сообщения. Эти сообщения мультиплексируются в небольшие блоки (Chunks), а далее эти блоки обратно как бы разъединяются (т.е. происходит демультиплексирование) на отдельные потоки (Chunk Stream).
Chunk Stream - это абстракция, которая используется для представления мультиплексирования и пакетирования сообщений RTMP. Это позволяет обеспечить разделение и чередование больших сообщений. Например, если нам нужно передать видеопакет размером 1 Мб через наше TCP-соединение, мы не сможем ничего отправить до тех пор, пока 1 Мб данных нашего видеопакета не будет отправлен полностью. Но если мы разделим наше сообщение размером 1 Мб на фрагменты, например, по 50 Кб, мы могли бы легко отправить что-то еще между этими фрагментами размером 50 Кб. Таким образом, меньшее сообщение имеет более высокий приоритет.
Размер блока по умолчанию в потоке блоков RTMP составляет 128 байт, и его можно изменить.

Каждый Chunk Stream имеет свой собственный числовой идентификатор. Обычно нам нужен один поток для видео и один для аудио. У каждого потока есть заголовок, куда включен данный идентификатор. Кроме того, заголовок блока содержит Chunk Type ID, который влияет на то, как должен обрабатываться оставшийся заголовок (если он существует).
Например, несколько последующих блоков с одинаковым Chunk Type ID являются частями одного и того же сообщения, и они совместно используют некоторые свойства этого сообщения, например timestamp. В этом случае мы можем сэкономить несколько байт для каждого блока, опуская все остальные данные заголовка.
Итак, нам нужно отправить несколько RTMP-сообщений. Мы разбиваем их на блоки (Chunk) и передаем с разными Chunk Type ID. Но что именно представляют собой эти сообщения? Каждое сообщение имеет идентификатор, указывающий на значение сообщения. Это может быть одно из управляющих сообщений протокола, например SET_CHUNK_SIZE (которое используется для указания изменения размера блока отправителя).
Это также может быть VIDEO (видеосообщение), AUDIO (аудиосообщение), DATA_AMF0/DATA_AMF3 или COMMAND_AMF0/COMMAND_AMF3. AMF (Action Message Format, формат сообщений о действиях) — бинарный формат обмена данными. Построен на основе протокола SOAP (Simple Object Access Protocol) и используется, преимущественно, для обмена информацией между Adobe Flash и базами данных. Большинство реализаций используют версию AMF0. Содержимое видео и аудиосообщений интерпретируется как теги VIDEODATA и AUDIODATA FLV соответственно.
Еще одним важным свойством RTMP-сообщения является временная метка (timestamp). Это время, когда данные должны быть декодированы и представлены пользователю. Временные метки ауидо- и видеосообщений синхронизированы друг с другом и имеют ту же начальную эпоху, которая согласована во время рукопожатия.
Так выглядит схема доставки контента от источника до конечного пользователя:

- Захват камерой. Камера выполняет работу по захвату света и звука и преобразованию этих аналоговых входных сигналов в необработанный (несжатый) цифровой формат, которые затем должны быть сжаты (закодированы) перед потоковой передачей.
- Кодирование. Кодек сжимает необработанные аудио- и видеоданные в поток меньшего битрейта.
- Загрузка. Далее RTMP устанавливает постоянное соединение между устройством захвата (клиентом) и стриминговой площадкой (сервером).
Медиасервер выполняет невидимую зрителю работу по перекодированию, чтобы сделать возможным плавное кроссплатформенное взаимодействие. В процессе транскодирования, сервер перепаковывает исходное медиа в версии с различным разрешением, качеством и битрейтом, и даже выводит несколько протоколов доставки, таких как HLS, для удовлетворения потребностей различных устройств воспроизведения. Например, когда вы переключаетесь с 480p на 720p во время просмотра видео на YouTube, вы фактически просите сервер YouTube воспроизвести другой файл (того же видео), который был закодирован в другом разрешении. Но это не один файл, а последовательность кусков (chunks), и поэтому воспроизведение может начинаться со следующего куска в другом разрешении, если изменились условия в канале передачи. - Сеть доставки контента (CDN). CDN (Content Delivery Network) — это географически распределённая сетевая инфраструктура, обеспечивающая быструю доставку контента пользователям веб-сервисов и сайтов. Входящие в состав CDN cерверы географически располагаются таким образом, чтобы сделать время ответа для пользователей сайта/сервиса минимальным.
- Воспроизведение на компьютере зрителя.
RTMP имеет два основных метода транспортировки - Push, при котором кодер доставляет RTMP на RTMP-сервер или CDN, и Pull, при котором клиент извлекает поток и воспроизводит его обратно.
Рассмотрим Push стриминг с RTMP-камеры:
-
Включаем RTMP-камеру или кодер.
-
Заходим в youtube в настройки прямого эфира:

Здесь мы видим Stream URL и ключ стрима (Stream key).
-
Теперь в веб-настройках камеры находим RTMP settings и в качестве ссылки вставляем stream URL, а затем через “/” ключ, который является идентификатором стрима. После перезагрузки (reboot) камеры стрим должен начаться.

Собственный сервер RTMP на базе Nginx:
Допустим, нам нужно организовать трансляцию на Youtube и проанализировать поток, идущий на стриминговый сервис. В таком случае можно создать свой rtmp-сервер, на который будет отправляться поток, который оттуда уже пойдёт к зрителям.
В бытовых условиях источником потока могут быть OBS, ffmpeg или смартфон с соответствующим приложением (например, Larix Broadcaster, работает на андроиде и айфоне). Просматривать его и отправлять на Youtube будем через OBS. Но OBS не является сервером RTMP, чтобы на него стримить, придется поставить промежуточный сервер.
Для создания своего сервера, можно использовать веб-сервер Nginx, включающий в себя модуль, который позволяет вам предоставлять поток RTMP с простой конфигурацией с выделенного URL-адреса, точно так же, как он обеспечивает HTTP-доступ к веб-страницам по умолчанию.
Для начала нужно обновить систему и установить веб-сервер nginx, а также его rtmp дополнение:
sudo apt-get update
sudo apt-get upgrade\n\nsudo apt install nginx-full
sudo apt install libnginx-mod-rtmp
В файле конфигурации прописываем сам сервер:
sudo nano /etc/nginx/nginx.conf
rtmp {
server {
listen 1935;
chunk_size 4096;
application live {
live on;
record off;
}
}
}
-
listen 1935 означает, что RTMP-сервер будет ожидать подключения по порту 1935, являющимся стандартным;
-
chunk_size 4096 определяет, что RTMP будет отправлять данные блоками по 4 КБ. Это значение не может быть меньше 128Б;
-
application live определяет application block that will be available at the /live URL path;
-
record off отключает функцию записи, так что по умолчанию потоки не сохраняются на диск отдельно.

Для сбора статистики настроим http-сервер. Теперь статистика будет доступна по адресу http://localhost:8080/stat:

Следующим шагом отправляем на rtmp-сервер поток с мобильного телефона. base1 – идентификатор конкретного поток, задаём это значение произвольно. Главное, чтобы у каждого источника был уникальный ключ:

Чтобы проверить картинку заходим в OBS и добавляем в источники Media Source, и прописываем URL с учётом ключа стрима:

Также есть возможность добавления потока со второго телефона (но ключ стрима нужно указать другой):

Уже сейчас можно просматривать статистику, в которой отображается количество потоков, ауидо- и видеокодеки, битрейт:


Автор текста: Покидова А. Ю., 2023