Commit 2b35d274 authored by VicDeo's avatar VicDeo Committed by GitHub

Merge pull request #24975 from yellowspace/master

Provide support for user defined thumbnails for .mp4 movies
parents edc99ca3 4b2d1d75
......@@ -5,6 +5,7 @@
* @author Morris Jobke <hey@morrisjobke.de>
* @author Olivier Paroz <github@oparoz.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Lorenzo Perone <lorenzo.perone@yellowspace.net>
*
* @copyright Copyright (c) 2017, ownCloud GmbH
* @license AGPL-3.0
......@@ -27,6 +28,13 @@ namespace OC\Preview;
class Movie extends Provider {
public static $avconvBinary;
public static $ffmpegBinary;
public static $atomicParsleyBinary;
/**
* Keep track of movies without artwork to avoid retries in same request
* @var array
*/
private $noArtworkIndex = array();
/**
* {@inheritDoc}
......@@ -73,13 +81,48 @@ class Movie extends Provider {
}
/**
* @param int $maxX
* @param int $maxY
* @param string $absPath
* @param int $second
* @return bool|\OCP\IImage
* @param $absPath
* @return bool|string
*/
private function generateThumbNail($maxX, $maxY, $absPath, $second) {
private function extractMp4CoverArtwork($absPath) {
if (isset($this->noArtworkIndex[$absPath])) {
return false;
}
if (self::$atomicParsleyBinary) {
$suffix = substr($absPath, -4);
if ('.mp4' === strtolower($suffix)) {
$tmpFolder = \OC::$server->getTempManager()->getTemporaryFolder();
$tmpBase = $tmpFolder.'/Cover';
$cmd = self::$atomicParsleyBinary . ' ' .
escapeshellarg($absPath).
' --extractPixToPath ' . escapeshellarg($tmpBase) .
' > /dev/null 2>&1';
exec($cmd, $output, $returnCode);
if ($returnCode === 0) {
$endings = array('.jpg', '.png');
foreach ($endings as $ending) {
$extractedFile = $tmpBase.'_artwork_1'.$ending;
if (is_file($extractedFile) &&
filesize($extractedFile) > 0) {
return $extractedFile;
}
}
}
}
}
$this->noArtworkIndex[$absPath] = true;
return false;
}
/**
* @param $absPath
* @param $second
* @return bool|string
*/
private function generateFromMovie($absPath, $second) {
$tmpPath = \OC::$server->getTempManager()->getTemporaryFile();
if (self::$avconvBinary) {
......@@ -98,16 +141,37 @@ class Movie extends Provider {
exec($cmd, $output, $returnCode);
if ($returnCode === 0) {
return $tmpPath;
}
return false;
}
/**
* @param int $maxX
* @param int $maxY
* @param string $absPath
* @param int $second
* @return bool|\OCP\IImage
*/
private function generateThumbNail($maxX, $maxY, $absPath, $second) {
$extractedCover = $this->extractMp4CoverArtwork($absPath);
if (false !== $extractedCover) {
$tmpPath = $extractedCover;
} else {
$tmpPath = $this->generateFromMovie($absPath, $second);
}
if (is_string($tmpPath) && is_file($tmpPath)) {
$image = new \OC_Image();
$image->loadFromFile($tmpPath);
unlink($tmpPath);
if ($image->valid()) {
$image->scaleDownToFit($maxX, $maxY);
return $image;
}
}
unlink($tmpPath);
return false;
}
}
......@@ -6,6 +6,7 @@
* @author Robin Appelman <icewind@owncloud.com>
* @author Thomas Müller <thomas.mueller@tmit.eu>
* @author Vincent Petry <pvince81@owncloud.com>
* @author Lorenzo Perone <lorenzo.perone@yellowspace.net>
*
* @copyright Copyright (c) 2017, ownCloud GmbH
* @license AGPL-3.0
......@@ -328,14 +329,26 @@ class PreviewManager implements IPreview {
// Video requires avconv or ffmpeg and is therefor
// currently not supported on Windows.
if (in_array('OC\Preview\Movie', $this->getEnabledDefaultProvider())) {
// AtomicParsley would actually work under Windows.
$avconvBinary = \OC_Helper::findBinaryPath('avconv');
$ffmpegBinary = ($avconvBinary) ? null : \OC_Helper::findBinaryPath('ffmpeg');
$atomicParsleyBinary = \OC_Helper::findBinaryPath('AtomicParsley');
if ($avconvBinary || $ffmpegBinary) {
// FIXME // a bit hacky but didn't want to use subclasses
// FIXME // a bit hacky but didn't want to use subclasses
$registerProvider = false;
if (null !== $avconvBinary) {
\OC\Preview\Movie::$avconvBinary = $avconvBinary;
$registerProvider = true;
}
if (null !== $ffmpegBinary) {
\OC\Preview\Movie::$ffmpegBinary = $ffmpegBinary;
$registerProvider = true;
}
if (null !== $atomicParsleyBinary) {
\OC\Preview\Movie::$atomicParsleyBinary = $atomicParsleyBinary;
$registerProvider = true;
}
if (true === $registerProvider) {
$this->registerCoreProvider('\OC\Preview\Movie', '/video\/.*/');
}
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment