magnify
Home arrow Posts tagged "flash video"
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 606 | 99 комментариев  comments 
formats

Потоковое Flash-Video + ClipShare

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

Один из моих недавних проектов был посвящен проблеме передачи потокового flash-видео.На сайте был установлен ClipShare (кто не знает — это клон популярного видеосервиса YouTube). Необходимо было исправить проблему загрузки файлов и настроить потоковую раздачу через HTTP загруженных видеороликов.

Объясню вкратце, что такое такое «потоковая» раздача flash-видео (HTTP flv streaming). Вообще говоря, передача видеороликов возможна несколькими способами:

  • Как обычный flv-файл, через flash-плеер браузера. При такой передаче файл кэшируется.
  • Как вложение в swf-файле. В этом случае, файл должен быть полностью загружен до начала проигрывания.
  • Прогрессивная загрузка по HTTP (Progressive download via HTTP). К преимуществам этого метода можно отнести буферизацию, использование обычных веб-серверов, возможность использовать один SWF-плеер для проигрывания различных роликов.Передача потока flash-video возможно только при наличии специальных метаданных в файле, описывающих стартовые позиции каждого ключевого кадра видео. Благодаря этому, Flash-плеер может запрашивать и получать любую часть видео до того как буферизация закончится. Другими словами, «перемотка» видеролика возможна без томительного ожидания закачки файла, что согласитесь, очень удобно. Вы наверняка замечали это при просмотре роликов на YouTube.
  • Поток RMTP. Реальная потоковая раздача, используя специализированные серверы, например Flash Media Server, Red5.

Так вот задача была как раз была реализовать 3-ий способ.

К тому же, непонятно почему файлы не загружались на сервер.

Проблема загрузки фалов решилась следующим способом:

Запустив ‘/usr/bin/php /path/to/public_html/convert.php test.mpeg test /path/to/public_html/video/test.mpeg‘, я обнаружил, что mencoder, как раз использующийся для конвертации видеофайла не знает ничего про параметр -lavfopts i_certify_that_my_video_stream_does_not_use_b_frames, что и указало на причину проблемы. Новые версии mencoder больше не поддерживают эту опцию. После того, как я убрал всякие вхождения этого параметра в php-файлах ClipShare (convert.php и upload.php) и заменил еще одну опцию -vop на -vf (чтобы сильно не ругался), аплоад заработал на ура.

Теперь про псевдо-потоковую раздачу видео. На стороне сервера, самым простым способом, является установка веб-сервера lighttpd. Все что нужно, это наличие такого куска в конфигурационном файле lighttpd:

server.modules = ( 
  ...,
  "mod_secdownload", ## optional
  "mod_flv_streaming",
  ...
)
flv-streaming.extensions = ( ".flv" )

К сожалению, в случае ClipShare,модуль загрузки файлов (Uber-Uploader, кстати) вместо отображения текущего процесса загрузки выплевывает ‘Failed To Find Flength File, но файл все-таки загружает. Поэтому я пошел другим путем и решил поставить модуль раздачи flash-видео mod_flvx. Для установки необходимо скачать сам модуль, запустить ‘apxs -i -a -c mod_flvx.c‘ и добавить директиву ‘AddHandler flv-stream .flv‘ в конфиг апача.

Принцип работы этих модулей довольно прост. Они лишь добавляют необходимый заголовок Content-Type и парсят запрос GET а наличие праметра start.Если этот параметр задан, то модуль сначала выдает FLV-заголовок, а затем начинает передавать файл с нужной позиции, заданной этим параметром.

Я уже отметил, что для использования возможности «перемотки» без полной буферизации необходимо наличие определенных метаданных в видеофайле. Для этого используется небольшая, но очень полезная утилитка flvtool2. Для обновления файла необходимо лишь запустить ‘flvtool2 -UP <файл>.flv‘ и после этого файл готов к HTTP-раздаче. В ClipShare при загрузке видеоролика эта утилита запускается, поэтому дополнительных телодвижений производить не надо.

Проделав необходимые манипуляции, и запустив Apachе, я столкнулся с еще одной неприятной проблемой, а именно «корявостью» интегрированного в ClipShare flash-плеера Agriya. «Перемотка» отказывалась работать.

Пришлось интегрировать другой плеер — JW FLV Media Player. Для ClipShare это было сделано следующим образом:

В файле templates/view_video.tpl заменить (не забыв, конечно скачать сам плеер)

<script type="text/javascript">
   var so1 = new SWFObject("/FLVplayer/flvplayer.swf", "flvplayer", "559", "444", "7",  null, true);
   so1.addParam("allowFullScreen", "true");
   so1.addParam("wmode", "transparent");
   so1.addParam("allowSciptAccess", "always");
   so1.addVariable("themes", "/FLVplayer/themes.xml");
   so1.addVariable("config", "/FLVplayer/playerXml.php?flv={$vinfo[0].flvdoname}");
   so1.write("playerDiv");
</script>

на

<script type="text/javascript">
   var so1 = new SWFObject("/FLVplayer/mediaplayer.swf", "flvplayer", "559", "444", "7",  null, true);
   so1.addParam("allowFullScreen", "true");
   so1.addParam("wmode", "transparent");
   so1.addParam("allowSciptAccess", "always");
   so1.addVariable('autostart','true');
   so1.addVariable('file','/flvideo/{$vinfo[0].flvdoname}');
   so1.addVariable('streamscript','lighttpd');
   so1.write("playerDiv");
</script>

Можно, и даже, наверное, нужно генерировать плейлист на лету через PHP, но я с этим играться не стал, поскольку надо было получить просто работающий вариант.

После этого потоковая раздача+»перемотка» заработали на ура.

Ссылки:

  1. http://en.wikipedia.org/wiki/Flash_Video
  2. http://blog.lighttpd.net/articles/2006/03/09/flv-streaming-with-lighttpd
  3. http://inlet-media.de/flvtool2
  4. http://www.jeroenwijering.com/?item=JW_FLV_Player
  5. http://journal.paul.querna.org/articles/2006/07/11/mod_flvx/
  6. http://apachedev.ru/2006/07/13/mod_flvx-peredacha-potokovogo-flash-video/
 
Просмотров: 8 123 | 6 комментариев  comments