Видео в GStreamer собирают как трубопровод: источник → обработка → приёмник. Включайте элементы, крутите свойства, и справа сразу видно результат и команду, которая это делает.
videotestsrc — источникsource
Настоящей камеры на сервере нет, поэтому кадры рисует тестовый генератор. На ноутбуке с вебкамерой вместо него был бы v4l2src, для IP-камеры — rtspsrc. Всё остальное в конвейере от этого не меняется.
Браузер снимает кадры с вашей камеры, сжимает в JPEG и шлёт на сервер по HTTPS. Там они попадают в именованный канал (FIFO), а GStreamer читает его как файл: filesrc ! jpegparse ! jpegdec. Кадры нигде не сохраняются. На самом сервере с камерой весь этот обходной путь заменила бы одна строчка v4l2src.
запрашиваю доступ к камере…
jpegenc → multipartmux → fdsink — приёмникsink
Хвост конвейера фиксирован: каждый кадр сжимается в JPEG, кадры склеиваются в MJPEG-поток и отдаются в stdout, откуда PHP-скрипт пересылает их в браузер. В боевой системе здесь стояли бы x264enc ! rtph264pay ! udpsink или запись в файл.
запускаю…
Командато же самое можно запустить в терминале на любой машине с GStreamer
Как читать эту команду
! — «труба»: выход левого элемента соединяется со входом правого.
имя=значение после элемента — его свойство. Полный список свойств любого элемента показывает gst-inspect-1.0 имя (кнопка «inspect» на карточке).
video/x-raw,width=480,… — это не элемент, а caps: ограничение формата. gst-launch сам вставляет туда capsfilter.
videoconvert между элементами — переходник между форматами пикселей (RGB, I420, …). Он нужен не всегда, но безопасен: если формат уже подходит, он просто пропускает данные.
-q — не печатать прогресс в stdout, ведь туда мы пишем видео.
Источник «моя камера»: filesrc location=…fifo do-timestamp=true ! jpegparse ! jpegdec — читаем поток JPEG-кадров из канала, jpegparse режет его на кадры, jpegdec распаковывает в сырое видео. do-timestamp ставит кадрам время по часам конвейера, иначе videorate не поймёт, когда они пришли.
Что такое GStreamer
GStreamer — это библиотека и набор плагинов для работы с медиапотоками: видео, звук, субтитры. Она не «плеер» и не «кодек», а конструктор: из готовых блоков вы собираете цепочку обработки, а GStreamer гоняет через неё данные, следит за временем и форматами. На нём работают плееры в Linux, системы видеонаблюдения, стриминг, вещание, обработка видео на встраиваемых платах (Raspberry Pi, NVIDIA Jetson).
Четыре слова, без которых не обойтись
Элемент (element)
Один блок с одной обязанностью: читать файл, декодировать H.264, повернуть кадр, отправить в сеть. Элементы бывают трёх ролей: source (только выход: камера, файл, сеть), filter (вход и выход: кодеки, эффекты, конвертеры), sink (только вход: экран, файл, сеть).
Пад (pad)
«Разъём» элемента. Выходной пад называется src, входной — sink (да, так же, как роли элементов, это путает всех новичков). Знак ! в gst-launch соединяет src-пад левого элемента с sink-падом правого.
Caps (capabilities)
Описание формата данных на паде: video/x-raw, format=I420, width=1280, height=720, framerate=30/1. При соединении падов GStreamer договаривается о caps (negotiation). Если договориться нельзя — конвейер не запустится с ошибкой «not-negotiated». В песочнице это видно: строки video/x-raw,… в команде и есть caps.
Конвейер (pipeline)
Контейнер, в котором живут элементы. У него есть общие часы и состояние: NULL → READY → PAUSED → PLAYING. Внутри можно группировать элементы в bin — «элемент из элементов». decodebin, playbin — это bin'ы, которые сами подбирают нужные элементы под формат файла.
Как данные текут
По конвейеру ходят буферы (кусок данных с временной меткой) и события (конец потока, перемотка, смена caps). Источник ставит на буфер время, приёмник (sync=true по умолчанию) ждёт этого времени по часам конвейера и только тогда показывает кадр. Поэтому videotestsrc в песочнице запущен с is-live=true: без этого он генерирует кадры со всей скоростью процессора, как при перекодировании файла.
Элемент queue делит конвейер на потоки ОС и копит буферы. Это главный инструмент против «тормозит захват, потому что медленный кодер»: всё после queue живёт отдельно.
Откуда берутся элементы: плагины
Элементы упакованы в плагины, плагины — в наборы с говорящими именами:
base — фундамент: videoconvert, videoscale, audioconvert, playbin, decodebin.
good — качественные, с чистой лицензией: v4l2src (вебкамера), jpegenc, rtspsrc, udpsink, эффекты *tv, matroskamux.
bad — работают, но API ещё может меняться: webrtcbin, hlssink2, gaussianblur, coloreffects, много кодеков.
ugly — хорошие, но с патентными/лицензионными вопросами: x264enc, mp3.
libav — обёртка над FFmpeg: декодеры почти всего (avdec_h264).
Посмотреть, что установлено: gst-inspect-1.0 (список всего), gst-inspect-1.0 x264enc (свойства одного элемента и его caps).
Читается слева направо: камера → ограничили формат → перевели в формат, который понимает кодер → сжали в H.264 → упаковали в RTP → отправили по UDP. Так выглядит простейшая «камера → сеть». Принимающая сторона — зеркальный конвейер: udpsrc ! rtph264depay ! avdec_h264 ! videoconvert ! autovideosink.
Ветвление делает tee: один поток и на экран, и в файл: … ! tee name=t t. ! queue ! autovideosink t. ! queue ! x264enc ! mp4mux ! filesink location=out.mp4. Обратите внимание на queue в каждой ветке — без них ветки блокируют друг друга.
… ! videoconvert ! appsink — и читаете буферы из Python/C/Rust
Где GStreamer, а где нет
FFmpeg — утилита «вход → выход» с огромным числом форматов; хорош для перекодирования файлов и простого стриминга. GStreamer — каркас для программ, где поток живёт долго, ветвится, меняется на ходу, встраивается в приложение (через API на C, Python, Rust). mediamtx, который уже крутится на этом сервере, — готовый медиасервер (RTSP/WebRTC/HLS), ему можно отдавать поток из GStreamer через rtspclientsink, и он раздаст его браузерам.
Отладка
GST_DEBUG=3 gst-launch-1.0 … — предупреждения и ошибки; GST_DEBUG=4 — подробнее; GST_DEBUG=videoflip:6 — только один элемент.
gst-launch-1.0 -v … — печатает согласованные caps на каждом паде. Первое, что смотреть при «not-negotiated».
GST_DEBUG_DUMP_DOT_DIR=/tmp gst-launch-1.0 … — рисует граф конвейера в .dot (Graphviz).
gst-discoverer-1.0 файл — что внутри файла: контейнер, кодеки, разрешение, длительность.
Шпаргалка
Элементы, которые встречаются чаще всего
Роль
Элемент
Зачем
source
v4l2src
вебкамера / USB-камера в Linux (device=/dev/video0)
файл; decodebin сам подберёт демультиплексор и декодер
videotestsrc / audiotestsrc
тестовые генераторы (как в песочнице)
appsrc
кадры подаёт ваша программа
filter
videoconvert, videoscale, videorate
формат пикселей, размер, частота кадров
capsfilter (запись video/x-raw,…)
потребовать конкретный формат
x264enc, avdec_h264, jpegenc, jpegdec
кодеры и декодеры
h264parse
разбирает поток H.264 на кадры — нужен перед муксерами и после rtph264depay
rtph264pay / rtph264depay
упаковка в RTP для передачи по сети
queue, tee, identity
буфер + новый поток, ветвление, отладка
sink
autovideosink
окно на экране
filesink + mp4mux/matroskamux
запись в файл
udpsink, rtspclientsink, hlssink2
в сеть: UDP/RTP, на RTSP-сервер, HLS-сегменты
appsink
кадры забирает ваша программа
fakesink
выбросить (для тестов производительности)
Команды
gst-inspect-1.0
все установленные элементы
gst-inspect-1.0 videoflip
свойства, сигналы и caps элемента
gst-launch-1.0 -v …
запустить конвейер, показать согласованные caps
gst-discoverer-1.0 файл
разобрать, что внутри медиафайла
gst-play-1.0 файл
простой плеер для проверки
GST_DEBUG=3 …
уровень логов (1 ошибки … 9 всё)
Частые ошибки
«could not link X to Y» или not-negotiated — форматы не совпали. Вставьте videoconvert / audioconvert, проверьте caps через -v.
Конвейер «висит» и ничего не показывает — не хватает queue в ветках после tee, или sink ждёт по часам буферы с временем в прошлом (sync=false для проверки).
Огромная задержка при стриминге — у x264enc нужен tune=zerolatency, у rtspsrc уменьшить latency, у приёмника убрать лишние буферы.
Элемент не найден — не установлен нужный набор плагинов (good/bad/ugly/libav). Проверьте gst-inspect-1.0 имя.
Что с этим делать дальше
Поставьте GStreamer на ноутбук (apt install gstreamer1.0-tools gstreamer1.0-plugins-{base,good,bad,ugly} gstreamer1.0-libav, на macOS — brew install gstreamer), скопируйте команду из песочницы и замените videotestsrc … на v4l2src (Linux) или avfvideosrc (macOS), а хвост jpegenc ! multipartmux ! fdsink — на autovideosink. Получите тот же конвейер, но с настоящей камерой и окном на экране.