GStreamer учебная песочница

Конвейер

Видео в GStreamer собирают как трубопровод: источник → обработка → приёмник. Включайте элементы, крутите свойства, и справа сразу видно результат и команду, которая это делает.

videotestsrc — источникsource

Настоящей камеры на сервере нет, поэтому кадры рисует тестовый генератор. На ноутбуке с вебкамерой вместо него был бы v4l2src, для IP-камеры — rtspsrc. Всё остальное в конвейере от этого не меняется.

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 живёт отдельно.

Откуда берутся элементы: плагины

Элементы упакованы в плагины, плагины — в наборы с говорящими именами:

Посмотреть, что установлено: gst-inspect-1.0 (список всего), gst-inspect-1.0 x264enc (свойства одного элемента и его caps).

gst-launch-1.0: язык описания конвейера

gst-launch-1.0 v4l2src device=/dev/video0 \
  ! video/x-raw,width=1280,height=720,framerate=30/1 \
  ! videoconvert ! x264enc tune=zerolatency bitrate=2000 \
  ! rtph264pay ! udpsink host=192.168.1.10 port=5000

Читается слева направо: камера → ограничили формат → перевели в формат, который понимает кодер → сжали в 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 в каждой ветке — без них ветки блокируют друг друга.

Типичные задачи

ЗадачаКонвейер
Проиграть что угодноgst-launch-1.0 playbin uri=file:///path/video.mp4
Снять кадр с вебкамеры в JPEGv4l2src num-buffers=1 ! videoconvert ! jpegenc ! filesink location=shot.jpg
Записать IP-камеру без перекодированияrtspsrc location=rtsp://cam/stream ! rtph264depay ! h264parse ! mp4mux ! filesink location=rec.mp4
Резать запись на файлы по 10 минут… ! h264parse ! splitmuxsink location=rec%03d.mp4 max-size-time=600000000000
HLS для браузера… ! x264enc ! h264parse ! hlssink2 location=seg%05d.ts playlist-location=live.m3u8
Своя программа получает кадры… ! videoconvert ! appsink — и читаете буферы из Python/C/Rust

Где GStreamer, а где нет

FFmpeg — утилита «вход → выход» с огромным числом форматов; хорош для перекодирования файлов и простого стриминга. GStreamer — каркас для программ, где поток живёт долго, ветвится, меняется на ходу, встраивается в приложение (через API на C, Python, Rust). mediamtx, который уже крутится на этом сервере, — готовый медиасервер (RTSP/WebRTC/HLS), ему можно отдавать поток из GStreamer через rtspclientsink, и он раздаст его браузерам.

Отладка

Шпаргалка

Элементы, которые встречаются чаще всего

РольЭлементЗачем
sourcev4l2srcвебкамера / USB-камера в Linux (device=/dev/video0)
rtspsrcIP-камера, RTSP-сервер (location=rtsp://…, latency=200)
filesrc + decodebinфайл; decodebin сам подберёт демультиплексор и декодер
videotestsrc / audiotestsrcтестовые генераторы (как в песочнице)
appsrcкадры подаёт ваша программа
filtervideoconvert, videoscale, videorateформат пикселей, размер, частота кадров
capsfilter (запись video/x-raw,…)потребовать конкретный формат
x264enc, avdec_h264, jpegenc, jpegdecкодеры и декодеры
h264parseразбирает поток H.264 на кадры — нужен перед муксерами и после rtph264depay
rtph264pay / rtph264depayупаковка в RTP для передачи по сети
queue, tee, identityбуфер + новый поток, ветвление, отладка
sinkautovideosinkокно на экране
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 всё)

Частые ошибки

Что с этим делать дальше

Поставьте 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. Получите тот же конвейер, но с настоящей камерой и окном на экране.