diff --git a/docs/source/Recipes.rst b/docs/source/Recipes.rst index 375bf70..53d1a86 100644 --- a/docs/source/Recipes.rst +++ b/docs/source/Recipes.rst @@ -8,8 +8,8 @@ In the following examples, we assume we work in an environnment where FFMpeg has been initialized to ``$ffmpeg``; there are two ways to initialize the environment (see below). -PHP-FFMpeg supports both ``avconv`` and legacy ``ffmpeg``. If both are installed -on your system, ``avconv`` will be loaded in first priority. Please read the +PHP-FFMpeg supports both ``avconv`` and legacy ``ffmpeg``. If both are installed +on your system, ``avconv`` will be loaded in first priority. Please read the dedicated chapter below if you want to load ``FFMpeg``. Load FFMpeg automatically @@ -34,7 +34,7 @@ look in your PATH environment variable to find ffmpeg/avconv binary : $ffmpeg = FFMpeg::load($logger); .. note:: FFMpeg and FFProbe both requires a logger for giving feedback about - what's happening. By passing a NullHandler to the logger, you will disable + what's happening. By passing a NullHandler to the logger, you will disable the log system. @@ -55,7 +55,7 @@ PHP-FFMpeg provides a set of predefined audio and video formats. These formats are usefull, but you'll probably need to define your own format with their own resize rules, etc... -This section describe how to use media formats, and how to define them. +This section describe how to use media formats, and how to define them. .. note:: Defining a format is just about implementing interfaces. @@ -64,7 +64,7 @@ This section describe how to use media formats, and how to define them. Video ^^^^^ -This section describes video processing and Interfaces for building video +This section describes video processing and Interfaces for building video formats. As Video is an extension of audio, all these features can be combined with audio features (see :ref:`dedicated audio section`). @@ -73,14 +73,24 @@ Simple transcoding To transcode a video, you have to pass the target format to FFMpeg. +When you define a format which implements the +:ref:`Resizable ` interface. +You must set FFprobe (see :ref:`FF-probe`) +for probing the media and found its height and size. + The following example initialize a Ogg format and encodes a `Video.mpeg` to a target file `file.ogv` : .. code-block:: php setProber($ffprobe); + $oggFormat = new Ogg(); $ffmpeg->open('Video.mpeg') @@ -93,7 +103,7 @@ target file `file.ogv` : HTML5 +++++ -PHP-FFMpeg provides three video formats out of the box : HTML5 video formats +PHP-FFMpeg provides three video formats out of the box : HTML5 video formats - ``FFMpeg\Format\Video\WebM`` - ``FFMpeg\Format\Video\X264`` @@ -163,11 +173,11 @@ Interface. ->encode($format, 'file.mp4') ->close(); -PHP-FFmpeg brings more interfaces for your video formats : +PHP-FFmpeg brings more interfaces for your video formats : - ``FFMpeg\Format\Video\Resamplable`` - ``FFMpeg\Format\Video\Resizable`` - - ``FFMpeg\Format\Video\Transcodable`` + - ``FFMpeg\Format\Video\Transcodable`` - ``FFMpeg\Format\Video\Interactive`` .. note:: You can combine these features in one video format. @@ -175,9 +185,11 @@ PHP-FFmpeg brings more interfaces for your video formats : Advanced media type +++++++++++++++++++ -This section presents usage for the different interfaces. You can combine +This section presents usage for the different interfaces. You can combine them for your own formats. +.. _resizable-reference: + Resizable ......... @@ -207,13 +219,15 @@ The example below resizes a video by half. ->encode($format, 'file.mp4') ->close(); +.. _resamplable-reference: Resamplable ........... -This interface provides video resampling. The example below resample the video -at 15 frame per second with a I-frame every 30 image (see -`GOP on wikipedia `_). +This interface provides video resampling. The example below resample the video +at 15 frame per second with a I-frame every 30 image (see +`GOP on wikipedia `_) and supports +B-frames (see `B-frames on wikipedia `_) .. code-block:: php @@ -234,6 +248,10 @@ at 15 frame per second with a I-frame every 30 image (see return 30; } + public function supportBFrames() + { + return true; + } } $format = new MyFormat(); @@ -258,7 +276,7 @@ video supported in flash player. class MyFormat implements Interactive { - + public function getVideoCodec() { return 'libx264'; @@ -281,14 +299,14 @@ video supported in flash player. Audio ^^^^^ -This section describes audio processing and Interfaces for building video +This section describes audio processing and Interfaces for building video formats. As Video is an extension of audio, all these features can be combined with video features (see :ref:`dedicated video section`). Simple transcoding ++++++++++++++++++ -To transcode audio file or extract an audio soundtrack from a video, you have to +To transcode audio file or extract an audio soundtrack from a video, you have to pass the target format to FFMpeg. The following example initialize a Mp3 format and transcode the file `tune.wav` @@ -308,7 +326,7 @@ to `tune.mp3` : Extract soundtrack from movie +++++++++++++++++++++++++++++ -The following example initialize a Flac format and extract the audio track from +The following example initialize a Flac format and extract the audio track from `Video.mpeg` to a target file `soudtrack.flac` : .. code-block:: php @@ -360,10 +378,10 @@ This example transcodes the mp3 track to a 128kb mp3 : ->encode($format, 'song-128.mp3') ->close(); -PHP-FFmpeg brings more interfaces for your audio formats : +PHP-FFmpeg brings more interfaces for your audio formats : - ``FFMpeg\Format\Audio\Resamplable`` - - ``FFMpeg\Format\Audio\Transcodable`` + - ``FFMpeg\Format\Audio\Transcodable`` - ``FFMpeg\Format\Audio\Interactive`` .. note:: You can combine these features in one video format. @@ -371,14 +389,14 @@ PHP-FFmpeg brings more interfaces for your audio formats : Advanced media type +++++++++++++++++++ -This section presents usage for the different audio interfaces. You can combine +This section presents usage for the different audio interfaces. You can combine them for your own formats. Resamplable ........... -This interface provides video resampling. The example below resample the video -at 15 frame per second with a I-frame every 30 image (see +This interface provides video resampling. The example below resample the video +at 15 frame per second with a I-frame every 30 image (see `GOP on wikipedia `_). .. code-block:: php @@ -420,7 +438,7 @@ a portable player. class MyFormat implements Interactive { - + public function getAudioCodec() { return 'libvorbis'; @@ -436,7 +454,7 @@ a portable player. Custom commandline options ^^^^^^^^^^^^^^^^^^^^^^^^^^ -If you need to add custom FFmpeg command line option, use the +If you need to add custom FFmpeg command line option, use the ``FFMpeg\Format\Audio::getExtraParams`` method. As ``Video`` extends ``Audio``, it is also available in any format. @@ -454,7 +472,7 @@ latest AvConv / FFMPeg version, aac encoding has to be executed with extra comma class MyFormat implements Video, Transcodable { - + public function getAudioCodec() { return 'aac'; @@ -477,10 +495,12 @@ latest AvConv / FFMPeg version, aac encoding has to be executed with extra comma ->encode($format, 'output-aac.mp4') ->close(); +.. _ffprobe-reference: + FFProbe recipes --------------- -FFProbe / AvProbe is a usefull tool for probing media files. PHP-FFMpeg +FFProbe / AvProbe is a usefull tool for probing media files. PHP-FFMpeg implementation is currenly light. Load FFProbe @@ -517,7 +537,7 @@ specifying the binary you want to use Probe streams ^^^^^^^^^^^^^ -Probe streams returns the output of ``avprobe -show_streams`` as a json +Probe streams returns the output of ``avprobe -show_streams`` as a json object. .. code-block:: php @@ -525,7 +545,7 @@ object. probeStreams('Video.ogv'); -will output something like +will output something like .. code-block:: json @@ -575,7 +595,7 @@ will output something like Probe formats ^^^^^^^^^^^^^ -Probe format returns the output of ``avprobe -show_format`` as a json +Probe format returns the output of ``avprobe -show_format`` as a json object. .. code-block:: php @@ -583,7 +603,7 @@ object. probeFormat('Video.ogv'); -will output something like +will output something like .. code-block:: json diff --git a/src/FFMpeg/FFMpeg.php b/src/FFMpeg/FFMpeg.php index de4b1e3..895b687 100644 --- a/src/FFMpeg/FFMpeg.php +++ b/src/FFMpeg/FFMpeg.php @@ -117,7 +117,7 @@ class FFMpeg extends Binary try { $process->run(); } catch (\RuntimeException $e) { - + } if ( ! $process->isSuccessful()) { @@ -198,7 +198,7 @@ class FFMpeg extends Binary try { $process->run(); } catch (\RuntimeException $e) { - + } if ( ! $process->isSuccessful()) { @@ -231,7 +231,7 @@ class FFMpeg extends Binary if ($format instanceof Video\Resizable) { if ( ! $this->prober) { - throw new LogicException('You must set a valid prober if you use RESIZEMODE_INSET'); + throw new LogicException('You must set a valid prober if you use a resizable format'); } $result = json_decode($this->prober->probeStreams($this->pathfile), true); @@ -256,7 +256,7 @@ class FFMpeg extends Binary } else { $this->logger->addInfo(sprintf('Read dimension for resizin failed !')); } - + if ($originalHeight !== null && $originalWidth !== null) { $dimensions = $format->getComputedDimensions($originalWidth, $originalHeight); @@ -269,15 +269,22 @@ class FFMpeg extends Binary if ($format instanceof Video\Resamplable) { $cmd_part2 .= ' -r ' . $format->getFrameRate(); + + /** + * @see http://sites.google.com/site/linuxencoding/x264-ffmpeg-mapping + */ + if ($format->supportBFrames()) { + $cmd_part2 .= ' -b_strategy 1 -bf 3 -g ' . $format->getGOPSize(); + } } if ($format instanceof Video\Transcodable) { $cmd_part2 .= ' -vcodec ' . $format->getVideoCodec(); } - $cmd_part2 .= ' -b ' . $format->getKiloBitrate() . 'k -g 25 -bf 3' + $cmd_part2 .= ' -b ' . $format->getKiloBitrate() . 'k' . ' -threads ' . $threads - . ' -refs 6 -b_strategy 1 -coder 1 -qmin 10 -qmax 51 ' + . ' -refs 6 -coder 1 -qmin 10 -qmax 51 ' . ' -sc_threshold 40 -flags +loop -cmp +chroma' . ' -me_range 16 -subq 7 -i_qfactor 0.71 -qcomp 0.6 -qdiff 4 ' . ' -trellis 1 -qscale 1 ' diff --git a/src/FFMpeg/Format/Dimension.php b/src/FFMpeg/Format/Dimension.php index 625bee1..605d6ef 100644 --- a/src/FFMpeg/Format/Dimension.php +++ b/src/FFMpeg/Format/Dimension.php @@ -33,7 +33,7 @@ class Dimension public function __construct($width, $height) { if ($width <= 0 || $height <= 0) { - throw InvalidArgumentException('Width and height should be positive integer'); + throw new InvalidArgumentException('Width and height should be positive integer'); } $this->width = (int) $width; diff --git a/src/FFMpeg/Format/Video/DefaultVideo.php b/src/FFMpeg/Format/Video/DefaultVideo.php index fcbb26f..a6d6c5f 100644 --- a/src/FFMpeg/Format/Video/DefaultVideo.php +++ b/src/FFMpeg/Format/Video/DefaultVideo.php @@ -97,8 +97,13 @@ abstract class DefaultVideo extends DefaultAudio implements Interactive, Resampl break; case self::RESIZEMODE_FIT: default: - $width = $this->width; - $height = $this->height; + if (null !== $this->width && null !== $this->height) { + $width = $this->width; + $height = $this->height; + } else { + $width = $originalWidth; + $height = $originalHeight; + } break; } diff --git a/src/FFMpeg/Format/Video/Resamplable.php b/src/FFMpeg/Format/Video/Resamplable.php index d27ff9c..0d4e2ff 100644 --- a/src/FFMpeg/Format/Video/Resamplable.php +++ b/src/FFMpeg/Format/Video/Resamplable.php @@ -30,9 +30,20 @@ interface Resamplable extends BaseVideo */ public function getFrameRate(); + /** + * Returns true if the current format supports B-Frames + * + * @see https://wikipedia.org/wiki/Video_compression_picture_types + * + * @return Boolean + */ + public function supportBFrames(); + /** * Returns the GOP size * + * @see https://wikipedia.org/wiki/Group_of_pictures + * * @return integer */ public function getGOPSize();