mediamtx — это готовый к использованию сервер и прокси-сервер с нулевой зависимостью, который позволяет пользователям публиковать, читать и проксировать прямые видео- и аудиопотоки по различным протоколам:
протокол | Описание | варианты | опубликовать | Читать | прокси — сервер |
---|---|---|---|---|---|
RTSP | самый быстрый способ публикации и чтения потоков | RTSP, RTSPS | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
RTMP | позволяет взаимодействовать с устаревшим программным обеспечением | RTMP, RTMPS | :heavy_check_mark: | :heavy_check_mark: | :heavy_check_mark: |
HLS | позволяет встраивать потоки на веб-страницу | HLS с низкой задержкой, стандартный HLS | :x: | :heavy_check_mark: | :heavy_check_mark: |
Характеристики:
- Публиковать прямые трансляции на сервере
- Читать прямые трансляции с сервера
- Прокси-потоки с других серверов или камер, всегда или по запросу
- Каждый поток может содержать несколько видео- и аудиодорожек, закодированных любым RTP-совместимым кодеком, включая H264, H265, VP8, VP9, MPEG2, MP3, AAC, Opus, PCM, JPEG
- Потоки автоматически преобразуются из одного протокола в другой. Например, можно опубликовать поток с помощью RTSP и прочитать его с помощью HLS
- Обслуживать несколько потоков одновременно по отдельным путям
- Аутентифицировать пользователей; использовать внутреннюю или внешнюю аутентификацию
- Перенаправление считывателей на другие RTSP-серверы (балансировка нагрузки)
- Запрашивать сервер и управлять им через HTTP API
- Перезагрузите конфигурацию, не отключая существующие клиенты (горячая перезагрузка)
- Прочитайте показатели, совместимые с Prometheus
- Запускайте внешние команды, когда клиенты подключаются, отключаются, читают или публикуют потоки
- Изначально совместимы с камерой Raspberry Pi
- Совместим с Linux, Windows и macOS, не требует никаких зависимостей или интерпретатора, это единый исполняемый файл
Запуск при загрузке
Linux
Systemd — это диспетчер служб, используемый Debian и многими другими дистрибутивами Linux, и позволяет запускать mediamtx при загрузке.
Загрузите пакет выпуска со страницы выпуска, распакуйте его и переместите исполняемый файл и конфигурацию в систему:
wget https://github.com/bluenviron/mediamtx/releases/download/v1.8.4/mediamtx_v1.8.4_linux_amd64.tar.gz tar xzvf mediamtx_v1.8.4_linux_amd64.tar.gz mv mediamtx /usr/local/bin/ mv mediamtx.yml /usr/local/etc/
Создание сервиса:
tee /etc/systemd/system/mediamtx.service >/dev/null << EOF [Unit] Wants=network.target [Service] ExecStart=/usr/local/bin/mediamtx /usr/local/etc/mediamtx.yml [Install] WantedBy=multi-user.target EOF
Включить и запустить службу:
systemctl enable mediamtx systemctl start mediamtx systemctl status mediamtx
Опубликовать на сервере
С веб-камеры
Чтобы опубликовать видеопоток обычной веб -камеры на сервере, отредактируйте rtsp-simple-server.yml и замените все, что находится внутри раздела paths, следующим содержимым:
paths: cam: runOnInit: ffmpeg -f v4l2 -i /dev/video0 -pix_fmt yuv420p -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$RTSP_PATH runOnInitRestart: yes
Если платформа Windows:
paths: cam: runOnInit: ffmpeg -f dshow -i video="USB2.0 HD UVC WebCam" -pix_fmt yuv420p -c:v libx264 -preset ultrafast -b:v 600k -f rtsp rtsp://localhost:$RTSP_PORT/$RTSP_PATH runOnInitRestart: yes
Где USB2.0 HD UVC WebCam — название вашей веб-камеры, которое можно получить с помощью:
ffmpeg -list_devices true -f dshow -i dummy
После запуска сервера доступ к веб-камере можно получить наrtsp://localhost:8554/cam.
С камеры Raspberry Pi
rtsp-simple-server изначально поддерживает камеру Raspberry Pi, обеспечивая высококачественную потоковую передачу видео с камеры любому пользователю с низкой задержкой. Есть несколько требований.:
-
Сервер должен работать на Raspberry Pi с операционной системой Raspberry Pi OS bullseye или новее в качестве операционной системы. Поддерживаются как 32-разрядные, так и 64-разрядные операционные системы.
-
Убедитесь, что стек устаревших камер отключен. Введите sudo raspi-config, затем перейдите в Interfacing options, enable/disable legacy camera support, выберите no. Перезагрузите систему.
Если вы хотите запустить стандартную (неконтейнеризованную) версию сервера:
-
Убедитесь, что libcamera0 версия пакета не ниже 0.0.2, в противном случае обновите его с помощью sudo apt update && sudo apt install libcamera0.
-
загрузите исполняемый файл сервера. Если вы используете 64-разрядную версию операционной системы, обязательно выберите arm64 вариант.
-
отредактируйте rtsp-simple-server.yml и замените все, что находится внутри раздела paths, следующим содержимым:
paths: cam: source: rpiCamera
Если вы хотите запустить сервер с помощью Docker, вам необходимо использовать latest-rpi образ (который уже содержит libcamera) и установить некоторые дополнительные флаги:
docker run --rm -it \ --network=host \ --privileged \ --tmpfs /dev/shm:exec \ -v /run/udev:/run/udev:ro \ -e RTSP_PATHS_CAM_SOURCE=rpiCamera \ aler9/rtsp-simple-server:latest-rpi
После запуска сервера доступ к камере можно получить с помощью rtsp://raspberry-pi:8554/cam или http://raspberry-pi:8888/cam.
Настройки камеры можно изменить с помощью rpiCamera* параметров:
paths: cam: source: rpiCamera rpiCameraWidth: 1920 rpiCameraHeight: 1080
Все доступные параметры перечислены в файле образца конфигурации.
От OBS Studio
OBS Studio может публиковать на сервере с помощью протокола RTMP. В Settings -> Stream (или в мастере автоматической настройки) используйте следующие параметры:
- Обслуживание: Custom…
- Сервер: rtmp://localhost
- Ключ потока: mystream
Если используются учетные данные, используйте следующие параметры:
- Обслуживание: Custom…
- Сервер: rtmp://localhost
- Ключ потока: mystream?user=myuser&pass=mypass
Из OpenCV
Чтобы опубликовать видеопоток из OpenCV на сервер, OpenCV должен быть скомпилирован с поддержкой GStreamer, следуя этой процедуре:
sudo apt install -y libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev gstreamer1.0-plugins-ugly gstreamer1.0-rtsp python3-dev python3-numpy git clone --depth=1 -b 4.5.4 https://github.com/opencv/opencv cd opencv mkdir build && cd build cmake -D CMAKE_INSTALL_PREFIX=/usr -D WITH_GSTREAMER=ON .. make -j$(nproc) sudo make install
Видео можно публиковать с помощью VideoWriter:
import cv2 import numpy as np from time import sleep fps = 20 width = 800 height = 600 out = cv2.VideoWriter('appsrc ! videoconvert' + \ ' ! x264enc speed-preset=ultrafast bitrate=600 key-int-max=40' + \ ' ! rtspclientsink location=rtsp://localhost:8554/mystream', cv2.CAP_GSTREAMER, 0, fps, (width, height), True) if not out.isOpened(): raise Exception("can't open video writer") while True: frame = np.zeros((height, width, 3), np.uint8) # create a red rectangle for y in range(0, int(frame.shape[0] / 2)): for x in range(0, int(frame.shape[1] / 2)): frame[y][x] = (0, 0, 255) out.write(frame) print("frame written to the server") sleep(1 / fps)
Чтение с сервера
От VLC и Ubuntu
VLC, поставляемый с Ubuntu 21.10, не поддерживает воспроизведение RTSP из-за проблемы с лицензией (см. Здесь и здесь).
Чтобы устранить проблему, удалите экземпляр VLC по умолчанию и установите версию snap:
sudo apt purge -y vlc snap install vlc
Затем используйте его для чтения потока:
vlc rtsp://localhost:8554/mystream
RTSP
Общее использование
RTSP — это стандартизированный протокол, позволяющий публиковать и считывать потоки; в частности, он поддерживает различные базовые транспортные протоколы, которые выбираются клиентами во время установления связи с сервером:
- UDP: наиболее производительный, но не работает при наличии NAT / брандмауэра между сервером и клиентами. Он не поддерживает шифрование.
- UDP-multicast: позволяет экономить пропускную способность, когда все клиенты находятся в одной локальной сети, отправляя пакеты один раз на фиксированный IP-адрес многоадресной рассылки. Он не поддерживает шифрование.
- TCP: самый универсальный, поддерживает шифрование.
Транспортным протоколом по умолчанию является UDP. Чтобы изменить транспортный протокол, вам необходимо настроить конфигурацию выбранного вами клиента.
Транспорт TCP
Протокол RTSP поддерживает транспортный протокол TCP, который позволяет получать пакеты даже при наличии NAT/ брандмауэра между сервером и клиентами, и поддерживает шифрование (см. Шифрование).
Вы можете использовать FFmpeg для публикации потока с использованием транспортного протокола TCP:
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f rtsp -rtsp_transport tcp rtsp://localhost:8554/mystream
Вы можете использовать FFmpeg для чтения этого потока с помощью транспортного протокола TCP:
ffmpeg -rtsp_transport tcp -i rtsp://localhost:8554/mystream -c copy output.mp4
Вы можете использовать GStreamer для чтения этого потока по транспортному протоколу TCP:
gst-launch-1.0 rtspsrc protocols=tcp location=rtsp://localhost:8554/mystream ! fakesink
Вы можете использовать VLC для чтения этого потока с помощью транспортного протокола TCP:
vlc --rtsp-tcp rtsp://localhost:8554/mystream
UDP — многоадресная передача
Протокол RTSP поддерживает UDP-многоадресный транспортный протокол, который позволяет серверу отправлять пакеты один раз, независимо от количества подключенных считывателей, экономя полосу пропускания.
Этот режим должен запрашиваться считывателями при установлении связи с сервером; как только считыватель завершит установление связи, сервер начнет отправлять многоадресные пакеты. Другим считывателям будет предложено прочитать существующие многоадресные пакеты. Когда все устройства многоадресной рассылки отключатся от сервера, последний прекратит отправку многоадресных пакетов.
Если вы хотите использовать протокол UDP-multicast в беспроводной локальной сети, пожалуйста, имейте в виду, что максимальный битрейт, поддерживаемый multicast, соответствует самой низкой разрешенной скорости передачи данных Wi-Fi. Например, если на вашем маршрутизаторе включена скорость передачи данных 1 Мбит / с (а она есть на большинстве маршрутизаторов), максимальный битрейт будет равен 1 Мбит / с. Чтобы увеличить максимальный битрейт, используйте кабельную локальную сеть или измените настройки своего маршрутизатора.
Чтобы запросить и прочитать поток с помощью UDP-многоадресной рассылки, вы можете использовать FFmpeg:
ffmpeg -rtsp_transport udp_multicast -i rtsp://localhost:8554/mystream -c copy output.mp4
или GStreamer:
gst-launch-1.0 rtspsrc protocols=udp-mcast location=rtsps://ip:8554/...
или VLC (добавить ?vlcmulticast к URL-адресу):
vlc rtsp://localhost:8554/mystream?vlcmulticast
Шифрование
Входящие и исходящие потоки RTSP могут быть зашифрованы с помощью TLS (получение протокола RTSPS). Необходим сертификат TLS, который может быть сгенерирован с помощью OpenSSL:
openssl genrsa -out server.key 2048 openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
Отредактируйте rtsp-simple-server.yml и установите параметры protocols, encryption serverKey и serverCert:
protocols: [tcp] encryption: optional serverKey: server.key serverCert: server.crt
Потоки могут публиковаться и считываться с помощью rtsps схемы и 8322 порта:
ffmpeg -i rtsps://ip:8322/...
Если клиентом является GStreamer, отключите проверку сертификата:
gst-launch-1.0 rtspsrc tls-validation-flags=0 location=rtsps://ip:8322/...
На данный момент VLC не поддерживает чтение зашифрованных RTSP-потоков. Обходной путь заключается в запуске экземпляра rtsp-simple-server на той же машине, на которой запущен VLC, использовании его для чтения зашифрованного потока в режиме прокси и чтения проксированного потока с помощью VLC.
Перенаправление на другой сервер
Для перенаправления на другой сервер используйте redirect исходный код:
paths: redirected: source: redirect sourceRedirect: rtsp://otherurl/otherpath
Резервный поток
Если никто не публикует на сервере, читатели могут быть перенаправлены на запасной путь или URL, который обслуживает резервный поток:
paths: withfallback: fallback: /otherpath
Поврежденные кадры
В некоторых сценариях при чтении RTSP с сервера декодированные кадры могут быть повреждены или неполными. Это может быть вызвано несколькими причинами.:
-
буфер пакетов сервера слишком мал и не справляется с пропускной способностью потока. Решение заключается в увеличении его размера.:
readBufferCount: 1024
-
Пропускная способность потока слишком велика, и поток не может быть корректно отправлен с помощью транспорта UDP. UDP более производителен, быстр и эффективен, чем TCP, но не имеет механизма повторной передачи, который необходим в случае потоков, требующих большой пропускной способности. Решение заключается в переключении на TCP:
protocols: [tcp]
В случае, если источником является камера:
paths: test: source: rtsp://.. sourceProtocol: tcp
Протокол RTMP
Общее использование
RTMP — это протокол, который позволяет считывать и публиковать потоки, но менее универсален и менее эффективен, чем RTSP (не поддерживает UDP, шифрование, не поддерживает большинство кодеков RTSP, не поддерживает механизм обратной связи). Используется, когда необходимо опубликовать или прочитать потоки из программного обеспечения, поддерживающего только RTMP (например, дроны OBS Studio и DJI).
На данный момент с протоколом RTMP можно использовать только кодеки H264 и AAC.
Потоки могут публиковаться или считываться с помощью протокола RTMP, например, с помощью FFmpeg:
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost/mystream
или GStreamer:
gst-launch-1.0 -v flvmux name=s ! rtmpsink location=rtmp://localhost/mystream filesrc location=file.mp4 ! qtdemux name=d d.video_0 ! queue ! s.video d.audio_0 ! queue ! s.audio
Учетные данные можно предоставить, добавив к URL — адресу параметры user и pass:
ffmpeg -re -stream_loop -1 -i file.ts -c copy -f flv rtmp://localhost:8554/mystream?user=myuser&pass=mypass
Шифрование
Соединения RTMP могут быть зашифрованы с помощью TLS, получая протокол RTMPS. Необходим сертификат TLS, который может быть сгенерирован с помощью OpenSSL:
openssl genrsa -out server.key 2048 openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
Отредактируйте rtsp-simple-server.yml и установите параметры rtmpEncryption, rtmpServerKey и rtmpServerCert:
rtmpEncryption: optional rtmpServerKey: server.key rtmpServerCert: server.crt
Потоки могут публиковаться и считываться с помощью rtmps схемы и 1937 порта:
rtmps://localhost:1937/...
Пожалуйста, имейте в виду, что RTMPS в настоящее время не поддерживается VLC, FFmpeg и GStreamer. Однако вы можете использовать прокси, такой как stunnel или nginx, чтобы разрешить RTMP-клиентам доступ к ресурсам RTMPS.
Протокол HLS
Общее использование
HLS — это протокол, позволяющий встраивать прямые трансляции на веб-страницы. Он работает путем разделения потоков на сегменты и обслуживания этих сегментов с помощью протокола HTTP. Доступ к каждому потоку, опубликованному на сервере, можно получить, посетив:
http://localhost:8888/mystream
где mystream — название публикуемого потока.
Пожалуйста, имейте в виду, что HLS поддерживает только одну видеодорожку H264 и одну аудиодорожку AAC из-за ограничений большинства браузеров. Если вы хотите использовать HLS с потоками, использующими другие кодеки, вам придется перекодировать их, например, с помощью FFmpeg:
ffmpeg -i rtsp://original-source -pix_fmt yuv420p -c:v libx264 -preset ultrafast -b:v 600k -c:a aac -b:a 160k -f rtsp rtsp://localhost:8554/mystream
Встраивание
Самый простой способ встроить прямую трансляцию на веб-страницу заключается в использовании тега iframe:
<iframe src="http://rtsp-simple-server-ip:8888/mystream" scrolling="no"></iframe>
В качестве альтернативы вы можете создать тег видео, который указывает непосредственно на список воспроизведения потокового видео:
<video src="http://localhost:8888/mystream/index.m3u8"></video>
Пожалуйста, обратите внимание, что большинство браузеров не поддерживают HLS напрямую (кроме Safari); для загрузки потока необходимо использовать библиотеку Javascript, например hls.js. Вы можете найти рабочий пример, просмотрев исходный код мультиплексора HLS.
Вариант с низкой задержкой
HLS с низкой задержкой — это недавно стандартизированный вариант протокола, позволяющий значительно снизить задержку воспроизведения. Он работает путем разделения сегментов на части, которые подаются до завершения сегмента.
LL-HLS по умолчанию отключен. Для его включения необходим сертификат TLS, который может быть сгенерирован с помощью OpenSSL:
openssl genrsa -out server.key 2048 openssl req -new -x509 -sha256 -key server.key -out server.crt -days 3650
Установите параметры hlsVariant, hlsEncryption, hlsServerKey и hlsServerCert в файле конфигурации:
hlsVariant: lowLatency hlsEncryption: yes hlsServerKey: server.key hlsServerCert: server.crt
Каждый поток, опубликованный на сервере, можно прочитать с помощью LL-HLS, посетив:
https://localhost:8888/mystream
Если поток отображается некорректно, попробуйте настроить, например, параметр hlsPartDuration:
hlsPartDuration: 500ms
Уменьшение задержки
в HLS вводится задержка, поскольку клиент должен дождаться, пока сервер сгенерирует сегменты, прежде чем загружать их. Эта задержка составляет 1-5 секунд в зависимости от продолжительности каждого сегмента и 500 мс-3 секунды, если включен вариант с низкой задержкой.
Чтобы уменьшить задержку, вы можете:
-
включите вариант протокола HLS с низкой задержкой, как описано в предыдущем разделе;
-
если включена функция низкой задержки, попробуйте уменьшить параметр hlsPartDuration;
-
попробуйте уменьшить параметр hlsSegmentDuration;
-
Длительность сегмента зависит от интервала между кадрами IDR видеодорожки. Кадр IDR — это кадр, который может быть декодирован независимо от других. Сервер изменяет длительность сегмента, чтобы включить в каждый сегмент хотя бы один кадр IDR. Следовательно, вам необходимо уменьшить интервал между кадрами IDR. Это можно сделать двумя способами:
-
если поток генерируется аппаратно (т. Е. камерой), обычно на странице конфигурации камеры есть настройка, называемая Интервал ключевых кадров
-
в противном случае поток необходимо перекодировать. Интервал между кадрами IDR можно настроить с помощью опции ffmpeg
-g
:ffmpeg -i rtsp://original-stream -pix_fmt yuv420p -c:v libx264 -preset ultrafast -b:v 600k -max_muxing_queue_size 1024 -g 30 -f rtsp rtsp://localhost:$RTSP_PORT/compressed
-