Skip to content
Snippets Groups Projects
Commit 0c6af551 authored by Vincent Petry's avatar Vincent Petry
Browse files

Added ffmpeg fallback when avconv is not available

On some distros, avconv isn't available yet.
This fix adds a fallback to ffmpeg.
When none is found, no error message is displayed in the console any
more.

Fixes #5745

Also, this now uses exec() instead of shell_exec() to be able to get the
return code.

The binary path found with "which" is now used to prevent further FS
binary lookup when running the commands.

Moved the "-ss" parameter before "-i" for ffmpeg.
parent 01344481
No related branches found
No related tags found
No related merge requests found
......@@ -8,21 +8,37 @@
*/
namespace OC\Preview;
function findBinaryPath($program) {
exec('which ' . escapeshellarg($program) . ' 2> /dev/null', $output, $returnCode);
if ($returnCode === 0 && count($output) > 0) {
return escapeshellcmd($output[0]);
}
return null;
}
// movie preview is currently not supported on Windows
if (!\OC_Util::runningOnWindows()) {
$isShellExecEnabled = !in_array('shell_exec', explode(', ', ini_get('disable_functions')));
$whichAVCONV = ($isShellExecEnabled ? shell_exec('which avconv') : '');
$isAVCONVAvailable = !empty($whichAVCONV);
$isExecEnabled = !in_array('exec', explode(', ', ini_get('disable_functions')));
if ($isExecEnabled) {
$avconvBinary = findBinaryPath('avconv');
if (!$avconvBinary) {
$ffmpegBinary = findBinaryPath('ffmpeg');
}
}
if($isShellExecEnabled && $isAVCONVAvailable) {
if($isExecEnabled && ( $avconvBinary || $ffmpegBinary )) {
class Movie extends Provider {
public static $avconvBinary;
public static $ffmpegBinary;
public function getMimeType() {
return '/video\/.*/';
}
public function getThumbnail($path, $maxX, $maxY, $scalingup, $fileview) {
// TODO: use proc_open() and stream the source file ?
$absPath = \OC_Helper::tmpFile();
$tmpPath = \OC_Helper::tmpFile();
......@@ -31,20 +47,38 @@ if (!\OC_Util::runningOnWindows()) {
$firstmb = stream_get_contents($handle, 1048576); //1024 * 1024 = 1048576
file_put_contents($absPath, $firstmb);
//$cmd = 'ffmpeg -y -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 -ss 1 -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) . ' ' . $tmpPath;
$cmd = 'avconv -an -y -ss 1 -i ' . escapeshellarg($absPath) . ' -f mjpeg -vframes 1 ' . escapeshellarg($tmpPath);
if (self::$avconvBinary) {
$cmd = self::$avconvBinary . ' -an -y -ss 1'.
' -i ' . escapeshellarg($absPath) .
' -f mjpeg -vframes 1 ' . escapeshellarg($tmpPath) .
' > /dev/null 2>&1';
}
else {
$cmd = self::$ffmpegBinary . ' -y -ss 1' .
' -i ' . escapeshellarg($absPath) .
' -f mjpeg -vframes 1' .
' -s ' . escapeshellarg($maxX) . 'x' . escapeshellarg($maxY) .
' ' . $tmpPath .
' > /dev/null 2>&1';
}
shell_exec($cmd);
$image = new \OC_Image($tmpPath);
exec($cmd, $output, $returnCode);
unlink($absPath);
unlink($tmpPath);
return $image->valid() ? $image : false;
if ($returnCode === 0) {
$image = new \OC_Image($tmpPath);
unlink($tmpPath);
return $image->valid() ? $image : false;
}
return false;
}
}
// a bit hacky but didn't want to use subclasses
Movie::$avconvBinary = $avconvBinary;
Movie::$ffmpegBinary = $ffmpegBinary;
\OC\Preview::registerProvider('OC\Preview\Movie');
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment