magnify
Home arrow Администрирование arrow Организация видеотрансляции на сайте
formats

Организация видеотрансляции на сайте

Опубликовано: 09.02.2009 Автор: в

В одном из моих прошлых постов для передачи потокового видео я использовал связку 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:

# На время написания статьи самая свежая стабильная версия - 0.9.8a
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:

cd vlc-0.9.8a
cp -r $YOUR_LIVE555_BUILD_DIR extras

4. Собираем VLC:

# Поскольку мне не нужен был 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:

./vlc -vv --no-rtsp-tcp rtsp://<URL потока> --rtsp-caching=10000 --no-sout-audio --sout \
'#std{access=http,dst=127.0.0.1:8080,mux=ts}'

6. Запускаем FLV encoder+streamer:

./vlc -vv http://127.0.0.1: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}}'

6. Интеграция в HTML:

# Скачиваем flash-плеер, я рекомендую JW FLV Media Player, но можно попробовать и другой
wget http://www.longtailvideo.com/jw/upload/mediaplayer.zip
# Распаковываем и кладем файлы  player.swf и swfobject.js в один каталог с предполагаемой
# HTML-страницей, где будем показывать видео

Добавляем следующий HTML-код в страницу:

<script type="text/javascript" src="swfobject.js"></script>
<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&amp;repeat=always&amp;file=http://<адрес потока>&amp;bufferlength=0&amp;autostart=true&amp;displayclick=none&amp;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.

Ссылки:

  1. http://www.videolan.org
  2. http://www.ffmpeg.org
  3. http://www.live555.com/liveMedia
  4. http://www.longtailvideo.com/players/jw-flv-player
 
Просмотров: 40 613 | 100 комментариев  comments 

100 комментариев

  1. Rocklviv

    Спасибо!!! Очень полезная статья.
    Но у меня есть вопрос.
    МОжно ли на основе етого сделать прямые трансляции через сайт, с помощю професионально камеры???

  2. Да, конечно, попробовать организовать можно. Для этого нужно настроить v4l или v4l2 на работу с камерой и запускать VLC для чтения с v4l. Например, ./vlc -I dummy v4l:// < параметры> —sout ‘#transcode{…}:std{http=…}’. Только если хочется нормального качества, то рекомендую использовать муксер asf, а кодек, например, mp4v, ну и выставить нормальный битрейт.

  3. Fern

    Блин. У меня рюки крюки может, но бьюсь уже битый час.
    Не хочет кодировать в 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′

    Что для этого нужно?

  4. Убедитесь, что используется VLC, версии >=0.9.0 и vcodec=FLV1 (именно с 1 и большими буквами).

  5. Кирилл

    Привет!
    Параллельно с тобой, очевидно, делали одну и ту же вещь.
    посмотреть можно на 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 в начале какой-то битый, что-ли,то ли метаданные какие-то не передаются, не было подобных симптомов?
    экспериментируя, боюсь что-то сломать.

  6. Кирилл

    ой, пардон, старый конфиг скинул
    не 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}

  7. Да, такая проблема действительно есть. Но я думаю, что она не обязательно связана с flash 10, может и с в JW Player (экземпляр последней версии, например, не захотел работать). Именно поэтому я добавил repeat=always и bufferlength=0 во flashvars. Проверял в IE, Firefox, Opera с Flash-плеером 10-ой версии, вроде работало. А вообще я еще на всякий случай добавил mms поток…8)

  8. Кирилл

    Ты знаешь, удивительным образом, начал ковыряться, добавил всего лишь start=1024 (хотя это же секунды!) и все заработало и в 10-ом.
    дурь
    ладно, спасибо!

  9. Кирилл

    кстати, меня вот интересовало, что мешает разрабочикам vlc сделать нормально чтобы встроенный http не обязательно отдавал потоки на разных портах, а достаточно было бы обычной части url для обращению к разным потокам.
    не копал?

  10. Кирилл

    мы тут пост собираемся на habrahabr.ru оформить по этому делу, про тебя упомянем, если не против.

  11. Нет, если честно не копал. Но думаю, сделано это было не просто так. Насчет start=1024 — это интересно, надо попробовать…8)

  12. Да, конечно, буду благодарен, если упомянете мой пост со ссылкой.

  13. Действительно, со start>0 проблем нет…8) Обновлю статью.

  14. Андрей

    Интересно. Но есть один вопрос:
    можно как-нибудь сделать чтобы flv поток передавался не сразу клиентам, а на еще какой-нибудь сервер — а оттуда уже клиентам?

  15. Думаю, можно. Попробуйте указать в качестве параметра dst IP-адрес этого «другого» сервера. Хотя что мешает просто забирать этот поток сторонним сервером и оттуда уже «раздавать»?

  16. Vaganovski

    Полезная статья! Спасибо! А на windows это можно организовать?

  17. Я рад, что моя статья оказалась полезной. Насчет Windows, честно говоря, не могу точно сказать. Попробуйте найти и установить одну из последних сборок VLC с FFMPEG для Windows.

  18. mustang

    Спасибо! Хорошая статья.
    Но вот вопросик: видеопоток во флеш-плеер не могу подхватить.
    Система построена таким образом:
    Один комп под виндой (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’);

    Но плеер его не видет. В чем может быть проблема?

  19. А VLC на FreeBSD, который забирает поток с 192.168.0.13 ничего в отладочной информации не показывает противоестественного? Попробуйте сначала просто сделать wget 192.168.0.2:8081/stream.flv и проверить идет ли FLV-поток вообще.

  20. Vaganovski

    Та же история. Пробую делать трансляцию через 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.

  21. А почему dst=127.0.0.1:8080/stream.flv?

  22. Vaganovski

    Кстати, качество картинки, которую показывает vlc на выходе резко падает через несколько секунд после запуска трансляции.

  23. Vaganovski

    Возможно потому, что я плохо шарю. :)

  24. Vaganovski

    Я на локалхосте проверяю. Поэтому так и выставил.

  25. Качество картинки может зависеть от ffmpeg, битрейта и т.д. Если веб-страница с плеером открывается на локалхосте, где запущен VLC, то можно и так указать.

  26. Vaganovski

    Читал форум videolan. С качеством у многих проблемы. Битрейт никак не влияет. Говорят, FLV1 — плохой кодек :)

  27. Noname

    Можете немного конкретнее расписать блок с кодом для флеш-плеера? У многих проблеммы. Допустим VLC проигрывает поток через http протокол на порт 8080 по IP-адресу 67.234.90.12 Как его теперь флешом поймать?

  28. Если 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

  29. Noname

    Методом, описанным вами почему-то не получается. Пишет «this will be replaced by the SWF.» Я пробовал написать другой код.(применяется в примере самого лонгтейл плеера)

    swfobject.registerObject(«player»,»9.0.98″,»expressInstall.swf»);

    Get Flash to see this player.

    Но и так не хочет работать. Пишет, что файл XML повреждён

  30. Noname

    В прошлом коментарии все теги были сьедены=) Но думаю, что вы меня поняли

  31. Моя неточность. В коде не было написано строчки подключения javascript-библиотеки SWFObject. Проверьте, что эта библиотека подключена. И http://code.google.com/p/swfobject/wiki/documentation Вам в помощь.

  32. Artzab

    А кто может подсказать как реализовать вот такую схему, есть поток mjpeg, который я захватываю vlc и раздаю его как http, но к этому потоку нужно еще приколбасить звук, как орагнизовать это. Звук идет от микрофона.

    Короче как с миксовать два потока(звук и видео) в один и потом его раздовать?

    OS MS Windows Vista

  33. dan1005

    Привет всем!
    А железа какого будет достаточно для такого он-лайн вещания?

  34. Современного обычного компьютера, думаю, хватит…8)

  35. Северный

    Спасибо, очень познавательно. Не подскажите, какими должны быть характеристики канала, чтобы трансляцию могла смотреть, допустим, тысяча юзеров? И есть ли возможность брать звук не с камеры, а отдельно, например с пульта?

  36. Zilant

    Кто разобрался? Сколько будет стоить организация такого под ключ? Жду ваших предложений mail@telsystems.ru

  37. mustang

    Waster, сорри, долго не отвечал, на то что вы мне писали. Но мы вот с админом разобрались и вроде все настроили. ) Остался только такого рода вопросик:
    мне надо запаролить этот поток. грубо говоря открывать только залогиненным и т.п. Пробовал реализовать через промежуточный php-скрипт, указывал для плеера в качестве источника не сам поток а скрипт, который соответственно должен в случае успешной авторизации его отдать. Но вот как оперировать с потоком на php не разобрался, именно как его правильно открыть и отдать назад плееру. Может у вас есть какие-то решения?

  38. К сожалению, у меня нет таких решений. Попробуйте посмотреть нужный кусок кода для работы с flv-потоком на http://xmoov.com/xmoov-php/source или на http://www.flashcomguru.com/index.cfm/2005/11/2/Streaming-flv-video-via-PHP-take-two

  39. Сергей

    Большое спасибо за статью!) Интересный эффект — поток идет, но постоянно повторяется, причем такое впечатление как будто кэшируется и время повторяемого фрагмента с каждым разом становится больше. Подскажите в чем может быть проблема? HTML-rод полностью повторяет Ваш.

  40. Попробуйте просмотреть поток не flash-плеером, а, например, vlc или mplayer и поиграйтесь с параметрами start и bufferlength. Может быть причина еще и в нехватке канала?

  41. Сергей

    На vlc идет но со звуком проблема (то появляется то пропадает), заметил разницу с частотой кадров — флеш на страничке играет похоже 25, а исходный поток у меня 1 кадр/с. Причем в vlc нормальный 1 кадр/с в transcode параметр fps=1 я добавил

  42. mixey

    Получается ужасная картинка: 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}

  43. Попробуйте другой кодек, например

    setup kamera output «#transcode{vcodec=DIV3,vb=1024}:std{access=mmsh,dst=:8082,mux=asfh}

    Будут ли лучше результаты? Также не могу сказать влияет ли параметр delay=1000 на скорость.

  44. mixey

    Пробую. Кодек такой есть, запустилось, камера вещает. А как поймать это вещание клиентом? Как я понимаю, это Microsoft ASF? То есть будет http://192.168.2.4:8082/? Что-то не работает =(

  45. Вещание можно поймать, например, тот же VLC, указав URL потока как mms://192.168.2.4:8082/.

    Код для вставки в HTML можно легко найти в сети. Если возникнут сложности, добавлю в статью примечание насчет ASF.

  46. Владимир

    Выяснился еще такой момент: если согласно указанных выше настроек запускать vlc под виндой он отдает http-поток в виде http://IP:port/ независимо от наличия в задающей строке имени файла в потоке. А под линуксом получается http://IP:port/file.flv

  47. mixey

    Пробую под виндой и ничего не работает вообще. VLС просто ничего не делает и никаких ошибок не выдает. Никто не знает, нужны ли какие-то библиотеки? FFMPEG, например, как внедрять в винду?

  48. Насколько мне известно, VLC под Windows уже имеет все необходимое с собой.

  49. Ivan

    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

    Как вы могли с такими ключами собрать?

  50. В опциях конфигурирования в начале должны стоять два дефиса. Просто движок сайта заменяет их на длинное тире. Постараюсь исправить эту проблему.