В одном из моих прошлых постов для передачи потокового видео я использовал связку Motion+ffmpeg+ffserver. В принципе, это рабочий вариант, но по какой-то причине ffserver довольно «криво» работал в качестве HTTP-сервера для отдачи видео.
В этот раз мы попробуем пойти другим путем и организовать трансляцию IP-камеры на сайте с помощью VLC Media Player — кроссплатформенного видеоплеера, а также, что наиболее важно в нашем случае, сервера потокового вещания. Сразу оговорюсь, что в качестве формата трансляции был выбран Flash Video (flv). Причин несколько, но самая главная — наличие Flash-плеера в браузере у 99% процентов пользователей Интернет. Конечно, можно выбрать и другой контейнер, например ASF.
Поскольку IP-камера (AXIS), с которой предполагалось вещание выдавала видео в формате MPEG ES, то предварительно его надо было преобразовать в MPEG TS, чтобы потом его можно было транскодировать в FLV.
Общая схема трансляции показана на рисунке ниже.
В качестве TS Muxer, FLV Encoder и FLV Streamer и будет выступать VLC.
Технически же это будет реализовано таким образом, что TS Muxer будет посылать MPEG TS поток по HTTP на порт 8080, откуда его можно будет «забирать», транскодировать в FLV и слать по HTTP на порт 8081. Чтобы было более понятно, проиллюстрирую это примером. Предположим, что все будет происходить на одном сервере (хотя это абсолютно не обязательно). Тогда техническая реализация работы будет следующей:
Приступим к реализации. Как обычно, детали установки приведу для Debian Etch 4.0. VLC будем собирать из исходников.
1. Подготовка:
# !!! НЕ ЗАБУДЬТЕ ДОБАВИТЬ РЕПОЗИТОРИЙ DEBIAN-MULTIMEDIA В APT !!!
apt-get install ffmpeg libavformatcvs51 libavcodeccvs51 libavcodeccvs51-dev libavformatcvs51-dev \
libavutilcvs49-dev libavutilcvs49 libavahi-client3 libavahi-common-dev libpostproccvs51-dev \
libswscalecvs0-dev libswscalecvs0 libxvidcore4-dev libxvidcore4 libx264-dev libx264-54 automake1.9 \
autoconf g++ gcc liba52-0.7.4-dev libdvbpsi3-dev libdvbpsi3 libfaad-dev libfaac-dev libfribidi-dev \
libgcrypt11-dev liblame-dev liblua5.1-0-dev libmad0-dev libmpeg2-4-dev libogg-dev libvorbis-dev \
zlib1g-dev libvcdinfo-dev libiso9660-dev libcddb2-dev libflac-dev
# Скачиваем и собираем LIVE555 Streaming Media
# !!! ВНИМАНИЕ !!! На 4.11.2009 vlc с последней версией live от 28.10.2009 не работает. Проверено.
# http://forum.videolan.org/viewtopic.php?f=13&t=66303
# У меня сохранилась более старая версия, поэтому загружаем отсюда:
wget http://flance.onego.ru/files/live/live.tar.gz
tar xvfz live.tar.gz
cd live
./genMakefiles linux
make
2. VLC:
wget http://download.videolan.org/pub/videolan/vlc/0.9.8a/vlc-0.9.8a.tar.bz2
bzip2 -d vlc-0.9.8a.tar.bz2
tar xvf vlc-0.9.8a.tar
3. Добавляем live555 в дерево исходных текстов VLC:
cp -r $YOUR_LIVE555_BUILD_DIR extras
4. Собираем VLC:
./configure --enable-release --enable-faad --disable-remoteosd --disable-qt4 --disable-skins2 \
--disable-activex --disable-v4l2 --disable-libv4l2 --disable-x11 --disable-xvideo --disable-glx \
--disable-opengl --disable-visual --enable-realrtsp --enable-flac --with-live555-tree=extras/live \
--disable-dbus --disable-hal > /tmp/1 2> /tmp/2
# В файле /tmp/2 можно будет смотреть ошибки и предупреждения процесса конфигурирования
# Если будет какая-нибудь ошибка, то необходимо установить соответствующий пакет Debian и
# запустить configure еще раз
make
5. Запускаем VLC TS Muxer:
'#std{access=http,dst=127.0.0.1:8080,mux=ts}'
6. Запускаем FLV encoder+streamer:
'#transcode{vcodec=FLV1,vb=1024}:std{access=http{mime=video/x-flv},dst=:8081/stream.flv,mux=ffmpeg{mux=flv}}'
6. Интеграция в HTML:
wget http://www.longtailvideo.com/jw/upload/mediaplayer.zip
# Распаковываем и кладем файлы player.swf и swfobject.js в один каталог с предполагаемой
# HTML-страницей, где будем показывать видео
Добавляем следующий HTML-код в страницу:
<div id="mplayer">this will be replaced by the SWF.</div>
<script type="text/javascript">
var so = new SWFObject('player.swf','player','459','375','9');
so.addParam('allowfullscreen','true');
so.addParam('flashvars','start=1&repeat=always&file=http://<адрес потока>&bufferlength=0&autostart=true&displayclick=none&mute=true');
so.write('mplayer');
</script>
Внимание! Параметры start (спасибо Кириллу) и repeat важны.
Все, можно проверять. Хочу еще отметить, что на данный момент VLC с текущей версией FFMPEG для в плане FLV кодирования не работает, поэтому я использовал пакеты Debian. Если кодек FLV1 не нужен, то можно собрать VLC и со свежими FFMPEG и X264.
04.11.2009 ОБНОВЛЕНИЕ:
Важная информация:
1. Для сборки на Debian Lenny 5.0 необходимо добавить в опции конфигурирования VLC на 4 шаге опции --disable-nls и --disable-mozilla, иначе вылезет ошибка о Buggy glibc version.
2. VLC с последней версией liveMedia не стартует. Смотрите комментарии в шаге 1.
Ссылки:
Спасибо!!! Очень полезная статья.
Но у меня есть вопрос.
МОжно ли на основе етого сделать прямые трансляции через сайт, с помощю професионально камеры???
Да, конечно, попробовать организовать можно. Для этого нужно настроить v4l или v4l2 на работу с камерой и запускать VLC для чтения с v4l. Например, ./vlc -I dummy v4l:// < параметры> —sout ‘#transcode{…}:std{http=…}’. Только если хочется нормального качества, то рекомендую использовать муксер asf, а кодек, например, mp4v, ну и выставить нормальный битрейт.
Блин. У меня рюки крюки может, но бьюсь уже битый час.
Не хочет кодировать в FLV
[00000705] main mux error: no sout mux module matched «flv»
[00000701] stream_out_standard stream out error: no suitable sout mux module for `http/flv://0.0.0.0:8081′
Что для этого нужно?
Убедитесь, что используется VLC, версии >=0.9.0 и vcodec=FLV1 (именно с 1 и большими буквами).
Привет!
Параллельно с тобой, очевидно, делали одну и ту же вещь.
посмотреть можно на URL
Камеры D-Link 2102
для vlc конфиг выглядит так:
new kamera1 broadcast enabled
setup kamera1 input «rtsp://87.251.159.6:554/jpeg»
setup kamera1 output #transcode{vcodec=FLV1,vb=1048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/stream.flv}
new kamera2 broadcast enabled
setup kamera2 input «rtsp://87.251.159.8:554/jpeg»
setup kamera2 output #transcode{vcodec=FLV1,vb=1048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8082/stream2.flv}
new kamera3 broadcast enabled
setup kamera3 input «rtsp://87.251.159.9:554/jpeg»
setup kamera3 output #transcode{vcodec=FLV1,vb=1048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8083/stream3.flv}
new kamera4 broadcast enabled
setup kamera4 input «rtsp://87.251.159.10:554/jpeg»
setup kamera4 output #transcode{vcodec=FLV1,vb=1048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8084/stream4.flv}
все круто, кроме!
если установлен flash 9, то autostart в jw flv работает!
а вот если flash 10, то хрен, приходится play нажимать, и буффер ставить, иначе не пашет.
непонятно в какую сторону копать.
причем, есть подозрение, что генерируемый flv в начале какой-то битый, что-ли,то ли метаданные какие-то не передаются, не было подобных симптомов?
экспериментируя, боюсь что-то сломать.
ой, пардон, старый конфиг скинул
не jpeg, конечно, а mp4
вот так
new kamera1 broadcast enabled
setup kamera1 input «rtsp://87.251.159.6:554/mp4»
setup kamera1 output #transcode{vcodec=FLV1,vb=2048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/stream.flv}
Да, такая проблема действительно есть. Но я думаю, что она не обязательно связана с flash 10, может и с в JW Player (экземпляр последней версии, например, не захотел работать). Именно поэтому я добавил repeat=always и bufferlength=0 во flashvars. Проверял в IE, Firefox, Opera с Flash-плеером 10-ой версии, вроде работало. А вообще я еще на всякий случай добавил mms поток…8)
Ты знаешь, удивительным образом, начал ковыряться, добавил всего лишь start=1024 (хотя это же секунды!) и все заработало и в 10-ом.
дурь
ладно, спасибо!
кстати, меня вот интересовало, что мешает разрабочикам vlc сделать нормально чтобы встроенный http не обязательно отдавал потоки на разных портах, а достаточно было бы обычной части url для обращению к разным потокам.
не копал?
мы тут пост собираемся на habrahabr.ru оформить по этому делу, про тебя упомянем, если не против.
Нет, если честно не копал. Но думаю, сделано это было не просто так. Насчет start=1024 — это интересно, надо попробовать…8)
Да, конечно, буду благодарен, если упомянете мой пост со ссылкой.
Действительно, со start>0 проблем нет…8) Обновлю статью.
Интересно. Но есть один вопрос:
можно как-нибудь сделать чтобы flv поток передавался не сразу клиентам, а на еще какой-нибудь сервер — а оттуда уже клиентам?
Думаю, можно. Попробуйте указать в качестве параметра dst IP-адрес этого «другого» сервера. Хотя что мешает просто забирать этот поток сторонним сервером и оттуда уже «раздавать»?
Полезная статья! Спасибо! А на windows это можно организовать?
Я рад, что моя статья оказалась полезной. Насчет Windows, честно говоря, не могу точно сказать. Попробуйте найти и установить одну из последних сборок VLC с FFMPEG для Windows.
Спасибо! Хорошая статья.
Но вот вопросик: видеопоток во флеш-плеер не могу подхватить.
Система построена таким образом:
Один комп под виндой (192.168.0.13), второй — freebsd (он же сервер — 192.168.0.2)
К винде подключена камера. Оттуда vlc по хттп раздает поток.
На сервере подхватываю поток как вы писали, конвертирую в флв и отдаю на 8081/stream.flv:
vlc -vv http://192.168.0.13:8080 .loop .http-caching=10000 .sout #transcode{vcodec=FLV1,vb=1024}:std{access=http{mime=video/x-flv},dst=:8081/stream.flv,mux=ffmpeg{mux=flv}}
Затем пытаюсь в браузере словить поток через флеш плеер. Опять таки так же как вы писали:
var so = new SWFObject(‘mediaplayer.swf’,’player’,’459′,’375′,’9′); so.addParam(‘allowfullscreen’,’true’); so.addParam(‘flashvars’,’start=1024&repeat=always&file=http://192.168.0.2:8081/stream.flv&&bufferlength=0&autostart=true&displayclick=none&mute=true’);
so.write(‘mplayer’);
Но плеер его не видет. В чем может быть проблема?
А VLC на FreeBSD, который забирает поток с 192.168.0.13 ничего в отладочной информации не показывает противоестественного? Попробуйте сначала просто сделать wget 192.168.0.2:8081/stream.flv и проверить идет ли FLV-поток вообще.
Та же история. Пробую делать трансляцию через VLM.
new camera broadcast enabled
setup camera input «rtsp://192.168.0.99:554/live.sdp»
setup camera output #transcode{vcodec=FLV1,vb=512}:duplicate{dst=std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=127.0.0.1:8080/stream.flv}}
Исходящий поток удается увидеть только в самом vlc, если указать dst=display.
Другие плееры не подключаются.
Камера у меня D-Link DSC 2120. Вещает в mpeg-4.
А почему dst=127.0.0.1:8080/stream.flv?
Кстати, качество картинки, которую показывает vlc на выходе резко падает через несколько секунд после запуска трансляции.
Возможно потому, что я плохо шарю. :)
Я на локалхосте проверяю. Поэтому так и выставил.
Качество картинки может зависеть от ffmpeg, битрейта и т.д. Если веб-страница с плеером открывается на локалхосте, где запущен VLC, то можно и так указать.
Читал форум videolan. С качеством у многих проблемы. Битрейт никак не влияет. Говорят, FLV1 — плохой кодек :)
Можете немного конкретнее расписать блок с кодом для флеш-плеера? У многих проблеммы. Допустим VLC проигрывает поток через http протокол на порт 8080 по IP-адресу 67.234.90.12 Как его теперь флешом поймать?
Если FLV-поток отдается по URL http://67.234.90.12:8080 и его можно просмотреть с помощью VLC, то соответствующая строка в кода с flash-плеером будет иметь вид:
…
so.addParam(‘flashvars’,’start=1&repeat=always&file=http://67.234.90.12:8080&bufferlength=0&autostart=true&displayclick=none&mute=true
…
Методом, описанным вами почему-то не получается. Пишет «this will be replaced by the SWF.» Я пробовал написать другой код.(применяется в примере самого лонгтейл плеера)
swfobject.registerObject(«player»,»9.0.98″,»expressInstall.swf»);
Get Flash to see this player.
Но и так не хочет работать. Пишет, что файл XML повреждён
В прошлом коментарии все теги были сьедены=) Но думаю, что вы меня поняли
Моя неточность. В коде не было написано строчки подключения javascript-библиотеки SWFObject. Проверьте, что эта библиотека подключена. И http://code.google.com/p/swfobject/wiki/documentation Вам в помощь.
А кто может подсказать как реализовать вот такую схему, есть поток mjpeg, который я захватываю vlc и раздаю его как http, но к этому потоку нужно еще приколбасить звук, как орагнизовать это. Звук идет от микрофона.
Короче как с миксовать два потока(звук и видео) в один и потом его раздовать?
OS MS Windows Vista
Привет всем!
А железа какого будет достаточно для такого он-лайн вещания?
Современного обычного компьютера, думаю, хватит…8)
Спасибо, очень познавательно. Не подскажите, какими должны быть характеристики канала, чтобы трансляцию могла смотреть, допустим, тысяча юзеров? И есть ли возможность брать звук не с камеры, а отдельно, например с пульта?
Кто разобрался? Сколько будет стоить организация такого под ключ? Жду ваших предложений mail@telsystems.ru
Waster, сорри, долго не отвечал, на то что вы мне писали. Но мы вот с админом разобрались и вроде все настроили. ) Остался только такого рода вопросик:
мне надо запаролить этот поток. грубо говоря открывать только залогиненным и т.п. Пробовал реализовать через промежуточный php-скрипт, указывал для плеера в качестве источника не сам поток а скрипт, который соответственно должен в случае успешной авторизации его отдать. Но вот как оперировать с потоком на php не разобрался, именно как его правильно открыть и отдать назад плееру. Может у вас есть какие-то решения?
К сожалению, у меня нет таких решений. Попробуйте посмотреть нужный кусок кода для работы с flv-потоком на http://xmoov.com/xmoov-php/source или на http://www.flashcomguru.com/index.cfm/2005/11/2/Streaming-flv-video-via-PHP-take-two
Большое спасибо за статью!) Интересный эффект — поток идет, но постоянно повторяется, причем такое впечатление как будто кэшируется и время повторяемого фрагмента с каждым разом становится больше. Подскажите в чем может быть проблема? HTML-rод полностью повторяет Ваш.
Попробуйте просмотреть поток не flash-плеером, а, например, vlc или mplayer и поиграйтесь с параметрами start и bufferlength. Может быть причина еще и в нехватке канала?
На vlc идет но со звуком проблема (то появляется то пропадает), заметил разницу с частотой кадров — флеш на страничке играет похоже 25, а исходный поток у меня 1 кадр/с. Причем в vlc нормальный 1 кадр/с в transcode параметр fps=1 я добавил
Получается ужасная картинка: http://spline.ifmo.ru/cam2/
Не подскажете, что может быть не так? Исползую FLV1, и есть подозрение, что какие-то проблемы с кодеком, именно в ОС (FreeBSD 7.1-RELEASE). Стоит ffmpeg-2008.07.27_10 из портов, vlc-0.9.9.a_1,3 — оба из портов. Битрейт пробовал разный — не влияет.
Еще момент: я продовал wget’ать
wget http://localhost:8081/cam.flv
Resolving localhost… 127.0.0.1
Connecting to localhost|127.0.0.1|:8081… connected.
HTTP request sent, awaiting response… 200 OK
Length: unspecified [video/x-flv]
— почему-то очень низкая скорость, 3.28K/s, 2.76K/s и т.д. Может тут проблема?
Конфиг:
setup kamera output #transcode{vcodec=FLV1,vb=2048,acodec=mp3,samplerate=22050}:std{access=http{mime=video/x-flv},mux=ffmpeg{mux=flv},dst=0.0.0.0:8081/cam.flv,delay=1000}
Попробуйте другой кодек, например
setup kamera output «#transcode{vcodec=DIV3,vb=1024}:std{access=mmsh,dst=:8082,mux=asfh}
Будут ли лучше результаты? Также не могу сказать влияет ли параметр delay=1000 на скорость.
Пробую. Кодек такой есть, запустилось, камера вещает. А как поймать это вещание клиентом? Как я понимаю, это Microsoft ASF? То есть будет http://192.168.2.4:8082/? Что-то не работает =(
Вещание можно поймать, например, тот же VLC, указав URL потока как mms://192.168.2.4:8082/.
Код для вставки в HTML можно легко найти в сети. Если возникнут сложности, добавлю в статью примечание насчет ASF.
Выяснился еще такой момент: если согласно указанных выше настроек запускать vlc под виндой он отдает http-поток в виде http://IP:port/ независимо от наличия в задающей строке имени файла в потоке. А под линуксом получается http://IP:port/file.flv
Пробую под виндой и ничего не работает вообще. VLС просто ничего не делает и никаких ошибок не выдает. Никто не знает, нужны ли какие-то библиотеки? FFMPEG, например, как внедрять в винду?
Насколько мне известно, VLC под Windows уже имеет все необходимое с собой.
ivan@userver:~/vlc-0.9.8a$ ./configure –enable-release –enable-faad –disable-remoteosd –disable-qt4 –disable-skins2 –disable-activex –disable-v4l2 –disable-libv4l2 –disable-x11 –disable-xvideo –disable-glx –disable-opengl –disable-visual –enable-realrtsp –enable-flac –with-live555-tree=extras/live –disable-dbus –disable-hal
вот что выдает:
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –enable-release
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –enable-faad
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-remoteosd
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-qt4
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-skins2
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-activex
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-v4l2
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-libv4l2
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-x11
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-xvideo
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-glx
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-opengl
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –disable-visual
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –enable-realrtsp
configure: WARNING: you should use —build, —host, —target
configure: WARNING: invalid host type: –enable-flac
configure: error: invalid variable name: –with-live555-tree
Как вы могли с такими ключами собрать?
В опциях конфигурирования в начале должны стоять два дефиса. Просто движок сайта заменяет их на длинное тире. Постараюсь исправить эту проблему.