Главная
Блог разработчиков phpBB
 
+ 17 предустановленных модов
+ SEO-оптимизация форума
+ авторизация через соц. сети
+ защита от спама

Создание полновесного видеохостинга своими руками (nginx php5-fpm ffmpeg cumulusclips)

Anna | 31.05.2014 | нет комментариев

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

Задача была дальнейшая:
Сделать видеоресурс, способный проводить многопоточные односторонние трансляции с web камеры, а так же из всякого файла (это скажем для охраны от прямого скачивания), видеошару с вероятностью просмотреть видео в различных форматах и битрейтах.

В основу лег освободившийся сервер! Не дюже сильный, но достаточно таки подходящий.

Intel® Xeon® CPU L5520 @ 2.27GHz
число ядер 16
оперативной памяти 16372 Мб

Немножко забегу вперед, при декодировании видео процессорная нагрузка достигает 500% (приблизительно 6 ядер);

Начнем с самого начала, из ОС я предпочел Ubuntu Server 13.04 x64 ввиду того, что огромнее времени провожу с ней и собственно разбираюсь я в ней отменнее чем в других семействах Linux.

В качестве WEB сервера я предпочел связку nginx php5-fpm, потому что nginx достаточно удачно справляется с нагрузками, а так же отдачей видео.

nginx по умолчанию ставится без потокового модуля, следственно ставим из сорцов

Нужные зависимости для сборки пакетов:

apt-get install build-essential checkinstall subversion unzip yamdi imagemagick php5-curl libssl-dev zlib1g-dev libpcre3-dev rpl php5-fpm git

Скачиваем исходники:

cd /tmp
wget http://nginx.org/download/nginx-1.5.2.zip
unzip nginx-1.5.2.zip -d nginx/
rm -f nginx-1.5.2.zip
cd nginx

Скачиваем нужные модули для стриминга:

mkdir modules
git clone https://github.com/masterzen/nginx-upload-progress-module.git modules/nginx-upload-progress-module
wget http://www.kernel-video-sharing.com/files/nginx_mod_h264_streaming-2.3.2.zip
unzip nginx_mod_h264_streaming-2.3.2.zip -d modules/
rm -f nginx_mod_h264_streaming-2.3.2.zip
git clone https://github.com/arut/nginx-rtmp-module.git modules/nginx-rtmp-module

Для комфорта создаем установочный скрипт:

touch nginx.sh
nano nginx.sh

с содержимым

./configure 
--conf-path=/etc/nginx/nginx.conf 
--error-log-path=/var/log/nginx/error.log 
--pid-path=/var/run/nginx.pid 
--lock-path=/var/lock/nginx.lock 
--http-log-path=/var/log/nginx/access.log 
--http-client-body-temp-path=/var/lib/nginx/body 
--http-proxy-temp-path=/var/lib/nginx/proxy 
--http-fastcgi-temp-path=/var/lib/nginx/fastcgi 
--with-debug 
--with-http_stub_status_module 
--with-http_secure_link_module 
--with-http_gzip_static_module 
--with-http_realip_module 
--with-http_mp4_module 
--with-http_flv_module 
--with-http_ssl_module 
--with-http_dav_module 
--with-md5=/usr/lib 
--add-module=modules/nginx-upload-progress-module 
--add-module=modules/nginx-rtmp-module 
--add-module=modules/nginx_mod_h264_streaming-2.3.2  

make -j16 (16 - число ядер. ускоряет сборку пакета. Дозволено узнать командой "grep -c processor /proc/cpuinfo")

checkinstall

Допустимо в процессе компиляции могут появиться ошибки. Следственно делаем так:

В файле auto/cc/gcc комментируем строчку:

#CFLAGS="$CFLAGS -Werror"

Запускаем:

sh nginx.sh

Позже установки создаем нужные симлинки и директории (если не создались):

ln -s /usr/local/nginx/sbin/nginx /usr/sbin/nginx
mkdir -p /var/lib/nginx/body
mkdir /var/lib/nginx/proxy
mkdir /var/lib/nginx/fastcgi
chown -R root /var/lib/nginx/
wget http://nginx-init-ubuntu.googlecode.com/files/nginx-init-ubuntu_v2.0.0-RC2.tar.bz2
tar -jxvf nginx-init-ubuntu_v2.0.0-RC2.tar.bz2 -C /etc/init.d/
chmod 715 /etc/init.d/nginx
/usr/sbin/update-rc.d -f nginx defaults
rm -f nginx-init-ubuntu_v2.0.0-RC2.tar.bz2
rpl 'DAEMON=/usr/local/sbin/nginx' 'DAEMON=/usr/local/nginx/sbin/nginx' /etc/init.d/nginx
rpl 'NGINX_CONF_FILE="/usr/local/nginx/conf/nginx.conf"' 'NGINX_CONF_FILE="/etc/nginx/nginx.conf"' /etc/init.d/nginx

На этом установка nginx и php5-fpm закончена.
К настройке возвратимся позднее.

Дальнейшим на очереди стоит ffmpeg. Установка apt-get не желанна, план теснее депрекейтет и многое отказывается трудиться. В поисках адекватной и больше свежей инструкции я провел примерно 2 ночи. Не спрячу, обнаружил доповольно таки отличный пак для установки.

Как ни необычно план именуется www.ffmpeginstaller.com и даже при наличии всех инсталяторов в открытом доступе предлагает свои службы за 50 долларов.

А делается все достаточно легко.
Скачиваем пакет:

cd  /tmp
wget http://mirror.ffmpeginstaller.com/old/scripts/ffmpeg7/ffmpeginstaller.7.4.tar.gz
tar -xzf ffmpeginstaller.7.4.tar.gz ffmpeg
cd ffmpeg

Позже первой установки я понял… не хватает кодека. Отмотаем <<< Ставим кодек до установки:

apt-get install libvpx

Открываем ffmpeg.sh и добавляем кодек в установку:

nano ffmpeg.sh
./configure --prefix=$INSTALL_DDIR --enable-shared --enable-nonfree 
                --enable-gpl --enable-pthreads  --enable-libopencore-amrnb  --enable-decoder=liba52 
                --enable-libopencore-amrwb  --enable-libfaac  --enable-libmp3lame 
                --enable-libtheora --enable-libvorbis  --enable-libx264  --enable-libxvid <b>--enable-libvpx</b> 
                --extra-cflags=-I/usr/local/cpffmpeg/include/ --extra-ldflags=-L/usr/local/cpffmpeg/lib 
                --enable-version3 --extra-version=syslint

На этом подготовка закончена. Дозволено устанавливать: sh install.sh

Установка займет минут 15-20 в зависимостти от вероятностей железа. Дозволено пойти попить чаю (либо кофе).

Позже установки исполняем:

hash x264 ffmpeg ffplay

Все. Поздравляю, мы это сделали!

Сейчас нам необходима CMS для управления этими инструментами

Вариантов было немножко, а вернее каждого 2 (а под мои нужды подходила только одна — cumulusclips).
Код исходников внятен, без лишней нервотрепки разобрался с составляющей. Вот только пришлось план переписывать с mysql на mysqli. Каждый код CMS структурирован и темлпейты лежат отдельно и эластично настраиваются. За основу предпочел образец псевдо Ютуба.

Пришлось всецело перекрутить проигрыватель, т.к. jwplayer был неспособен переключать видеопотоки. Немножко полазив по github обнаружил бесхитростный плеер под простым наименованием jQplayer.
Данный плеер горазд легко переключать потоки. Правда есть один минус. Проигрывание файла начинается с начала. И это не оказалось задачей — видеофайлы легко режутся nginx из коробки.

Сейчас нам необходимо настроить web хостинг для нашего плана.
Прилагаю маленький скрипт для автоматизации данного процесса. В комплекте с CMS лежал .htaccess — а nginx его понимать отказывается, следственно я его переписал под нужды данного web сервера.

#!/bin/bash
echo -n "Введите имя создаваемого хоста: " 
read host 
echo -n "Введите имя пользователя nginx: " 
read users 
sap=/etc/nginx/sites-available/$host.conf 
mkdir -p /var/hosting/
touch $sap 
chmod 777 $sap 
directives="upstream backend-${host} {server unix:/var/run/php5-${host}.sock;} 
server {
    listen 80;
    server_name ${host} www.${host};
    root /var/hosting/${host}/www;
    access_log /var/log/nginx/${host}-access.log;
    error_log /var/log/nginx/${host}-error.log;
    index index.php;
    rewrite_log on;
    if ($host = '${host}' ) {
        rewrite ^/(.*)$ http://www.${host}/$1 permanent;
    }    
    location /im {
        rewrite ^/im/(.*)$ /cc-core/controllers/thumbs.php?$1 last;
    }
    location /videos {
        rewrite ^/videos/([0-9] )/(.*)$ /cc-core/controllers/play.php?vid=$1 last;
        rewrite ^/videos/page/([0-9] )/$ /cc-core/controllers/videos.php?page=$1 last;
        rewrite ^/videos/(most-recent|most-viewed|most-discussed|most-rated)/$ /cc-core/controllers/videos.php?load=$1 last;
        rewrite ^/videos/(most-recent|most-viewed|most-discussed|most-rated)/page/([0-9] )/$ /cc-core/controllers/videos.php?load=$1&page=$2 last;
        rewrite ^/videos/([a-zA-Z0-9-] )/$ /cc-core/controllers/videos.php?category=$1 last;
        rewrite ^/videos/([a-zA-Z-] )/page/([0-9] )/$ /cc-core/controllers/videos.php?category=$1&page=$2 last;
        rewrite ^/videos/([0-9] )/comments/$ /cc-core/controllers/comments.php?vid=$1 last;
        rewrite ^/videos/([0-9] )/comments/page/([0-9] )/$ /cc-core/controllers/comments.php?vid=$1&page=$2 last;
        rewrite ^/videos/$ /cc-core/controllers/videos.php last;
    }    
    location /private {
        rewrite ^/private/get/$ /cc-core/controllers/play.php?get_private=true last;
        rewrite ^/private/videos/([a-zA-Z0-9] )/$ /cc-core/controllers/play.php?private=$1 last;
        rewrite ^/private/comments/([a-zA-Z0-9] )/$ /cc-core/controllers/comments.php?private=$1 last;
        rewrite ^/private/comments/([a-zA-Z0-9] )/page/([a-z0-9] )/$ /cc-core/controllers/comments.php?private=$1&page=$2 last;
    }    
    location /members {        
        rewrite ^/members/page/([0-9] )/$ /cc-core/controllers/members.php?page=$1 last;
        rewrite ^/members/([a-zA-Z0-9] )/$ /cc-core/controllers/profile.php?username=$1 last;
        rewrite ^/members/([a-zA-Z0-9] )/videos/$ /cc-core/controllers/member_videos.php?username=$1 last;
        rewrite ^/members/([a-zA-Z0-9] )/videos/page/([0-9] )/$ /cc-core/controllers/member_videos.php?username=$1&page=$2 last;
        rewrite ^/members/$ /cc-core/controllers/members.php last;
    }    
    location /search {
        rewrite ^/search(/page/([0-9] ))?/$ /cc-core/controllers/search.php?page=$2 last;
    }    
    location /login {
        rewrite ^(.*)$ /cc-core/controllers/login.php last;
    }    
    location /login/forgot {
        rewrite ^(.*)$ /cc-core/controllers/login.php?action=forgot last;
    }    
    location /logout {
        rewrite ^(.*)$ /cc-core/system/logout.php last;
    }    
    location /register {
        rewrite ^(.*)$ /cc-core/controllers/register.php last;
    }    
    location /activate {
        rewrite ^(.*)$ /cc-core/controllers/activate.php last;
    }    
    location /opt {
        rewrite ^/opt-out/$ /cc-core/controllers/opt_out.php last;
    }    
    location /contact {
        rewrite ^(.*)$ /cc-core/controllers/contact.php last;
    }    
    location /embed {
        rewrite ^/embed/([0-9] )/$ /cc-core/system/embed.php?vid=$1 last;
    }    
    location /page {
        rewrite ^(.*)$ /cc-core/system/page.php last;
    } 
    location /translation {
        rewrite ^(.*)$ /cc-core/system/translation.php last;
    }    
    location /notify {
        rewrite ^(.*)$ /cc-core/system/notify.php last;
    }    
    location /language/get {
        rewrite ^(.*)$ /cc-core/system/language.php?get last;
    }    
    location /language {
        rewrite ^/language/set/(.*)/$ /cc-core/system/language.php?set&language=$1 last;
    }    
    location /feed {
        rewrite ^/feed(/([a-zA-Z0-9] ))?/$ /cc-core/system/feed.php?username=$2 last;
    }    
    location /video {
        rewrite ^/video-sitemap(-([0-9] ))?.xml$ /cc-core/system/video_sitemap.php?page=$2 last;
    }    
    location /myaccount/upload/avatar {
        rewrite ^(.*)$ /cc-core/system/avatar.ajax.php last;
    }    
    location /myaccount/upload/validate {
        rewrite ^(.*)$ /cc-core/system/upload.ajax.php last;
    }    
    location /myaccount/grab/validate {
        rewrite ^(.*)$ /cc-core/system/grab.ajax.php last;
    }    
    location /actions/username {
        rewrite ^(.*)$ /cc-core/system/username.ajax.php last;
    }    
    location /actions/flag {
        rewrite ^(.*)$ /cc-core/system/flag.ajax.php last;
    }    
    location /actions/favorite {
        rewrite ^(.*)$ /cc-core/system/favorite.ajax.php last;
    }    
    location /actions/subscribe {
        rewrite ^(.*)$ /cc-core/system/subscribe.ajax.php last;
    }    
    location /actions/rate {
        rewrite ^(.*)$ /cc-core/system/rate.ajax.php last;
    }    
    location /actions/comment {
        rewrite ^(.*)$ /cc-core/system/comment.ajax.php last;
    }    
    location /actions/post {
        rewrite ^(.*)$ /cc-core/system/post.ajax.php last;
    } 
    location /actions/stream {
        rewrite ^(.*)$ /cc-core/system/stream.ajax.php last;
    }    
    location /actions {
        rewrite ^/actions/mobile-(videos|search)/$ /cc-core/system/mobile_$1.ajax.php?mobile last;
    }   
    location /myaccount {        
        rewrite ^/myaccount/upload/complete/$ /cc-core/controllers/myaccount/upload_complete.php last;
        rewrite ^/myaccount/upload/video/$ /cc-core/controllers/myaccount/upload_video.php last;
        rewrite ^/myaccount/upload/$ /cc-core/controllers/myaccount/upload.php last;
        rewrite ^/myaccount/myvideos(/page/([0-9] ))?/$ /cc-core/controllers/myaccount/myvideos.php?page=$2 last;
        rewrite ^/myaccount/myvideos/([0-9] )/$ /cc-core/controllers/myaccount/myvideos.php?vid=$1 last;
        rewrite ^/myaccount/editvideo/([0-9] )/$ /cc-core/controllers/myaccount/edit_video.php?vid=$1 last;
        rewrite ^/myaccount/myfavorites(/page/([0-9] ))?/$ /cc-core/controllers/myaccount/myfavorites.php?page=$2 last;
        rewrite ^/myaccount/myfavorites/([0-9] )/$ /cc-core/controllers/myaccount/myfavorites.php?vid=$1 last;
        rewrite ^/myaccount/privacy-settings/$ /cc-core/controllers/myaccount/privacy_settings.php last;
        rewrite ^/myaccount/change-password/$ /cc-core/controllers/myaccount/change_password.php last;
        rewrite ^/myaccount/subscriptions(/([0-9] ))?/$ /cc-core/controllers/myaccount/subscriptions.php?id=$2 last;
        rewrite ^/myaccount/subscriptions(/page/([0-9] ))?/$ /cc-core/controllers/myaccount/subscriptions.php?page=$2 last;
        rewrite ^/myaccount/subscribers(/page/([0-9] ))?/$ /cc-core/controllers/myaccount/subscribers.php?page=$2 last;
        rewrite ^/myaccount/message/inbox(/page/([0-9] ))?/$ /cc-core/controllers/myaccount/message_inbox.php?page=$2 last;
        rewrite ^/myaccount/message/inbox/([0-9] )/$ /cc-core/controllers/myaccount/message_inbox.php?delete=$1 last;
        rewrite ^/myaccount/message/read/([0-9] )/$ /cc-core/controllers/myaccount/message_read.php?msg=$1 last;
        rewrite ^/myaccount/message/send/([a-zA-Z0-9] )/$ /cc-core/controllers/myaccount/message_send.php?username=$1 last;
        rewrite ^/myaccount/message/reply/([0-9] )/$ /cc-core/controllers/myaccount/message_send.php?msg=$1 last;
        rewrite ^/myaccount/$ /cc-core/controllers/myaccount/myaccount.php last;
    }    
    location /myaccount/profile {
        rewrite ^(.*)$ /cc-core/controllers/myaccount/update_profile.php last;
    }    
    location /myaccount/profile/reset {
        rewrite ^(.*)$ /cc-core/controllers/myaccount/update_profile.php?action=reset last;
    }
    location /myaccount/message/send {
        rewrite ^(.*)$ /cc-core/controllers/myaccount/message_send.php last;
    }    
    location /m {
        rewrite ^/m/v/([0-9] )/$ /cc-core/controllers/mobile/play.php?mobile&vid=$1 last;
        rewrite ^/m/v/$ /cc-core/controllers/mobile/videos.php?mobile last;
        rewrite ^/m/s/$ /cc-core/controllers/mobile/search.php?mobile last;
        rewrite ^/m/$ /cc-core/controllers/mobile/index.php?mobile last;
    }    
    location /system {
        rewrite ^/system-error/$ /cc-core/controllers/system_error.php last;
    }
    location /t {
        rewrite ^/t/(.*)$ /cc-core/system/translation.php last;
    }
    location / {
        if (!-e $request_filename){
            #rewrite ^/(.*)$ /$request_uri/ permanent;            
            rewrite ^/(.*)$ /cc-core/system/page.php last;
        }
    }
    location ~ .php$ {
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        fastcgi_pass backend-${host};
    }
    location ~* ^. .(jpg|jpeg|gif|css|png|js|ico|bmp)$ {
        access_log off;
        expires 10d;
        break;
    }
    location ~ .(flv|mp4|webm|ogg|ogv|mp3)$ {
        mp4;
        mp4_buffer_size     1m;
        mp4_max_buffer_size 5m;        
    }
    location ~ /. {
        deny all;
    }
}
" 
echo "$directives">$sap 
sap_poll=/etc/php5/fpm/pool.d/$host.conf 
touch $sap_poll 
chmod 777 $sap_poll 
directives_poll="[${host}]
	listen = /var/run/php5-${host}.sock
	listen.mode = 0666
	user = ${users}
	group = ${users}
	chdir = /var/hosting/${host}
	php_admin_value[upload_tmp_dir] = /var/hosting/${host}/tmp
	php_admin_value[soap.wsdl_cache_dir] = /var/hosting/${host}/tmp
	php_admin_value[date.timezone] = Asia/Yekaterinburg
	pm                                  = dynamic
    pm.min_spare_servers                = 10
    pm.max_spare_servers                = 20
    pm.start_servers                    = 10
    pm.max_children                     = 40" 
echo "$directives_poll">$sap_poll 
ln -s /etc/nginx/sites-available/$host.conf /etc/nginx/sites-enabled/$host.conf 
mkdir -p /var/hosting/$host/www/ 
mkdir -p /var/hosting/$host/tmp/ 
dir=/var/hosting/$host/www 
chown -R $users:$users "$dir"; 
find "$dir" -type d -exec chmod 0755 '{}' ; 
find "$dir" -type f -exec chmod 0644 '{}' ; 
/etc/init.d/nginx restart
/etc/init.d/php5-fpm restart

На этом все. Данная конфигурация способна кодировать видео в различные форматы, а так же стримить поток. Если данная статья заинтересует кого либо, я с удовольствием приведу живые примеры стриминга.

К сожалению полной начинки показать не могу, но вот что получилось у меня stream.etagi.com

Спасибо за внимание. Верю обилие кода не помешает выдаче инвайта.

Источник: programmingmaster.ru

Оставить комментарий
Форум phpBB, русская поддержка форума phpBB
Рейтинг@Mail.ru 2008 - 2017 © BB3x.ru - русская поддержка форума phpBB