Вещание с вэб-камеры на сайте
Определённого рода задачи требуют демонстрации видео на сайте, получаемого посредством вэб-камеры. В общем случае эта задача решается дублированием кода с технической страницы камеры (мы рассматриваем случай использования Ethernet-камеры, способной самостоятельно формировать видео-поток, в случае более дешёвых решений алгоритм немного меняется) на сайт и камера напрямую отдаёт картинку посетителю. К сожалению, мощности камер и ширина каналов, которые они используют, очень часто бывают ограничены, а в случае весьма посещаемого сайта количество посетителей может быть вполне немаленьким.
В этом случае задача обычно решается путем установки потокового сервера на пути между посетителем и камерой. Принцип действия потокового сервера одинаков и в случае видео-вещания и в случае аудио-вещания: выделяются источник вещания, который является поставщиком контента (в нашем случае это камера), и приемники (подключающиеся пользователи). Сам сервер играет роль разветвителя (или ретранслятора) — принимая данные с одного канала, он раздаёт его на множество других каналов. По пути возможны различные преобразования (например, понижение скорости потока за счет снижения качества), впрочем одно то, что на источник можно подавать любой сигнал, гораздо упрощает управление — достаточно одного специализированного места оператора (пульта DJ-я в случае радио) и оставляем на потоковый сервер заботу о посетителях.
Теперь перейдём к вэб-камерам. В общем случае с любой ethernet-камеры можно снять данные двумя методами — в виде серии картинок и потоком видео. Первый случай более общий, но в этом случае видео получается весьма ступенчатым. Второй случай более приятен в созерцании, но не исключена вероятность, что воспроизводится будет лишь при помощи специализированного кодека, что неприятно. Впрочем, AXIS славится своей приверженностью к открытым системам, так что проблем быть не должно.
Другой нюанс заключается в извечном компромиссе сетевого вещания «качество — скорость». Чем выше качество картинки, тем больше требуется канал из расчёта на посетителя и тем больше вероятность, что видео будет притормаживать вследствие использования непрогнозируемых задержек передачи по сети и не рассчитанного на вещание реального времени с возможной потерей пакетов в угоду синхронизации протокола HTTP. С другой стороны, чем хуже картинка, тем меньше требуется полоса пропускания для ее доставки до потребителя, а, следовательно, больше вероятность, что пользователь увидит видео как надо, а не покадровую склейку. Именно между двух зол и придётся балансировать.
Испробованное решение базируется на пакете ffmpeg, в состав которого входит потоковый сервер ffserver. Упрежу сразу, что следует брать наиболее свежую версию ПО, поскольку в дистрибутивах зачастую попадаются не самые новые, а засим не самые стабильны сборки. Конфигурационный файл, по умолчанию располагающийся в /etc/ffserver.conf (для ручной сборки лучше переложить в /usr/local/etc/ffserver.conf) будет выглядеть примерно так:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 | Port 8090 BindAddress 0.0.0.0 MaxClients 300 MaxBandwidth 100000 CustomLog /var/log/ffservser.log <Feed feed1.ffm> File /tmp/feed1.ffm FileMaxSize 1024M ACL allow 127.0.0.1 </Feed> <Stream cam.swf> Feed feed1.ffm Format swf VideoSize cif VideoBitRate 512 VideoBufferSize 4000 VideoQMin 1 VideoQMax 5 NoAudio PreRoll 0 </Stream> <Stream cam.asf> Feed feed1.ffm Format asf VideoSize cif VideoBitRate 512 VideoQMin 1 VideoQMax 12 VideoGopSize 20 NoAudio StartSendOnKey PreRoll 0 </Stream> <Stream stat.html> Format status </Stream> <Redirect index.html> URL http://www.relabs.ru/ </Redirect> |
В данном случае мы используем один источник потока feed1.fmm, доступ к которому ограничен рамками локального хоста. В качестве выходных потоков будут применяться cam.asf для выдачи видео-потока для Windows Media Player и cam.swf для выдачи в виде swf-файла. Последний вариант более универсален, поскольку позволяет проигрывать видео в браузерах на платформах, отличных от Microsoft Windows. Параметрами можно играться для достижения оптимального результата, при этом надо отдавать отчет, что у товарища на другом конце света с хорошим каналом видео может показывать гораздо лучше, нежели у друга из соседнего дома.
Далее, организуем поставку видео-потока. Тут, как уже говорилось, два варианта:
а) с использованием mjpeg (суть — последовательного потока кадров в формате jpeg)
1 2 3 4 5 6 | #!/bin/bash while [ 1 ] do ffmpeg -v 0 -s cif -y -an -r 4 -f mjpeg -sameq -i http://АДРЕС_КАМЕРЫ/mjpg/video.mjpg http://127.0.0.1:8090/feed1.ffm sleep 15 done |
б) с использованием потока MPEG-4, транслируемого по RTSP
1 2 3 4 5 6 | #!/bin/bash while [ 1 ] do openRTSP -v -c -t rtsp://АДРЕС_КАМЕРЫ/mpeg4/media.amp | /usr/local/bin/ffmpeg -f m4v -i - -an http://127.0.0.1:8090/feed1.ffm > /dev/null sleep 15 done |
В обоих случаях для обеспечения непрерывности применяется бесконечный цикл средствами shell, а во втором еще и используется утилита для снятия RTSP-потока OpenRTSP, входящая в состав пакета live555, ориентированного на работу с этим протоколом.
Далее, запускаем один их этих вариантов и проверяем результаты (в этом очень часто хорошо помогает страница статуса сервера http://АДРЕС_СЕРВЕРА:8090/stat.html). В случае успешной настройки можем спокойно приступить к интеграции видео в код сайта.
Код варианта с WMP будет выглядеть как
1 2 3 4 5 6 7 | <object width="352" height="280" type="video/x-ms-wmv" id="IFid1" classid="CLSID:6BF52A52-394A-11D3-B153-00C04F79FAA6"> <param value="1" name="AutoStart"/> <param value="none" name="uiMode"/> <param value="0" name="Volume"/> <param value="http://АДРЕС_СЕРВЕРА:8090/cam.asf" name="URL"/> <embed width="352" height="320" autostart="1" src="http://АДРЕС_СЕРВЕРА:8090/cam.asf" videoborder3d="0" showstatusbar="1" showdisplay="0" showtracker="1" showcontrols="0" bgcolor="darkblue" autosize="1" displaysize="4" name="mediaPlayer" id="mediaPlayer" pluginspage="http://microsoft.com/windows/mediaplayer/en/download/" type="application/x-mplayer2"/> </object> |
Вариант с применением Flash будет выглядеть как
1 2 3 4 5 |
В этом случае применяется JS-библиотека SWFObject.
Если все прошло успешно — не забываем прописать запуск сервера и поставщика видео в автозапуск и хорошенько проверить систему из разных точек сети.
Источники информации:


Пароботало полчаса и выдал /usr/local/bin/ffmpeg — нет такого файла или каталога. И все(( его и правда нет
Интересно. А картинку давало?
nema
неа. Три разных плейра вставил в html на соседнем компе, везде темнота была. Но цикл с openRTSP исправно крутился, тревожных сообщений не выкидывал. И вдруг встал((
nema
параллельно работает аналог на VLC, видеопоток вижу без проблем (ну тока порты вещения, понятно другие)
nema
поработало
ошибся
У меня вопрос, а какой канал нужен чтобы допустим 100 пользователей с каналом 1мбит каждый. Могли смотреть видео
В теории 100 МБитс, на практике лучше держать запас еще 20%, т.е. итого 120 МБитс. Разумеется, это когда все сто пользователей одновременно смотрят. Если они смотрят стохастически — 20-30Мбитс должно хватить.