Mediamtx: различия между версиями
Нет описания правки |
Мария (обсуждение | вклад) |
||
(не показано 14 промежуточных версий 2 участников) | |||
Строка 61: | Строка 61: | ||
systemctl start mediamtx # запустить mediamtx сейчас | systemctl start mediamtx # запустить mediamtx сейчас | ||
</syntaxhighlight> | </syntaxhighlight> | ||
= API = | |||
Прежде чем пользоваться API, нужно убедится что использование API включено в конфигурационном файле: | |||
<syntaxhighlight> | |||
api: yes | |||
</syntaxhighlight> | |||
По умолчанию, обращение к API происходит по следующему адресу: | |||
<syntaxhighlight> | |||
http://127.0.0.1:9997 | |||
</syntaxhighlight> | |||
Основные функции API: | |||
* Управление конфигурацией | |||
* Получение информации о текущих трансляциях | |||
* Экспорт и удаление записей трансляций | |||
Пример получения информации о трансляциях: | |||
<syntaxhighlight> | |||
curl http://127.0.0.1:9997/v3/paths/list | |||
{ | |||
"itemCount":1, | |||
"pageCount":1, | |||
"items":[ | |||
{ | |||
"name":"cam", | |||
"confName":"all_others", | |||
"source":{ | |||
"type":"rtmpConn", | |||
"id":"cb8df488-5ee5-4464-b124-ba10f35afb1f" | |||
}, | |||
"ready":true, | |||
"readyTime":"2024-10-21T05:20:19.31856878+04:00", | |||
"tracks":[ | |||
"H264" | |||
], | |||
"bytesReceived":607882609, | |||
"bytesSent":899217011, | |||
"readers":[ | |||
{ | |||
"type":"webrtcSession", | |||
"id":"0aa897f9-bd18-4fd1-8716-8ec8acf15cac" | |||
}, | |||
{ | |||
"type":"webrtcSession", | |||
"id":"f92d8b5f-9da8-48f7-905f-745a3d6de653" | |||
}, | |||
{ | |||
"type":"webrtcSession", | |||
"id":"034e4937-bf94-467f-b714-37221b0129fe" | |||
}, | |||
{ | |||
"type":"webrtcSession", | |||
"id":"f2c003c8-e9df-427e-a1f7-b7915f82eccf" | |||
} | |||
] | |||
}, | |||
] | |||
} | |||
</syntaxhighlight> | |||
[https://bluenviron.github.io/mediamtx/#tag/Recordings Полная документация по API mediamtx тут]. | |||
= Примеры использования = | = Примеры использования = | ||
Строка 69: | Строка 129: | ||
<syntaxhighlight> | <syntaxhighlight> | ||
my_camera: | my_camera: | ||
source: rtsp://login:password@ | source: rtsp://login:password@192.168.10.44:554 | ||
</syntaxhighlight> | </syntaxhighlight> | ||
* my_camera: Это имя вашей трансляции. Его можно использовать в конфигурации MediaMTX для идентификации источника. | * my_camera: Это имя вашей трансляции. Его можно использовать в конфигурации MediaMTX для идентификации источника. | ||
Строка 98: | Строка 158: | ||
* ffmpeg: Команда для запуска программы обработки мультимедиа. | * ffmpeg: Команда для запуска программы обработки мультимедиа. | ||
* -i tcp://192.168.1.1:5555: Указывает исходный поток. Здесь используется TCP-поток с IP квадрокоптера. | * -i tcp://192.168.1.1:5555: Указывает исходный поток. Здесь используется TCP-поток с IP квадрокоптера. | ||
* -c:v libx264: Задает кодек для видео, в данном случае используется H.264, который обеспечивает | * -c:v libx264: Задает кодек для видео, в данном случае используется H.264, который обеспечивает хорошее сжатие и качество. | ||
* -bf 0: Указывает, что не нужно использовать предсказания кадров (B-frames), что может снизить задержку. | * -bf 0: Указывает, что не нужно использовать предсказания кадров (B-frames), что может снизить задержку. | ||
* -c:a libopus: Указывает кодек для аудио (Opus), который подходит для передачи звука. | * -c:a libopus: Указывает кодек для аудио (Opus), который подходит для передачи звука. | ||
Строка 104: | Строка 164: | ||
* rtmp://192.168.1.50/drone: URL, по которому будет отправляться поток. Этот адрес указывает на сервер RTMP, который будет обрабатывать и передавать поток. drone - имя трансляции. | * rtmp://192.168.1.50/drone: URL, по которому будет отправляться поток. Этот адрес указывает на сервер RTMP, который будет обрабатывать и передавать поток. drone - имя трансляции. | ||
* Порт для подключения можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:<syntaxhighlight> INF [RTMP] listener opened on :1935</syntaxhighlight> | * Порт для подключения можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:<syntaxhighlight> INF [RTMP] listener opened on :1935</syntaxhighlight> | ||
=== Просмотр трансляции с квадрокоптера === | === Просмотр трансляции с квадрокоптера === | ||
В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу: | В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу: | ||
Строка 158: | Строка 219: | ||
* Название трансляции smartphone замените на своё | * Название трансляции smartphone замените на своё | ||
* Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:<syntaxhighlight>INF [WebRTC] listener opened on :8889 (HTTP)</syntaxhighlight> | * Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:<syntaxhighlight>INF [WebRTC] listener opened on :8889 (HTTP)</syntaxhighlight> | ||
== Использование API для создания web-приложения == | |||
Для отображения всех трансляций на одной web-странице сделаем простое приложение на python. | |||
# Импортируем модуль '''flask''', предназначенный для создания веб-приложений и модуль '''requests''', упрощающий работу с API через HTTP:<syntaxhighlight lang="python"> | |||
from flask import Flask, render_template_string | |||
import requests | |||
</syntaxhighlight> | |||
# Напишем функцию, которая через запрос к API multimediamtx получает список всех потоков:<syntaxhighlight lang="python"> | |||
import requests | |||
def get_item_names(url): | |||
response = requests.get(url) | |||
if response.status_code == 200: | |||
data = response.json() | |||
return [item['name'] for item in data['items']] | |||
else: | |||
return [f"Error: {response.status_code}"] | |||
</syntaxhighlight> | |||
# Напишем функцию, которая генерирует тело страницы с трансляциями:<syntaxhighlight lang="python"> | |||
ip_address = "127.0.0.1" | |||
port = "9997" | |||
url = f"http://{ip_address}:{port}/v3/paths/list" | |||
@app.route('/') | |||
def index(): | |||
names = get_item_names(url) | |||
return render_template_string(''' | |||
<div class="container"> | |||
{% for name in names %} | |||
<div class="item"> | |||
<iframe src="http://localhost:8889/{{ name }}"></iframe> | |||
<div class="button-container"> | |||
<button onclick="openInNewTab('http://localhost:8889/{{ name }}')"> открыть {{ name }}</button> | |||
</div> | |||
</div> | |||
{% endfor %} | |||
</div> | |||
''', names=names) | |||
</syntaxhighlight> | |||
# Полный код доступен в [https://git.altlinux.org/people/voropaevdmtr/packages/?p=web-for-mediamtx-example.git репозитории]. Пример получившегося интерфейса: | |||
[[Файл:Пример web-приложения для mediamtx.png |776x776пкс]] |
Текущая версия от 18:04, 5 ноября 2024
Введение
MediaMTX — это готовый к использованию и независимый медиасервер реального времени и медиапрокси, который позволяет публиковать, читать, проксировать, записывать и воспроизводить видеопотоки. Он был задуман как «медиамаршрутизатор», который направляет медиапотоки с одного конца на другой.
Возможности:
- Прием видеопотоков с различных источников
- Передача видеопотоков на различные источники
- Автоматическая конвертация видеопотоков из одного формата в другой
- Запись видеопотоков на диск
- Воспроизведение записанных видеопотоков
- Аутентификация пользователей
- Перенаправление читателей на другие RTSP-серверы (балансировка нагрузки)
- Управление сервером через API
- В некоторых случаях подключение видеопотоков не требует какого либо взаимодействия с сервером MediaMTX. Для этого достаточно передать источнику видеопотока url, на котором mediamtx принимает соединения.
- Совместимо с Linux, Windows и macOS, не требует никаких зависимостей или интерпретатора, это единый исполняемый файл.
Установка MediaMTX
# apt-get update
# apt-get install mediamtx
Запуск MediaMTX
$ mediamtx <путь к конфигурационному файлу>
Если путь к конфигурационному файлу не указан, mediamtx будет искать в следующих путях:
- ./rtsp-simple-server.yml (в текущем каталоге)
- ./mediamtx.yml (в текущем каталоге)
- /usr/local/etc/mediamtx.yml
- /usr/etc/mediamtx.yml
- /etc/mediamtx/mediamtx.yml
Пример готового конфигурационного файла можно взять из репозитория
Запуск MediaMTX как service
Создайте файл с именем mediamtx.service в каталоге /etc/systemd/system/:
[Unit]
Description=MediaMTX Service
After=network.target
[Service]
ExecStart=/usr/local/bin/mediamtx #заменить на своё
Restart=on-failure
User=mediamtx
Group=mediamtx
[Install]
WantedBy=multi-user.target
Выполните следующую последовательность команд:
systemctl daemon-reload # обновить список файлов служб
systemctl enable mediamtx # настроить автоматический запуск mediamtx при включении системы
systemctl start mediamtx # запустить mediamtx сейчас
API
Прежде чем пользоваться API, нужно убедится что использование API включено в конфигурационном файле:
api: yes
По умолчанию, обращение к API происходит по следующему адресу:
http://127.0.0.1:9997
Основные функции API:
- Управление конфигурацией
- Получение информации о текущих трансляциях
- Экспорт и удаление записей трансляций
Пример получения информации о трансляциях:
curl http://127.0.0.1:9997/v3/paths/list
{
"itemCount":1,
"pageCount":1,
"items":[
{
"name":"cam",
"confName":"all_others",
"source":{
"type":"rtmpConn",
"id":"cb8df488-5ee5-4464-b124-ba10f35afb1f"
},
"ready":true,
"readyTime":"2024-10-21T05:20:19.31856878+04:00",
"tracks":[
"H264"
],
"bytesReceived":607882609,
"bytesSent":899217011,
"readers":[
{
"type":"webrtcSession",
"id":"0aa897f9-bd18-4fd1-8716-8ec8acf15cac"
},
{
"type":"webrtcSession",
"id":"f92d8b5f-9da8-48f7-905f-745a3d6de653"
},
{
"type":"webrtcSession",
"id":"034e4937-bf94-467f-b714-37221b0129fe"
},
{
"type":"webrtcSession",
"id":"f2c003c8-e9df-427e-a1f7-b7915f82eccf"
}
]
},
]
}
Полная документация по API mediamtx тут.
Примеры использования
Трансляция с IP-камеры
Подключение IP-камеры
Для подключения IP-камеры с RTSP-потоком необходимо добавить в секцию paths следующие строки
my_camera:
source: rtsp://login:password@192.168.10.44:554
- my_camera: Это имя вашей трансляции. Его можно использовать в конфигурации MediaMTX для идентификации источника.
- source: URL потока, указывающий на вашу IP-камеру. В данном случае:
- rtsp:// – протокол передачи данных для потокового видео.
- login:password – учетные данные (логин и пароль) для доступа к камере.
- 192.168.10.44:554 – IP-адрес камеры и порт (обычно 554 для RTSP).
Просмотр видеопотока с IP-камеры
В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу:
http://<ip адрес>:PORT/my_camera
- В качестве ip-адреса укажите адрес, на котором запущен mediamtx.
- Название трансляции my_camera замените на своё
- Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [WebRTC] listener opened on :8889 (HTTP)
Трансляция с квадрокоптера
Подключение квадрокоптера
Для примера возьмем квадрокоптер Parrot AR.Drone 2.0. Штатным способом получения видеопотока является ffplay:
ffplay tcp://192.168.1.1:5555
Для трансляции через mediamtx нам необходимо перекодировать видео с другими кодеками. Для этого нужно выполнить следующую команду на компьютере, находящимся в одной сети с дроном:
ffmpeg -i tcp://192.168.1.1:5555 -c:v libx264 -bf 0 -c:a libopus -f flv rtmp://10.64.128.195/drone
- ffmpeg: Команда для запуска программы обработки мультимедиа.
- -i tcp://192.168.1.1:5555: Указывает исходный поток. Здесь используется TCP-поток с IP квадрокоптера.
- -c:v libx264: Задает кодек для видео, в данном случае используется H.264, который обеспечивает хорошее сжатие и качество.
- -bf 0: Указывает, что не нужно использовать предсказания кадров (B-frames), что может снизить задержку.
- -c:a libopus: Указывает кодек для аудио (Opus), который подходит для передачи звука.
- -f flv: Указывает формат вывода (FLV), используемый для RTMP.
- rtmp://192.168.1.50/drone: URL, по которому будет отправляться поток. Этот адрес указывает на сервер RTMP, который будет обрабатывать и передавать поток. drone - имя трансляции.
- Порт для подключения можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [RTMP] listener opened on :1935
Просмотр трансляции с квадрокоптера
В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу:
http://<ip адрес>:PORT/drone
- В качестве ip-адреса укажите адрес, на котором запущен mediamtx.
- Название трансляции drone замените на своё
- Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [WebRTC] listener opened on :8889 (HTTP)
Трансляция рабочего стола
Подключение трансляции рабочего стола
Для трансляции рабочего стола используется команда, аналогичная предыдущему пункту.
ffmpeg -f x11grab -s 1366x768 -i :0.0 -c:v libx264 -bf 0 -f rtsp rtsp://10.64.128.195:8554/screen
- ffmpeg: Команда для запуска программы обработки мультимедиа.
- -f x11grab: Указывает, что будет использоваться захват экрана из X11 (системы окон Unix).
- -s 1366x768: Устанавливает разрешение захвата экрана; в данном случае 1366x768 пикселей.
- -i :0.0: Указывает дисплей, с которого будет осуществляться захват (обычно это :0.0 для первого дисплея).
- -c:v libx264: Использует кодек H.264 для сжатия видео.
- -bf 0: Отключает использование B-frames.
- -f rtsp: Задает формат вывода (RTSP).
- rtsp://10.64.128.195:8554/screen: URL, по которому будет доступна трансляция рабочего стола.
- Порт для подключения можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [RTMP] listener opened on :1935
Просмотр трансляции с рабочего стола
В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу:
http://<ip адрес>:PORT/screen
- В качестве ip-адреса укажите адрес, на котором запущен mediamtx.
- Название трансляции screen замените на своё
- Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [WebRTC] listener opened on :8889 (HTTP)
Трансляция с камеры телефона
Подключение трансляции с камеры телефона
Для трансляции видео с камеры смартфона можно использовать протокол rtmp. Для этого необходимо скачать приложение, поддерживающее эту функцию и добавить в него url следующего вида:
rtmp://192.168.1.55:1935/smartphone
- rtmp:// - протокол передачи видеопотока
- 192.168.1.55 - ip адрес сервера mediamtx
- 1935 - порт, на котором mediamtx принимает соединения по rtmp
- smartphone - название видеопотока.
- Порт для подключения можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [RTMP] listener opened on :1935
Просмотр трансляции с камеры телефона
В случае успешного подключения видеопоток можно будет посмотреть в браузере по следующему адресу:
http://<ip адрес>:PORT/smartphone
- В качестве ip-адреса укажите адрес, на котором запущен mediamtx.
- Название трансляции smartphone замените на своё
- Порт для просмотра видеопотока по HTTP можно узнать из конфигурационного файла или следующей строки, которую mediamtx выводит в стандартный вывод в первые секунды запуска:
INF [WebRTC] listener opened on :8889 (HTTP)
Использование API для создания web-приложения
Для отображения всех трансляций на одной web-странице сделаем простое приложение на python.
- Импортируем модуль flask, предназначенный для создания веб-приложений и модуль requests, упрощающий работу с API через HTTP:
from flask import Flask, render_template_string import requests
- Напишем функцию, которая через запрос к API multimediamtx получает список всех потоков:
import requests def get_item_names(url): response = requests.get(url) if response.status_code == 200: data = response.json() return [item['name'] for item in data['items']] else: return [f"Error: {response.status_code}"]
- Напишем функцию, которая генерирует тело страницы с трансляциями:
ip_address = "127.0.0.1" port = "9997" url = f"http://{ip_address}:{port}/v3/paths/list" @app.route('/') def index(): names = get_item_names(url) return render_template_string(''' <div class="container"> {% for name in names %} <div class="item"> <iframe src="http://localhost:8889/{{ name }}"></iframe> <div class="button-container"> <button onclick="openInNewTab('http://localhost:8889/{{ name }}')"> открыть {{ name }}</button> </div> </div> {% endfor %} </div> ''', names=names)
- Полный код доступен в репозитории. Пример получившегося интерфейса: