Собственный видеохостинг

Статья описывает процесс построения собственного видеохостинга (как, например, YouTube) на базе lighttpd с модулем mod_flv_streaming для трансляции потокового видео в формате .flv и модулем
mod_secdownload для предотвращения хотлинкинга. В качестве проигрывателя мы возьмем FlowPlayer, который поддерживает mod_flv_streaming. Также мы опишем процесс перекодировки видео различных форматов (.mp4 .mov .mpg .3gp .mpeg .wmv .avi) в формат FLV, который будет использоваться на нашем сайте

Необходимые замечания
Перед описанием непосредственно процесса давайте определим используемые в статье некоторые параметры, которые могут отличаться от ваших (и наверняка отличаются :))
Все происходит на сервере с адресом server1.example.com и IP-адресом 192.168.0.100. Предполагается, что на сервере уже установлен lighttpd и php с поддержкой MySQL
В Лайти также включена поддержка PHP. В качестве операционной системы мы используем Debian Etch
Итак, приступим

Устанавливаем LAME
LAME - это mp3-декодер. Он необходим нам для того, чтобы в наших сконвертированных видеофайлах сохранялась аудиодорожка. В репозитриях Etch LAME отсутствует, поэтому мы будем собирать его вручную.
Установим необходимые пакеты:

apt-get install build-essential

Затем скачаем и скомпилируем LAME

cd /tmp
wget http://mesh.dl.sourceforge.net/sourceforge/lame/lame-3.97.tar.gz
tar xvfz lame-3.97.tar.gz
cd lame-3.97
./configure --enable-shared --prefix=/usr
make
make install

Устанавливаем ffmpeg
Для перекодирования видео мы будем использовать ffmpeg. Установим его и плагины к нему

apt-get install ffmpeg libavcodec0d libavformat0d libavifile-0.7c2 libpostproc0d libasound2-plugins avifile-player avifile-utils avifile-mad-plugin avifile-mjpeg-plugin avifile-vorbis-plugin

Проблема LAME в Debian заключается в том, что он не поддерживает кодирование mp3 из-за патентных ограничений, а значит наше видео превратится в “немое кино”. Чтож, немного поправим пакет

cd /usr/src/
apt-get source ffmpeg
cd ffmpeg-0.cvs20060823

Отредактируем файл debain/rules. В начале файла есть две строки confflags с опциями сборки. Добавим в одну из них --enable-mp3lame и сохраним файл

[...]
confflags += --enable-gpl --enable-pp --enable-pthreads --enable-mp3lame
confflags += --enable-vorbis --enable-libogg --enable-a52 --enable-dts --enable-libgsm
[...]

Соберем пакет

dpkg-buildpackage

dpkg-buildpackage, скорее всего, будет “ругаться” на отсутствующие пакеты, которые нужны ему для сборки ffmpeg

server1:/usr/src/ffmpeg-0.cvs20060823# dpkg-buildpackage
dpkg-buildpackage: source package is ffmpeg
dpkg-buildpackage: source version is 0.cvs20060823-8
dpkg-buildpackage: source changed by Sam Hocevar (Debian packages) 
dpkg-buildpackage: host architecture i386
dpkg-buildpackage: source version without epoch 0.cvs20060823-8
dpkg-checkbuilddeps: Unmet build dependencies: debhelper (>= 4.0) quilt libogg-dev libvorbis-dev liba52-dev libdts-dev zlib1g-dev libsdl1.2-dev libfreetype6-dev libimlib2-dev texi2html libraw1394-dev libdc1394-13-dev libtheora-dev (>> 0.0.0.alpha4) libgsm1-dev
dpkg-buildpackage: Build dependencies/conflicts unsatisfied; aborting.
dpkg-buildpackage: (Use -d flag to override.)
server1:/usr/src/ffmpeg-0.cvs20060823#

Если вы видите что-то подобное, то просто доставьте недостающие пакеты

apt-get install debhelper quilt libogg-dev libvorbis-dev liba52-dev libdts-dev zlib1g-dev libsdl1.2-dev libfreetype6-dev libimlib2-dev texi2html libraw1394-dev libdc1394-13-dev libtheora-dev libgsm1-dev

и запустите dpkg-buildpackage снова

dpkg-buildpackage

Процесс создания нового пакета займет некоторое время, а результатом его будут *.deb-файлы в директории /usr/src. Установим их командой

cd ..
dpkg -i *.deb

Устанавливаем flvtool2
При перекодировке видео неплохо было добавить некоторые метаданные в конечные файлы, например информацию о длительности, чтобы наш плеер смог корректно показывать счетчик времени. Для этого воспользуемся утилитой flvtool2. Она написана на Ruby, поэтому сначала установим его

apt-get install ruby

Затем скачаем и установим flvtool2

cd /tmp
wget http://rubyforge.org/frs/download.php/17497/flvtool2-1.0.6.tgz
tar xvfz flvtool2-1.0.6.tgz
cd flvtool2-1.0.6
ruby setup.rb config
ruby setup.rb setup
ruby setup.rb install

Подгототавливаем директории для видео
Корневой директорией для Лайти в нашем случае является /var/www (по умолчанию в Debian так и есть). Конечно же мы не хотим хранить оригинальные и сконвертированные видеофайлы в этой директории, иначе их смогут скачать все, кто захочет (зная прямую ссылку). Поэтому директорию с оригинальными видео (/var/videos/incoming) и сконвертированными (/var/videos/flv) мы расположим вне DocumentRoot

mkdir -p /var/videos/incoming
mkdir -p /var/videos/flv

Вы (или ваши пользователи) смогут загружать файлы в /var/videos/incoming через FTP или WEB-интерфейс, а вы будете их перекодировать (вручную или автоматически) в FLV-формат и хранить в /var/videos/flv

Перекодирование видео
Предположим, что у нас есть файл video.avi в директории /var/videos/incoming (или .mp4 .mov .mpg .3gp .mpeg .wmv). Мы хотим сконвертировать его в fideo.flv и сохранить в /var/videos/flv. Разрешение конечного файла должно быть 320×240, звук 44100 Hz и частота кадров 12 fps

ffmpeg -i /var/videos/incoming/video.avi -s 320×240 -ar 44100 -r 12 /var/videos/flv/video.flv

(для дополнительной информации рекомендую обратиться к man ffmpeg). Это займет некоторое время, а вывод будет похож на

server1:~# ffmpeg -i /var/videos/incoming/video.avi -s 320x240 -ar 44100 -r 12 /var/videos/flv/video.flv
FFmpeg version SVN-rUNKNOWN, Copyright (c) 2000-2004 Fabrice Bellard
  configuration:  --enable-gpl --enable-pp --enable-pthreads --enable-mp3lame --enable-vorbis --enable-libogg
 --enable-a52 --enable-dts --enable-libgsm --enable-dc1394 --disable-debug --enable-shared --prefix=/usr
  libavutil version: 0d.49.0.0
  libavcodec version: 0d.51.11.0
  libavformat version: 0d.50.5.0
  built on Aug 14 2007 15:02:25, gcc: 4.1.2 20061115 (prerelease) (Debian 4.1.1-21)
Input #0, avi, from '/var/videos/incoming/video.avi':
  Duration: 00:10:53.8, start: 0.000000, bitrate: 5455 kb/s
  Stream #0.0: Video: mpeg4, yuv420p, 1024x576, 24.00 fps(r)
  Stream #0.1: Audio: ac3, 48000 Hz, 5:1, 448 kb/s
Output #0, flv, to '/var/videos/flv/video.flv':
  Stream #0.0: Video: flv, yuv420p, 320x240, q=2-31, 200 kb/s, 12.00 fps(c)
  Stream #0.1: Audio: mp3, 44100 Hz, stereo, 64 kb/s
Stream mapping:
  Stream #0.0 -> #0.0
  Stream #0.1 -> #0.1
No accelerated IMDCT transform found
Press [q] to stop encoding
frame= 7847 q=2.0 Lsize=   21682kB time=653.8 bitrate= 271.7kbits/s
video:16061kB audio:5108kB global headers:0kB muxing overhead 2.427536%
server1:~#

Обратите особое внимание на секцию Output - там должно быть два потока: видео и аудио. Если вы видите там только видеопоток, то значит какие-то проблемы с аудиокодированием, внимательно проверьте наши инструкции по подключению LAME
После кодирования добавим метаданные

cat /var/videos/flv/video.flv | flvtool2 -U stdin /var/videos/flv/video.flv

Настройка Lighttpd
Теперь приступим к настройке Лайти. Откроем главный конфигурационный файл /etc/lighttpd/lighttpd.conf активируем в нем модули mod_secdownload и mod_flv_streaming. Обратите внимание: крайне важно, чтобы модуль mod_secdownload шел перед модулем mod_flv_streaming в секции server.modules. В обратном случае будут проблемы с отображением видео FlowPlayer’ом

[...]
server.modules              = (
            "mod_access",
            "mod_alias",
            "mod_accesslog",
            "mod_fastcgi",
#           "mod_rewrite",
#           "mod_redirect",
#           "mod_status",
#           "mod_evhost",
#           "mod_compress",
#           "mod_usertrack",
#           "mod_rrdtool",
#           "mod_webdav",
#           "mod_expire",
            "mod_secdownload",
            "mod_flv_streaming",
#           "mod_evasive"
 )
[...]

Также добавьте в конец конфига следующие строки

[...]
flv-streaming.extensions = ( ".flv" )
secdownload.secret          = "somesecret"
secdownload.document-root   = "/var/videos/flv/"
secdownload.uri-prefix      = "/dl/"
secdownload.timeout         = 120

Не забудьте заменить somesecret на реальную парольную фразу
Как работает mod_secdownload:
На web-странице расположена ссылка примерно следующего вида:
<uri-prefix>/<token>/<timestamp-in-hex>/<rel-path> (например: /dl/d8a8cb150f7e5962f6a8443b0b6c6cc2/46c1d9f6/video.flv)
Где <token> - это md5-хэш от

  • Секретной строки
  • <rel-path> (начинающегося с /)
  • <timestamp-in-hex>
  • mod_secdownload перенаправит эту ссылку на файл, расположенный в secdownload.document-root (который вне основного корня веб-сервера) и обеспечит доступ к нему в течении secdownload.timeout секунд. По истечении времени ссылка перестанет быть валидной и доступ будет закрыт.
    После установки FlowPalyer мы будем генерировать валидные сслыки для mod_secdownload при помощи PHP-скрипта. Дополнительную информацию по mod_secdownload можно получить здесь
    Не забудьте перезапустить Лайти

    /etc/init.d/lighttpd restart

    Установка FlowPlayer
    Скачайте последнюю версию плеера с http://flowplayer.org/download и приготовьте его к работе

    cd /tmp
    wget http://belnet.dl.sourceforge.net/sourceforge/flowplayer/flowplayer-1.19.zip
    unzip flowplayer-1.19.zip
    mv flowplayer /var/www/

    Настройка FlowPlayer
    Плеер установлен, теперь давайте создадим файл, с помощью которого можно будет посмотреть наше видео. В нашем примере это /var/www/flowplayertest.php, в котором расположены все параметры для запуска плеера и генерируются валидные ссылки для mod_secdownload

    <?php
    $secret = "somesecret";
    $uri_prefix = "/dl/";
    
    # filename
    $f = "/video.flv";
    
    # current timestamp
    $t = time();
    
    $t_hex = sprintf("%08x", $t);
    $m = md5($secret.$f.$t_hex);
    
    ?>
    
    <object type="application/x-shockwave-flash" data="/flowplayer/FlowPlayerThermo.swf">
        width="320" height="256" id="FlowPlayer">
    <param name="allowScriptAccess" value="sameDomain"></param>
    <param name="movie" value="/flowplayer/FlowPlayerThermo.swf"></param>
    <param name="quality" value="high"></param>
    <param name="scale" value="noScale"></param>
    <param name="allowFullScreen" value="true"></param>
    <param name="flashvars" value="config={videoFile: '<?php printf('%s%s/%s%s', $uri_prefix, $m, $t_hex, $f, $f); ?>', streamingServer: 'lighttpd', loop: 'false', useNativeFullScreen: true}"></param>
    </object>

    Не забудьте позаботиться о том, чтобы переменная $secret совпадала со значением, указанным в конфиге Лайти. Также должны совпадать $uri_prefix и secdownload.uri-prefix. Если все верно, то ссылки точно будут рабочими. В переменной $f содержится имя видеофайла, начинающееся со слеша (”/”). В нашем примере имя “жестко” зашито в код, но вы можете получать его из БД, например.
    В тэгах <object></object> содержатся конфигурационные параметры для FlowPlayer. Плеер может использовать разные скины (в нашем примере это FlowPlayerThermo), видео имеет размер 320×240 и панель управления имеет высоту 16px. Пожтому мы указали ширину равной 320px и высоту (240+16) 256px. Если вы используете другой скин, поправьте эти параметры. За документацией по FlowPlayer обращайтесь на официальный сайт
    В параметре <param name="flashvars"... содержатся настройки окружения плеера. Важным параметром является videoFile - это ссылка на файл, которую генерирует наш скрипт. Другая важная опция - это streamingServer: 'lighttpd', которая указывает, что для потоковой трансляции файла мы используем mod_flv_streaming Остальные опции (loop, useNativeFullScreen) являются необязательными. Например, если вы установите опцию useNativeFullScreen в true (это поддержка нативного полноэкранного режима для Flash Player 9), то вы должны включить в object строку <param name=”allowFullScreen” value=”true” /> и не можете использовать <param name=”wmode” value=”transparent” />
    За дополнительными настройками FlowPlayer обратитесь к документации

    Проверим?
    Зайдем браузером на http://192.168.0.100/flowplayertest.php - видео должно работать (со звуком)
    2.png
    И даже в полноэкранном режиме
    3.png
    Enjoy.

    Оригинал: http://howtoforge.org/video_streaming_lighttpd_flowplayer

Система Orphus

 


 

Comments: 10

  1. hand May 25th, 2009 at 12:41 pm

    Steps 2 and 3 can be done instead by going:

    vi /etc/apt/sources.list
    deb http://www.debian-multimedia.org stable main

    apt-get update
    apt-get install ffmpeg

    This will install ffmpeg with mp3 support

    -steve

  2. adw0rd May 25th, 2009 at 5:19 pm

    Хай, хорошая статья!
    Я сейчас пишу аналогичную статью, но только связку FreeBSD/ffmpeg/FlowPlayer/Yamdi/nginx! У меня имеется опыт создания видео-сервисов для соц. сетей :)

    А вообще, может обменяемся ссылками на блоги, у нас и посещаемость в среднем одинакова?

  3. adw0rd May 26th, 2009 at 2:42 am

    Кстати, мелькнуло в рассылке Nginx, что Сысоев собирается написать модуль для mp4. Там и размер нормальный и качество получше.

    А лайти поддерживает мп4?

  4. ash2k May 26th, 2009 at 4:09 pm

    да любопытно, спасибо за статью!

    з.ы. adw0rd hi ;)

  5. adw0rd May 26th, 2009 at 4:13 pm

    ash2k, хай! :)
    У вас там как все работает на сервере?)

  6. ash2k May 26th, 2009 at 4:36 pm

    у нас нгинкс отдает флв как статику и все) ссылки на статику получает флеш плеер

  7. boombick June 5th, 2009 at 3:42 pm

    Thank you very much, Steve =)

  8. adw0rd June 18th, 2009 at 12:26 am

    А чего мой пост удалил? Ну как хочешь, сотру на тебя линк пожалуй…

  9. mkrentovskiy August 3rd, 2009 at 9:32 pm

    Хе, Андрей, а я это делал вот так - http://relabs.ru/archives/30
    Правда, потому передумал и теперь жму в H.264-AAC в контейнере mp4, который затем отдается модулем псевдостриминга mod_h264_streaming, который есть для лайти, апача и нгинкса.

  10. andy December 2nd, 2009 at 11:53 pm

    Прикольно. Правда я когда-то так пробовал конвертировать - конечное качество слабовато при конвертации в FLV1.
    Вот тут описано как под Федору настроить конвертер в FLV4 с HD-качеством.
    http://webmax.do.am/publ/administration/hdtv_flash_video_converting/1-1-0-2
    На 100% работает.

Add a Comment