📜 ⬆️ ⬇️

Video coding for web projects

image
Good day.
Many web programmers need to work with video sooner or later. This problem arose in me.
There are many articles on the Internet on forums and blogs, both on Russian and foreign sites. But, having done the same as it was proposed in the instructions, the result did not give the expected result. That was the reason for this article. I think she will help the same as I do many beginners.

Let's get started


Everything was done under the root on a machine with 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 

First, remove the old one installed if it is present.

 root@r2d2:~# apt-get remove ffmpeg x264 libx264-dev 

Update the list of packages

 root@r2d2:~# apt-get update && apt-get upgrade 

Install the right

 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 

Install the library to encode H.264 video streams

You can read more here and here .
 root@r2d2:~# git clone git://git.videolan.org/x264.git root@r2d2:~# cd x264 root@r2d2:~/x264# ./configure --enable-shared 

Here you need to make a retreat. When configuring x264 WITHOUT the --enable-shared parameter, the library will be installed in the default directory (I have it / usr / local / bin) and when I run ffmpeg, it will give an error about the unknown location of the libx264 library:
ERROR: libx264 not found

With the --enable-shared parameter, the result after the checkinstall command is as follows:
 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 

When installing on Debian there were also problems with the libx264 library.
The parameter --prefix=/shared helped when configuring x264.
 root@r2d2:~/x264# make root@r2d2:~/x264# checkinstall -fstrans=no -install=yes -pkgname=x264 -pkgversion «1:0.svn`date +%Y%m%d`« -default 

Install ffmpeg

You can read more here and here .
 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 

As a result, we have:
 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 

Now if you type in console
 ffmpeg -threads 4 -y -i "video.avi" -vcodec libx264 -vpre "hq" -b 2000k -acodec libfaac -ar 44100 -ab 128k -ac 2 "video.flv" 
the output is a converted file that can be used for your own purposes.

A little bit about the conversion options

-i - the name of the source file;
-ar - audio sampling frequency (must be a multiple of 11kHz);
-ab - audio bit rate;
-ac - the number of sound channels (1 - mono, 2 - stereo);
-f - outgoing video file format;
-b - video bitrate (30k, 200k, 512k, 1024k);
-maxrate - maximum video encoding bit rate (9000k);
-r - frames per second (FPS);
-s - video size in pixels;
-fs - set the maximum size of the output file;
-vpre - file with preset conversion parameters (preset);
-ss 00:02:00 - offset from the beginning of the file (position). Here: skip the first 2 minutes (shift in seconds). Set in seconds or time in the format: hh: mm: ss [.xxx];
-vframes - limit on the number of video frames;
-y - overwrite the file if it already exists;
-aspect - aspect ratio (4: 3, 16: 9, 1.3333);
-acodec - audio codec (libfaac, aac, libmp3lame);
-vcodec - video codec (libx264);
-threads 0 is the number of cores in the computer. Values: 0 - 4. 0 - automatically determine the number of processor cores and use them in the process.
')
ffmpeg has files with predefined settings for encoding. They are in the ffmpeg / ffpresets folder
 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 

And after installation should be in / usr / local / share / ffmpeg /. By the name of the file, you can guess what the specific file is responsible for. More information about these files can be found at the above links.

The settings file that is used in the examples.
 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 

Rollback of all installed

 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 

Retrieving video information with PHP

For information about the video, I use a slightly reworked function that I found in this post.
 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 ); } 

As a result, we have a finished example.

 $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); 

Source: https://habr.com/ru/post/127910/


All Articles