LINUX.ORG.RU

Live video streaming with libffmpeg

 ,


0

1

В который раз возникает необходимость отображать в браузере свежесгенерированный видеоряд (данные с камеры после небольшой обработки). Обычно я решал это совсем уродским способом: генерировал jpeg файл куда-нибудь, а в браузере жабоскриптом 2-3 раза в секунду менял источник <img>. Но это неэффективно. Другой способ — отправлять клиенту по вебсокету очередной jpeg, что тоже не очень хорошо, т.к. связано с накладными расходами (изображение приходится кодировать в base64, а потом браузер его должен раскодировать, прежде, чем показать).

Вот и возникла идея — гнать «живой» видеопоток. Коллега мне настойчиво предлагает решить проблему именно так. Но меня, похоже, забанили в гугле, т.к. я вообще не нахожу вариантов, как это сделать при помощи libffmpeg! Ведь здесь по сути идет непрерывная трансляция, да еще и с переменным количеством кадров в секунду (в зависимости от освещенности экспозиция может быть как 20мс, так и пару секунд).

Вопрос: как в 2021 году правильно решить проблему отображения «живого» видео с переменным fps в браузере?

☆☆☆☆☆

Вот и возникла идея — гнать «живой» видеопоток. Коллега мне настойчиво предлагает решить проблему именно так.

Обычно я решал это совсем уродским способом: генерировал jpeg файл куда-нибудь, а в браузере жабоскриптом 2-3 раза в секунду менял источник

Вы можете сойтись на компромиссе :)

как это сделать при помощи libffmpeg

В чем проблема? Берешь любой output format (mjpeg, mpegts, …) и вперед? Стрим конечно нужно доставлять клиенту каким-то образом (ffmpeg может сам сервить, а может отдавать поток чему угодно для дальнейшей раздачи)

derlafff ★★★★★
()
Последнее исправление: derlafff (всего исправлений: 1)
Ответ на: комментарий от derlafff

Вы можете сойтись на компромиссе :)

С mjpeg проблема в том, что если браузер постоянно получает поток данных с разделителями, то старые он не удаляет. В итоге через несколько часов в лучшем случае OOM-killer прибьет вкладку браузера.

Берешь любой output format (mjpeg, mpegts, …) и вперед?

Хотелось бы MWE. Вот с этим и возникли проблемы.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

С mjpeg проблема в том, что если браузер постоянно получает поток данных с разделителями, то старые он не удаляет. В итоге через несколько часов в лучшем случае OOM-killer прибьет вкладку браузера.

это какой-то новый броузер ? :-) ни разу не замечал (даже и не слышал) чтобы видео в mjpeg с камер вешало или прибивало броузер.

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

Все известные браузеры этим страдают: и хром, и огнелис. Ну, по крайней мере, так было лет 5 назад.

Ну и вообще, хотелось бы все же RTSP какой-нибудь замутить, чтобы нативно браузером поддерживался и не было проблем с синхронизацией.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от anonymous

Ну не буду же я перечислять всю эту толпу:

/usr/lib64/libavdevice.so
/usr/lib64/libavformat.so
/usr/lib64/libavfilter.so
/usr/lib64/libavresample.so
/usr/lib64/libpostproc.so
/usr/lib64/libswresample.so
/usr/lib64/libavcodec.so
/usr/lib64/libswscale.so

вот и обозвал условно.

Eddy_Em ☆☆☆☆☆
() автор топика
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

С mjpeg проблема в том, что если браузер постоянно получает поток данных с разделителями, то старые он не удаляет. В итоге через несколько часов в лучшем случае OOM-killer прибьет вкладку браузера.

Пользовался софтом с mjpeg, такой проблемы не замечал

derlafff ★★★★★
()
Ответ на: комментарий от Eddy_Em

Ну, по крайней мере, так было лет 5 назад.

Когда ты сидел на необновленном раче 2011 года? :)

derlafff ★★★★★
()
Ответ на: комментарий от Eddy_Em

ни знаю откуда у вас такое, но не было такого никогда..тем паче 5 лет назад :-)

и RTSP тоже позволяет mjpeg :-)

матчасть что-ли почитайте

MKuznetsov ★★★★★
()
Ответ на: комментарий от Harald

Не прокатит в видеоплеере: нужен интерактив. Помимо кнопочек/менюшек еще и само изображение активно (как минимум, выбрать координаты нужной звезды).

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от MKuznetsov

Вот полез я в свой код различной давности. И везде я обновлял изображение через жабоскрипт (кроме попыток отправлять изображения через вебсокет). Но точно помню, что было и с mjpeg дело. Видимо, это лет 12 назад было — забыл уже даже, где эти файлы искать (тогда у меня еще не было привычки на гитхаб все выкладывать)…

Eddy_Em ☆☆☆☆☆
() автор топика

гугли mse и webrtc эдя, энивей все равно говно слепишь; очередной братишка - мне проста камерку в интернет стримануть

anonymous
()
Ответ на: комментарий от Eddy_Em

Не прокатит в видеоплеере: нужен интерактив. Помимо кнопочек/менюшек еще и само изображение активно (как минимум, выбрать координаты нужной звезды).

выбрать координаты звезды (мелкий почти пиксель) в любом видеопотоке, это некоторый гарантированный секс, почти женитьба. Звезды размыты, имеют ореолы и потенциально «дёргаются».

отдать видео в потоке из подготовленных картинок, есть в разных howto и гуглах. Я бы честно смотрел в сторону gstreamer - можно сделать подходящий конвеер (подобрав/написав доп.плагин), который ещё и интерактивные команды сможет воспринять. Но это на транслирующей стороне. Милисекундные задержки в трансляции вас вряд-ли волнуют, поэтому такой конвеер самое оно.

MKuznetsov ★★★★★
()

RTMP, nginx (nginx-mod-rtmp), mpeg-dash, hls и плеер на JS для одного из двух последних. Тебе в любом случае нужен mpeg-dash или HLS.

anonymous-angler ★☆
()
Ответ на: комментарий от anonymous-angler

Вообще мимо.

Я вот не понимаю: веб уже черт знает сколько развивается, а «живое» видео с неопределенным количеством кадров в секунду до сих пор по-старинке в виде mjpeg транслируют что ли? Неужто больше вариантов нет?

Вот как, например, веб-морды камер наблюдения работают? Неужели они тоже уйму потоков mjpeg отдают клиенту?

Дурость какая-то…

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от MKuznetsov

Звезды размыты, имеют ореолы и потенциально «дёргаются».

Да и пусть. Главное — определить, в какие координаты изображения ткнул пользователь мышей. А потом я просто из списка отождествленных объектов найду ближайший к этой точке.

gstreamer

Вообще мимо. Зачем мне эта жирная дрянь, когда есть более легкие вещи? Тупо mjpeg генерировать я могу с помощью STB (надо, кстати, обновить репу, я уже достаточно много накалякал; сегодня начал добавлять поддержку сети для управления через netcat — баш-скриптами — или веб-демон).

Похоже, придется mjpeg рукоблудить, чтобы на коллегу не взваливать еще и это. Он и так веб-сервер с нуля рисует, хотя у меня уже «зайчатки» есть на libonion (но «в продакшн» это не хочется отдавать, т.к. я уже нашел несколько багов в этой библиотеке, ХЗ, сколько их там еще не найденных).

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Почему мимо то? MPEG-DASH нарезает поток RTMP на куски (по несколько секунд) и выстраивает из них динамический плейлист, который бесшовно играется JS плеером. Для рилтайма есть WebRTC, но тебе вроде не нужно.

anonymous-angler ★☆
()
Ответ на: комментарий от anonymous-angler

Ну и зачем мне это? Вот представь: идет у меня поток, 1 кадр за 0.5-2 секунды. А эта фигня начнет его буферизовать и отдавать по нескольку кадров. И кирдык рилтайму! Увидит юзер звездочку, тыкнет по ней, а ее там уже и нет давно…

А мне нужно, чтобы из картинки получался базовый кадр, а дальше уже вейвлетами к нему вычислялись дополнения и передавались клиенту. В итоге трафик очень сильно мог бы уменьшиться (скажем, не 100кБ в секунду, а 20кБ). Ну, а чтобы вновь подключившиеся могли почти сразу картинку видеть, можно раз в 10 секунд базовый кадр пересчитывать.

Eddy_Em ☆☆☆☆☆
() автор топика
Последнее исправление: Eddy_Em (всего исправлений: 1)
Ответ на: комментарий от Eddy_Em

А, т.е. 2-3 кадра - это задумка, а не костыль, окей. Тогда не вижу проблемы в том что бы слать JPEG через вебсокет. и это, есть Blob - может тебе оно нужно?

anonymous-angler ★☆
()
Ответ на: комментарий от anonymous-angler

О, спасибо! Оказывается, можно было сделать вот так:

var myImage = document.querySelector('img');

fetch('flowers.jpg').then(function(response) {
  return response.blob();
}).then(function(myBlob) {
  var objectURL = URL.createObjectURL(myBlob);
  myImage.src = objectURL;
});
а не мучиться с base64, как я делал несколько лет назад…

Тогда все упрощается: я по запросу буду отдавать jpeg'и в своем велосипеде, а веб-сервер будет уже их отсылать через вебсокет клиентам (вебсокеты нонче поддерживают тип blob).

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

Тогда все упрощается: я по запросу буду отдавать jpeg’и в своем велосипеде, а веб-сервер будет уже их отсылать через вебсокет клиентам (вебсокеты нонче поддерживают тип blob).

веб-сокеты отдают блобы с рождения и от проекта..у них конечно два режима работы - бинарный,текстовый, но оба касаются только служебной части.

что-ж блин за ерунда - нафига вы ищите грабли где их нет ? ну хоум-видео-же..звёзды вместо грудастых див, но всё равно разрешение, цветность и всякое-такое вам вдоль и пофик…отдали стрим в , взяли разрешение с двух сторон и странслировали координаты. Ещё раз - сделать видео из серии картинок на стороне сервера - это из FAQ везде.

конечно засада в js и зоопарке устройств принимающих сторон - но тогда так и формулируйте. «могу дать дать поток-другой видео, надо позиционировать event-ы по нему в исходных координатах» на js

MKuznetsov ★★★★★
()
Ответ на: комментарий от MKuznetsov

сделать видео из серии картинок на стороне сервера - это из FAQ везде.

Нет такого нигде! Потому что «серия картинок» не на диске лежит, а генерируется в реальном времени. И текущий кадр нужно с минимальными задержками отобразить на экране у пользователя.

Eddy_Em ☆☆☆☆☆
() автор топика
Ответ на: комментарий от Eddy_Em

пруф где что генерируется в реальном времени ?

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.