Стриминг видео mp4(h264), модуль Lighttpd mod_h264_streaming
Категория: / DEV Блог
/ Сервер (FreeBSD)
Итак, имеем поддомен с выделеным под него ip адресом. Ставится сервер достаточно просто,
перейдем к его конфигурации:
Нам нужно раздавать Mp4 файлы для зарегистрированных пользователей системы.
У нас все мувики заворачиваются на файл /secure/index.php
Файл проверяет произвел ли пользователь вход в систему, если да - отдает видео.
Все отлично, за исключением того что не поддерживается навигация (seek) по mp4 файлу.
Скажите кто знает, почему? Ведь судя из описания mod_h264_steraming он должен по параметру start
отдавать ролик со смещением.
Видео конвертировалось по инструкции (http://h264.code-shop.com/trac/wiki/Encoding).
Вот снипет класса работы с видео:
UPD
В последних версиях ffmpeg'а изменились передаваемые параметы.
Прежний код перестал работать, в часности параметры -loop 1 и -me xxxx.
Рекомендуемый профиль для кодирования Ffmpeg/x264 (profile High, level 3.0) (latest versions of x264).
2-ух уровневый с переменным бит рейтом.
'qt-faststart' не обязателен к использованию, нужен для индексации файла - возможности использования модулем псевдостримминга.
перейдем к его конфигурации:
Нам нужно раздавать Mp4 файлы для зарегистрированных пользователей системы.
server.modules = (
"mod_access",
"mod_secdownload",
"mod_fastcgi",
"mod_h264_streaming",
"mod_proxy",
"mod_redirect",
"mod_rewrite",
"mod_accesslog" )
server.document-root = "/home/thumb/lexiclips.com/public_html"
server.errorlog = "/usr/local/lighttpd/logs/error.log"
index-file.names = ( "index.php", "index.html",
"index.htm", "default.htm" )
accesslog.filename = "/usr/local/lighttpd/logs/access.log"
#url.access-deny = ( "~", ".inc" )
server.port = 80
server.bind = "ip_address"
server.max-keep-alive-requests = 0
server.max-fds = 2048
server.max-write-idle = 30
server.max-worker = 16
h264-streaming.extensions = ( ".mp4" )
$HTTP["url"] !~ ".(mp4|avi|mpeg|mpg|flv|wmv|php)$" {
url.access-deny = ( "" )
}
url.rewrite-once = (
"^/videos/([^/]+)/(.*)\.mp4\??(start=.*)?" => "/secure/index.php?id=/videos/$1/$2.mp4&$3",
)
fastcgi.server = ( ".php" =>
( "localhost" =>
(
"socket" => "/tmp/php-fastcgi.socket",
"bin-path" => "/usr/local/php-cgi/bin/php-cgi",
"allow-x-send-file" => "enable"
)
)
)
server.errorlog-use-syslog = "enable"
accesslog.use-syslog = "disable"
У нас все мувики заворачиваются на файл /secure/index.php
<?php
/**
* Uploads checker
*/
require "../modules/core/loader.php";
$core = core::get_instance();
if (core::lib('auth')->get_user()->is_anonymous()) {
die('Restricted');
}
else {
// Send file
$id = functions::request_var('id', '');
$file = loader::get_root() . substr($id, 1);
if (strpos($id, '/videos') !== false
&& ($file = loader::get_root() . substr($id, 1))
&& file_exists($file) && is_readable($file)
) {
$mime_type = 'video/H264';
header('Content-disposition: attachment;filename="' . (basename($file)) . '";');
header('Content-type: ' . $mime_type /*fs::get_mime($file)*/);
header('Content-length: ' . filesize($file));
header("X-LIGHTTPD-send-file: " . $file);
die;
}
else {
header(' ', true, 403);
echo "Restticted";
}
}
Файл проверяет произвел ли пользователь вход в систему, если да - отдает видео.
Все отлично, за исключением того что не поддерживается навигация (seek) по mp4 файлу.
Скажите кто знает, почему? Ведь судя из описания mod_h264_steraming он должен по параметру start
отдавать ролик со смещением.
Видео конвертировалось по инструкции (http://h264.code-shop.com/trac/wiki/Encoding).
Вот снипет класса работы с видео:
class video_encoder {
protected $ffmpeg_exe = '/usr/bin/ffmpeg';
protected $qt_faststart_exe = '/usr/bin/qt-faststart';
protected $ffmpeg_params;
protected $source;
/**
* MP4 h264
*/
function convert_to_mp4($dst_file, $length = false, $dim = false /*array(320, 240)*/) {
$source = $this->source;
$tmp_file = loader::get_temp() . microtime(true) . '.mp4';
$options = "-vcodec libx264 -b 512k -bf 3 -subq 6 -cmp 256 -refs 5 -qmin 10 \
-qmax 51 -qdiff 4 -coder 1 -loop 1 -me hex -me_range 16 -trellis 1 \
-flags +mv4 -flags2 +bpyramid+wpred+mixed_refs+brdo+8x8dct \
-partitions parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 -g 250 \
-keyint_min 25 -sc_threshold 40 -i_qfactor 0.71";
if (!empty($dim))
$options .= " -s {$dim[0]}x{$dim[1]}";
if (!empty($length)) {
$options .= " -t {$length}";
}
$this->set_params("-y -i \"$source\" -an -pass 1 -threads 2 $options \"$tmp_file\"");
$this->run();
// libmp3lame
$acodec = "-acodec libfaac -ar 44100 -ab 96k";
$this->set_params("-y -i \"$source\" {$acodec} -pass 2 -threads 2 $options \"$tmp_file\"");
$this->run();
$this->run_qt_faststart($tmp_file, $dst_file);
@unlink($tmp_file);
return true;
}
/**
* Run
*/
protected function run() {
$cmd = $this->ffmpeg_exe . ' ' . $this->ffmpeg_params . ' 2>&1';
$this->_output = false;
if ($this->valid_encoder()) {
$this->_output = shell_exec($cmd);
}
return $this->_output;
}
/**
* qtfast
*/
protected function run_qt_faststart($in, $out) {
$cmd = $this->qt_faststart_exe . ' "' . $in . '" "' . $out . '" 2>&1';
// check exists
preg_match('#^([^\s]+)#', $this->qt_faststart_exe, $matches);
$check = $matches[1];
if (file_exists($check) && is_executable($check)) {
shell_exec($cmd);
core::dprint($cmd);
}
else {
core::dprint('[video_conv] qt_faststart failed', core::E_ERROR);
}
return true;
}
/**
* Verify all files in right place
*/
protected function valid_encoder() {
return (file_exists($this->ffmpeg_exe) && is_executable($this->ffmpeg_exe));
}
}
UPD
В последних версиях ffmpeg'а изменились передаваемые параметы.
Прежний код перестал работать, в часности параметры -loop 1 и -me xxxx.
Рекомендуемый профиль для кодирования Ffmpeg/x264 (profile High, level 3.0) (latest versions of x264).
2-ух уровневый с переменным бит рейтом.
infile ="video.avi"
tmpfile="video_tmp.mp4"
outfile="video.mp4"
options="-vcodec libx264 -b 512k -flags +loop+mv4 -cmp 256 \
-partitions +parti4x4+parti8x8+partp4x4+partp8x8+partb8x8 \
-me_method hex -subq 7 -trellis 1 -refs 5 -bf 3 \
-flags2 +bpyramid+wpred+mixed_refs+dct8x8 -coder 1 -me_range 16 \
-g 250 -keyint_min 25 -sc_threshold 40 -i_qfactor 0.71 -qmin 10\
-qmax 51 -qdiff 4"
ffmpeg -y -i "$infile" -an -pass 1 -threads 2 $options "$tmpfile"
ffmpeg -y -i "$infile" -acodec libfaac -ar 44100 -ab 96k -pass 2 -threads 2 $options "$tmpfile"
qt-faststart "$tmpfile" "$outfile"
'qt-faststart' не обязателен к использованию, нужен для индексации файла - возможности использования модулем псевдостримминга.