Fall back to full file for video previews

If the first 5 MB are not enough to grab a useful frame for the
thumbnail preview, fall back to reading the full file.

Signed-off-by: Vincent Petry <vincent@nextcloud.com>
This commit is contained in:
Vincent Petry 2021-09-18 10:46:48 +02:00 committed by backportbot[bot]
parent eb3d06c53a
commit 389c7dcd6a
2 changed files with 31 additions and 11 deletions

View file

@ -50,17 +50,34 @@ class Movie extends ProviderV2 {
public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage {
// TODO: use proc_open() and stream the source file ?
$absPath = $this->getLocalFile($file, 5242880); // only use the first 5MB
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 5);
if ($result === null) {
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 1);
if ($result === null) {
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 0);
}
$result = null;
if ($this->useTempFile($file)) {
// try downloading 5 MB first as it's likely that the first frames are present there
// in some cases this doesn't work for example when the moov atom is at the
// end of the file, so if it fails we fall back to getting the full file
$sizeAttempts = [5242880, null];
} else {
// size is irrelevant, only attempt once
$sizeAttempts = [null];
}
$this->cleanTmpFiles();
foreach ($sizeAttempts as $size) {
$absPath = $this->getLocalFile($file, $size);
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 5);
if ($result === null) {
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 1);
if ($result === null) {
$result = $this->generateThumbNail($maxX, $maxY, $absPath, 0);
}
}
$this->cleanTmpFiles();
if ($result !== null) {
break;
}
}
return $result;
}

View file

@ -70,6 +70,10 @@ abstract class ProviderV2 implements IProviderV2 {
*/
abstract public function getThumbnail(File $file, int $maxX, int $maxY): ?IImage;
protected function useTempFile(File $file) {
return $file->isEncrypted() || !$file->getStorage()->isLocal();
}
/**
* Get a path to either the local file or temporary file
*
@ -78,8 +82,7 @@ abstract class ProviderV2 implements IProviderV2 {
* @return string
*/
protected function getLocalFile(File $file, int $maxSize = null): string {
$useTempFile = $file->isEncrypted() || !$file->getStorage()->isLocal();
if ($useTempFile) {
if ($this->useTempFile($file)) {
$absPath = \OC::$server->getTempManager()->getTemporaryFile();
$content = $file->fopen('r');