<?php
/** FFMPEG CLASS
*
* This code is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of the
* License, or (at your option) any later version.
*
* This code is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty
* of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this code; if not, write to the Free Software Foundation,
* Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* @package shr
* @version 0.1
* @authorxxx <xxx@xxx.net>
* @copyright 2007 xxx
* @license http://www.opensource.org/licenses/gpl-license.php GPL
*/
/** FFMpeg class */
class ap_ffmpeg {
/** Path to ffmpeg binary
* @var string */
protected $bin;
/** Path to watermark.so vhook file
* @var string */
protected $watermark_so;
/** File formats available for encoding
* @var array */
protected $encode_file_formats;
/** File formats available for decoding
* @var array */
protected $decode_file_formats;
/** Video codecs available for encoding
* @var array */
protected $encode_video_codecs;
/** Video codecs available for decoding
* @var array */
protected $decode_video_codecs;
/** Audio codecs available for encoding
* @var array */
protected $encode_audio_codecs;
/** Audio codecs available for decoding
* @var array */
protected $decode_audio_codecs;
/** Class constructor.
* @param string $bin FFMpeg binary location (e.g. /usr/bin/ffmpeg). If it's not given, the constructor will try to detect binary location automaticaly
* @param string $watermark_so Location of watermark.so file (e.g. /usr/lib/vhook/watermark.so). Skip this if you are not planinig to place watermark on the converted video
* @return ap_ffmpeg */
function __construct($bin="", $watermark_so="") {
$bin = trim($bin);
$watermark_so = trim($watermark_so);
if (!$bin) {
$bin = trim(shell_exec("which ffmpeg 2>&1"));
if (substr($bin, 0, 1) != "/")
die("Cannot find FFMpeg executible");
} else {
if (!preg_match('/\/ffmpeg$/', $bin)) {
if (substr($bin, -1) != "/")
$bin .= "/";
$bin .= "ffmpeg";
}
// if (!file_exists($bin))
// die("$bin not exists");
}
// if (!is_readable($bin))
// die("Cannot read $bin. Please check the permissions");
// if (!is_executable($bin))
// die("File $bin is not executible");
if ($watermark_so) {
if (!preg_match('/\/watermark\.so$/', $watermark_so)) {
if (substr($watermark_so, -1) != "/")
$watermark_so .= "/";
$watermark_so .= "watermark.so";
}
// if (!file_exists($watermark_so))
// die("Watermark vhook $watermark_so not exists");
// if (!is_readable($watermark_so))
// die("Cannot read $watermark_so. Please check the permissions");
// if (!is_executable($watermark_so))
// die("File $watermark_so is not executible");
}
$this->bin = $bin;
$this->watermark_so = $watermark_so;
$this->encode_file_formats = $this->get_avail_formats('^ .E ');
$this->decode_file_formats = $this->get_avail_formats('^ D. ');
$this->encode_video_codecs = $this->get_avail_codecs('^ .EV... ');
$this->decode_video_codecs = $this->get_avail_codecs('^ D.V... ');
$this->encode_audio_codecs = $this->get_avail_codecs('^ .EA... ');
$this->decode_audio_codecs = $this->get_avail_codecs('^ D.A... ');
}
/** Fetch available file formats, matching with given regular expression
* @param string $rexpr
* @return array */
protected function get_avail_formats($rexpr) {
$cmd = "{$this->bin} -formats 2>&1 | grep -e '$rexpr' | cut -c 5-20";
return explode("\n", trim(preg_replace('/ +\n/', "\n", shell_exec($cmd))));
}
/** Fetch available codecs, matching with given regular expression
* @param string $rexpr
* @return array */
protected function get_avail_codecs($rexpr) {
$cmd = "{$this->bin} -formats 2>&1 | grep -e '$rexpr' | cut -c 9-100";
return explode("\n", trim(shell_exec($cmd)));
}
/** Returns file formats available for encoding
* @return array */
public function get_avail_encode_file_formats() {
return $this->encode_file_formats;
}
/** Returns file formats available for decoding
* @return array */
public function get_avail_decode_file_formats() {
return $this->decode_file_formats;
}
/** Returns video codecs available for encoding
* @return array */
public function get_avail_encode_video_codecs() {
return $this->encode_video_codecs;
}
/** Returns video codecs available for decoding
* @return array */
public function get_avail_decode_video_codecs() {
return $this->decode_video_codecs;
}
/** Returns audio codecs available for encoding
* @return array */
public function get_avail_encode_audio_codecs() {
return $this->encode_audio_codecs;
}
/** Returns audio codecs available for decoding
* @return array */
public function get_avail_decode_audio_codecs() {
return $this->decode_audio_codecs;
}
/** Grab video codec from the file
* @param string $file_path
* @return string */
public function get_video_codec($file_path) {
$file_path = str_replace('"', "\\\"", $file_path);
$cmd = "{$this->bin} -i \"$file_path\" 2>&1 | grep \" Stream #\" | grep \"Video: \" | awk '{print \$4}'";
$codec = preg_replace('/^([^,]*),?$/', "$1", trim(shell_exec($cmd)));
return $codec;
}
/** Grab audio codec from the file
* @param string $file_path
* @return string */
public function get_audio_codec($file_path) {
$file_path = str_replace('"', "\\\"", $file_path);
$cmd = "{$this->bin} -i \"$file_path\" 2>&1 | grep \" Stream #\" | grep \"Audio: \" | awk '{print \$4}'";
$codec = preg_replace('/^([^,]*),?$/', "$1", trim(shell_exec($cmd)));
return $codec;
}
/** Returns array($width, $height) with horizontal and vertical sizes
* @param string $file_path
* @return array */
public function get_video_size($file_path) {
$file_path = str_replace('"', "\\\"", $file_path);
$cmd = "{$this->bin} -i \"$file_path\" 2>&1 | grep \" Stream #\" | grep \"Video: \" | awk '{print \$6}'";
$size = preg_replace('/^(\d+x\d+),?$/', "$1", trim(shell_exec($cmd)));
$width = preg_replace('/^(\d+)x\d+$/', "$1", $size);
$height = preg_replace('/^\d+x(\d+)$/', "$1", $size);
return array($width, $height);
}
/** Returns video duration time (HH:MM:SS)
* @param string $file_path
* @return string */
public function get_duration($file_path) {
$file_path = str_replace('"', "\\\"", $file_path);
$cmd = "{$this->bin} -i \"$file_path\" 2>&1 | grep \"Duration: \" | awk '{print \$2}' | cut -c 1-8";
return shell_exec($cmd);
}
/** Check if the video in the file can be decoded
* @param string $file_path
* @return bool */
public function is_video_decodable($file_path) {
return in_array($this->get_video_codec($file_path), $this->decode_video_codecs);
}
/** Check if the audio in the file can be decoded
* @param string $file_path
* @return bool */
public function is_audio_decodable($file_path) {
return in_array($this->get_audio_codec($file_path), $this->decode_audio_codecs);
}