![image](https://habrastorage.org/getpro/habr/post_images/e7b/b94/dc8/e7bb94dc8762e0a0a5c0e6d8b6695b00.png)
Доброго времени суток.
Многим web-программистам рано или поздно нужно работать с видео. Такая задача возникла и у меня.
В Интернете есть много статей на форумах и блогах, как на русскоязычных, так и на зарубежных сайтах. Но, проделавши, так же как и предлагалось в инструкциях — результата ожидаемого не дало. Что и послужило поводом для этой статьи. Думаю, она поможет
Приступим
Все производилось под рутом на машине с Ubuntu 11.04 (Natty Narwhal).
root@r2d2:~# uname -a
Linux r2d2 2.6.35-30-generic #57-Ubuntu SMP Tue Aug 9 18:00:33 UTC 2011 i686 GNU/Linux
Сначала удалим старое установленное, если оно присутствует
root@r2d2:~# apt-get remove ffmpeg x264 libx264-dev
Обновляем список пакетов
root@r2d2:~# apt-get update && apt-get upgrade
Устанавливаем нужное
root@r2d2:~# apt-get install build-essential checkinstall git git-core libfaac-dev libfaad-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libva-dev libvdpau-dev libvorbis-dev libx11-dev libxfixes-dev libxvidcore-dev subversion texi2html yasm zlib1g-dev libavcodec52 mencoder
Устанавливаем библиотеку для кодирования видеопотоков H.264
Почитать подробнее можно тут и тут.root@r2d2:~# git clone git://git.videolan.org/x264.git
root@r2d2:~# cd x264
root@r2d2:~/x264# ./configure --enable-shared
Тут нужно сделать отступление. При конфигурировании x264 БЕЗ параметра
--enable-shared
библиотека будет инсталлироваться в каталог по умолчанию (у меня это /usr/local/bin) и при запуске ffmpeg будет выдавать ошибку о неизвестном местоположении библиотеки libx264:ERROR: libx264 not found
С параметром
--enable-shared
результат после команды checkinstall будет следующим:install -d /usr/local/bin
install x264 /usr/local/bin
install -d /usr/local/include
install -d /usr/local/lib
install -d /usr/local/lib/pkgconfig
install -m 644 x264.h /usr/local/include
install -m 644 x264_config.h /usr/local/include
install -m 644 x264.pc /usr/local/lib/pkgconfig
ln -f -s libx264.so.116 /usr/local/lib/libx264.so
install -m 755 libx264.so.116 /usr/local/lib
При установке на Debian также были проблемы с библиотекой libx264.
Помог параметр
--prefix=/shared
при конфигурировании x264.root@r2d2:~/x264# make
root@r2d2:~/x264# checkinstall -fstrans=no -install=yes -pkgname=x264 -pkgversion «1:0.svn`date +%Y%m%d`« -default
Установка ffmpeg
Почитать подробнее можно тут и тут.root@r2d2:~# svn checkout svn://svn.ffmpeg.org/ffmpeg/trunk ffmpeg
root@r2d2:~# cd ffmpeg
root@r2d2:~# ./configure --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-x11grab
root@r2d2:~# make
root@r2d2:~# checkinstall -fstrans=no -install=yes -pkgname=ffmpeg -pkgversion «4:0.5+svn`date +%Y%m%d`« -default
В результате имеем:
root@r2d2:~# x264 --version
x264 0.116.2074 2641b9e
built on Sep 6 2011, gcc: 4.4.5
configuration: --bit-depth=8
x264 license: GPL version 2 or later
root@r2d2:~# ffmpeg -version
FFmpeg version SVN-r26402, Copyright (c) 2000-2011 the FFmpeg developers
built on Sep 6 2011 09:26:49 with gcc 4.4.5
configuration: --enable-gpl --enable-version3 --enable-nonfree --enable-postproc --enable-libfaac --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libtheora --enable-libvorbis --enable-libx264 --enable-libxvid --enable-x11grab
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 1 / 0.16. 1
libavcodec 52.108. 0 / 52.108. 0
libavformat 52.93. 0 / 52.93. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.74. 0 / 1.74. 0
libswscale 0.12. 0 / 0.12. 0
libpostproc 51. 2. 0 / 51. 2. 0
FFmpeg SVN-r26402
libavutil 50.36. 0 / 50.36. 0
libavcore 0.16. 1 / 0.16. 1
libavcodec 52.108. 0 / 52.108. 0
libavformat 52.93. 0 / 52.93. 0
libavdevice 52. 2. 3 / 52. 2. 3
libavfilter 1.74. 0 / 1.74. 0
libswscale 0.12. 0 / 0.12. 0
libpostproc 51. 2. 0 / 51. 2. 0
Теперь, если набрать в консоли
ffmpeg -threads 4 -y -i "video.avi" -vcodec libx264 -vpre "hq" -b 2000k -acodec libfaac -ar 44100 -ab 128k -ac 2 "video.flv"
на выходе получаем сконвертированый файл, который можно использовать в своих целях.Немного о параметрах конвертации
-i — имя исходного файла;-ar — частота дискретизации звука (должна быть кратна 11кГц);
-ab — аудио битрейт;
-ac — количество каналов звука (1 — моно, 2 — стерео);
-f — формат исходящего видео-файла;
-b — битрейт видео (30k, 200k, 512k, 1024k);
-maxrate — максимальный битрейт кодирования видеопотока (9000k);
-r — кадров в сек (FPS);
-s — размер видео в пикселях;
-fs — установить максимальный размер выходного файла;
-vpre — файл с предустановленными параметрами конвертирования (preset);
-ss 00:02:00 — смещение по времени от начала файла (position). Здесь: пропустить первые 2 мин (сдвиг в сек.). Задается в сек. или временем в формате: hh:mm:ss[.xxx];
-vframes — ограничение на количество кадров видео;
-y — перезаписать файл, если он уже существует;
-aspect — соотношение сторон(4:3, 16:9, 1.3333);
-acodec — аудио-кодек (libfaac, aac, libmp3lame);
-vcodec — видео-кодек (libx264);
-threads 0 — количество ядер в компьютере. Значения: 0 — 4. 0 — автоматически определить количество ядер процессора и использовать их в процессе работы.
ffmpeg имеет файлы с предустановленными настройками для кодирования. Они находятся в папке ffmpeg/ffpresets
root@r2d2:~/ffmpeg/ffpresets# ls -al
libx264-baseline.ffpreset
libx264-faster.ffpreset
libx264-faster_firstpass.ffpreset
libx264-fast.ffpreset
libx264-fast_firstpass.ffpreset
libx264-ipod320.ffpreset
libx264-ipod640.ffpreset
libx264-lossless_fast.ffpreset
libx264-lossless_max.ffpreset
libx264-lossless_medium.ffpreset
libx264-lossless_slower.ffpreset
libx264-lossless_slow.ffpreset
libx264-lossless_ultrafast.ffpreset
libx264-main.ffpreset
libx264-medium.ffpreset
libx264-medium_firstpass.ffpreset
libx264-placebo.ffpreset
libx264-placebo_firstpass.ffpreset
libx264-slower.ffpreset
libx264-slower_firstpass.ffpreset
libx264-slow.ffpreset
libx264-slow_firstpass.ffpreset
libx264-superfast.ffpreset
libx264-superfast_firstpass.ffpreset
libx264-ultrafast.ffpreset
libx264-ultrafast_firstpass.ffpreset
libx264-veryfast.ffpreset
libx264-veryfast_firstpass.ffpreset
libx264-veryslow.ffpreset
libx264-veryslow_firstpass.ffpreset
И после установки должны находиться в /usr/local/share/ffmpeg/. По названию файла можно догадаться, за что отвечает определенный файл. Подробнее об этих файлах можно почитать по вышеуказанным ссылкам
Файл с настройками, который используется в примерах
root@r2d2:/usr/share/ffmpeg# cat libx264-hq.ffpreset
coder=1
flags=+loop
cmp=+chroma
partitions=+parti8x8+parti4x4+partp8x8+partb8x8
me_method=umh
subq=8
me_range=16
g=250
keyint_min=25
sc_threshold=40
i_qfactor=0.71
b_strategy=2
qcomp=0.6
qmin=10
qmax=51
qdiff=4
bf=3
refs=4
directpred=3
trellis=1
flags2=+wpred+mixed_refs+dct8x8+fastpskip
Откат от всего установленного
root@r2d2:~# apt-get remove build-essential checkinstall git git-core libfaac-dev libfaad-dev libjack-jackd2-dev libmp3lame-dev libopencore-amrnb-dev libopencore-amrwb-dev libsdl1.2-dev libtheora-dev libva-dev libvdpau-dev libvorbis-dev libx11-dev libxfixes-dev libxvidcore-dev subversion texi2html yasm zlib1g-dev libavcodec52 mencoder x264 ffmpeg
Получении информации о видео с помощью PHP
Для получения информации о видео я использую немного переделаную функцию, которую нашел в этом посте.function get_video_size($videofile) {
define('MAX_VIDEO_WIDTH', 200);
$vwidth = 0;
$vheight = 0;
$owidth = 0;
$oheight = 0;
$duration = array();
$bitrate = 0;
$audio_bitrate = 0;
$sfrequency = 0;
ob_start();
passthru('ffmpeg -i "' . $videofile . '" 2>&1 | egrep -e "(Duration|Stream)"');
$ffmpeg_output = ob_get_contents();
ob_end_clean();
if (sizeof($ffmpeg_output) == 0) {
return null;
}
foreach (explode("\n", $ffmpeg_output) as $line) {
$ma = array();
// get duration and video bitrate
if (strpos($line, 'Duration:') !== false) {
preg_match('/(?<hours>\d+):(?<minutes>\d+):(?<seconds>\d+)\.(?<fractions>\d+)/', $line, $ma);
$duration = array(
'raw' => $ma['hours'] . ':' . $ma['minutes'] . ':' . $ma['seconds'],
'hours' => intval($ma['hours']),
'minutes' => intval($ma['minutes']),
'seconds' => intval($ma['seconds']),
'fractions' => intval($ma['fractions']),
'rawSeconds' => intval($ma['hours']) * 60 * 60 + intval($ma['minutes']) * 60 + intval($ma['seconds']) + (intval($ma['fractions']) != 0 ? 1 : 0)
);
preg_match('/bitrate:\s(?<bitrate>\d+)\skb\/s/', $line, $ma);
$bitrate = $ma['bitrate'];
}
// get video info
if (strpos($line, 'Video:') !== false) {
preg_match('/Stream #(?:[0-9\.]+)(?:.*)\: Video: (?P<videocodec>.*) (?P<width>[0-9]*)x(?P<height>[0-9]*)/', $line, $ma);
$vheight = $oheight = $ma['width'];
$vwidth = $owidth = $ma['height'];
}
// get audio info
if (strpos($line, 'Audio:') !== false) {
preg_match('/,\s(?<sfrequency>\d+)\sHz,/', $line, $ma);
$sfrequency = $ma['sfrequency'];
preg_match('/,\s(?<bitrate>\d+)\skb\/s/', $line, $ma);
$audio_bitrate = $ma['bitrate'];
}
}
// calculate new size of the video
if ($vwidth > MAX_VIDEO_WIDTH) {
$coef = $vheight / $vwidth;
$vwidth = MAX_VIDEO_WIDTH;
$vheight = round($vwidth * $coef);
}
// frame size must be a multiple of 2
$vwidth = $vwidth % 2 != 0 ? $vwidth - 1 : $vwidth;
$vheight = $vheight % 2 != 0 ? $vheight - 1 : $vheight;
return array(
'width' => $vwidth,
'height' => $vheight,
'srcWidth' => $owidth,
'srcHeight' => $oheight,
'duration' => $duration,
'bitrate' => $bitrate,
'audioBitrate' => $audio_bitrate,
'audioSampleFrequency' => $sfrequency
);
}
В итоге имеем готовый пример
$ffmpeg_path = 'ffmpeg'; // Путь к ffmpeg
$in = 'ATB - Let You Go.avi'; // Входящий файл
$out = 'ATB - Let You Go.flv'; // Исходящий файл
$video = get_video_size($in);
$hq = 'hq'; // Подключаем файл с предустановленными настройками
$command = $ffmpeg_path . ' -threads 0 -y -i "' . $in . '" -vcodec libx264 -vpre "' . $hq . '" -b ' . $video['bitrate'] . 'k -s ' . $video['width'] . 'x' . $video['height'] . ' -acodec libfaac -ar ' . $video['audioSampleFrequency'] . ' -ab ' . $video['audioBitrate'] . 'k -ac 2 "' . $out . '"';
$conv = exec($command);