Grab FFMPEG from ZM_PATH_FFMPEG (if available), more robust error checking against codecs and paths

Signed-off-by: Jai Dhar <jdhar@eyezm.com>

git-svn-id: http://svn.zoneminder.com/svn/zm/trunk@3203 e3e1d417-86f3-4887-817a-d78f3d33393f
This commit is contained in:
jaidhar 2010-11-18 19:09:51 +00:00
parent bd31f9ec4b
commit 635d8e1dad
3 changed files with 75 additions and 61 deletions

View File

@ -119,58 +119,59 @@ body {
</head>
<?php
}
/** Returns whether necessary components for MPEG-4 event-generation are present */
function canGenerateMpeg4() {
/* Check for ffmpeg */
$res = shell_exec("which ffmpeg");
if ($res == "") {
logXml("ZMSTREAMER not installed, cannot generate MPEG-4");
return 0;
}
/* Check for libx264 support */
$res = shell_exec("ffmpeg -codecs 2> /dev/null | grep mpeg4");
if ($res == "") {
logXml("FFMPEG doesn't support MPEG-4");
return 0;
}
return 1;
}
/** Returns whether necessary components for H264 event-generation are present */
function canGenerateH264() {
/* Check for ffmpeg */
$res = shell_exec("which ffmpeg");
if ($res == "") {
logXml("ZMSTREAMER not installed, cannot stream H264");
return 0;
}
/* Check for libx264 support */
$res = shell_exec("ffmpeg -codecs 2> /dev/null | grep libx264");
if ($res == "") {
logXml("FFMPEG doesn't support libx264");
return 0;
}
return 1;
}
/** Returns whether necessary components for H264 streaming
* are present */
function canStream264() {
function canStream264($sup = 0) {
if (!ffmpegSupportsCodec("libx264")) {
if (!$sup) logXmlErr("FFMPEG not installed, accessible in path/ZM_PATH_FFMPEG, or doesn't support libx264");
return FALSE;
}
/* Make sure segmenter exists */
$res = shell_exec("which segmenter");
if ($res == "") {
logXml("H264 Requested, but segmenter not installed.");
return 0;
if (!exeExists(shell_exec("which segmenter"))) {
if (!$sup) logXmlErr("HTTP segmenter not installed or not accessible in path");
return FALSE;
}
/* Check for zmstreamer */
$res = shell_exec("which zmstreamer");
if ($res == "") {
logXml("ZMSTREAMER not installed, cannot stream H264");
return 0;
if (!exeExists(shell_exec("which zmstreamer"))) {
if (!$sup) logXmlErr("ZMSTREAMER not installed or not accessible in path");
return FALSE;
}
if (!canGenerateH264()) {
return 0;
return TRUE;
}
return 1;
/* Returns the path of ffmpeg by using define */
function getFfmpegPath()
{
if (defined("ZM_PATH_FFMPEG")) {
return ZM_PATH_FFMPEG;
} else {
/* Not defined, get it from using 'which' */
return shell_exec("which ffmpeg");
}
}
/* Returns whether ffmpeg supports a given codec. Takes into account
* whether FFMPEG exists or not */
function ffmpegSupportsCodec($codec)
{
if (!ffmpegExists()) return FALSE;
/* FFMPEG exists */
if (preg_match("/\b".$codec."\b/", shell_exec(getFfmpegPath()." -codecs 2> /dev/null")) > 0) {
/* More than one match */
return TRUE;
} else {
return FALSE;
}
}
function exeExists($exepath)
{
$path = trim($exepath);
return (file_exists($path) && is_readable($path) && ($path != ""));
}
/* Returns whether ffmpeg exists or not */
function ffmpegExists()
{
return exeExists(getFfmpegPath());
}
function getFfmpeg264FoutParms($br, $fout)
{
$ffparms = "-analyzeduration 0 -acodec copy -s 320x240";
@ -187,7 +188,7 @@ function getFfmpeg264FoutParms($br, $fout)
function getFfmpeg264Str($width, $height, $br, $fin, $fout)
{
$ffparms = getFfmpeg264FoutParms($br, $fout);
$ffstr = "ffmpeg -t ".ZM_XML_H264_MAX_DURATION." -analyzeduration 0 -i ";
$ffstr = getFfmpegPath()." -t ".ZM_XML_H264_MAX_DURATION." -analyzeduration 0 -i ";
$ffstr .= $fin." -f mpegts ".$ffparms;
return $ffstr;
}

View File

@ -41,6 +41,11 @@ if (isset($_GET['action'])) {
$width = getset('width', $dims['Width']);
$height = getset('height', $dims['Height']);
$br = getset('br', ZM_XML_H264_DEFAULT_BR);
/* Check that we can stream first */
if (!canStream264()) {
/* canStream264 will print out error */
exit;
}
$streamUrl = stream264fn($monitor, $width, $height, $br);
logXml("Using H264 Pipe Function: ".$streamUrl);
$pid = shell_exec($streamUrl);
@ -111,11 +116,20 @@ if (isset($_GET['action'])) {
$fps = getset('fps', ZM_WEB_VIDEO_MAXFPS);
$scale = getset('scale', 100);
$vcodec = getset('vcodec', ZM_XML_FEED_VCODEC);
/* Only allow H264 as of v1.2 and greater */
if (!requireVer("1","2") && !strcmp($vcodec,"h264")) {
logXml("Version 1.2 required for H264 Streaming");
/* Select which codec we want */
if (!strcmp($vcodec, "h264")) {
/* Validate that we can in fact stream H264 */
if (!canStream264()) {
/* canStream264 will print out error if
* there is one */
echo "Server cannot stream H264. Check XML log for details";
exit;
}
if (!requireVer("1", "2")) {
echo "H264 Streaming requires eyeZm v1.2 or above";
logXmlErr("H264 Streaming requires eyeZm v1.2 or above");
exit;
}
if (!strcmp($vcodec, "h264") && canStream264() && requireVer("1","2")) {
$br = getset('br', ZM_XML_H264_DEFAULT_BR);
/* H264 processing */
noCacheHeaders();
@ -150,6 +164,7 @@ if (isset($_GET['action'])) {
logXml("Streaming MJPEG on Monitor ".$monitor.", ".$width."x".$height." @".$fps."fps");
echo "<body>\n";
echo "<div style=\"border: 0px solid; padding: 0px; background-color: black; position: absolute; top: 0px; left; 0px; margin: 0px; width: ".$width."px; height: ".$height."px;\">\n";
logXml("Using stream source: ".$streamSrc);
outputImageStream("liveStream", $streamSrc, $width, $height, "stream");
echo "</div></body></html>";
} else {
@ -176,21 +191,19 @@ if (isset($_GET['action'])) {
$vcodec = getset('vcodec', ZM_XML_EVENT_VCODEC);
$baseURL = ZM_PATH_WEB."/".getEventPathSafe($event);
/* Here we validate the codec.
* MPEG-4 requires canGenerateMpeg4 and v1.1
* H264 requires canGenerateH264 and v1.2 */
* Check that FFMPEG exists and supports codecs */
if (!strcmp($vcodec, "mpeg4")) {
if (!canGenerateMpeg4()) {
logXmlErr("Selected MPEG-4 for event, but determined system cannot generate MPEG-4 with FFMPEG");
if (!ffmpegSupportsCodec("mpeg4")) {
logXmlErr("FFMPEG not installed, accessible in path/ZM_PATH_FFMPEG, or doesn't support mpeg4");
exit;
}
/* Can generate, we are good to go */
logXml("Selected MPEG-4 for viewing event ".$event['Id']);
$fname = "capture.mov";
$ffparms = "-vcodec mpeg4 -r ".ZM_XML_EVENT_FPS." ".$baseURL."/".$fname." 2> /dev/null";
} else if (!strcmp($vcodec, "h264")) {
if (!canGenerateH264()) {
logXmlErr("Selected H264 for event, but determined system cannot generate H-264 with FFMPEG");
if (!ffmpegSupportsCodec("libx264")) {
logXmlErr("FFMPEG not installed, accessible in path/ZM_PATH_FFMPEG, or doesn't support H264");
exit;
}
if (!requireVer("1","2")) {
@ -198,7 +211,6 @@ if (isset($_GET['action'])) {
exit;
}
/* Good to go */
logXml("Selected H264 for viewing event ".$event['Id']);
$fname = "capture.mp4";
$ffparms = getFfmpeg264FoutParms(
getset('br',ZM_XML_H264_DEFAULT_EVBR),
@ -208,8 +220,9 @@ if (isset($_GET['action'])) {
logXmlErr("Unknown codec ".$vcodec." selected for event viewing");
exit;
}
logXml("Selected ".$vcodec." for viewing event ".$event['Id']);
$fnameOut = $baseURL."/".$fname;
$shellCmd = "ffmpeg -y -r ".$fps." -i ".$baseURL."/%03d-capture.jpg";
$shellCmd = getFfmpegPath()." -y -r ".$fps." -i ".$baseURL."/%03d-capture.jpg";
$shellCmd .= " ".$ffparms;
logXml("Encoding event with command: ".$shellCmd);
$shellOutput = shell_exec($shellCmd);

View File

@ -153,7 +153,7 @@ xml_tag_val("RUNNING", $running);
xml_tag_val("PROTOVER", ZM_XML_PROTOCOL_VERSION);
xml_tag_val("FEATURESET", ZM_XML_FEATURE_SET);
xml_tag_val("VERSION", ZM_VERSION);
xml_tag_val("CANSTR264", canStream264());
xml_tag_val("CANSTR264", canStream264(1));
xml_tag_val("FVCODEC", ZM_XML_FEED_VCODEC);
xml_tag_val("FVTMT", ZM_XML_H264_TIMEOUT);
xml_tag_val("USER", $user['Username']);