diff --git a/lib/Video/Adapter/Ffmpeg.php b/lib/Video/Adapter/Ffmpeg.php index dd84bec9801..1d18ac4edbf 100644 --- a/lib/Video/Adapter/Ffmpeg.php +++ b/lib/Video/Adapter/Ffmpeg.php @@ -37,6 +37,11 @@ class Ffmpeg extends Adapter */ protected $arguments = []; + /** + * @var array + */ + private $tmpFiles = []; + /** * @return bool */ @@ -72,6 +77,16 @@ public static function getFfmpegCli() */ public function load($file) { + if (!stream_is_local($file)) { + // Create local copy of remote file + $tmpFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/ffmpeg-tmp-' . uniqid() . '.' . File::getFileExtension($file); + recursiveCopy($file, $tmpFile); + + $file = $tmpFile; + + $this->tmpFiles[] = $tmpFile; + } + $this->file = $file; $this->setProcessId(uniqid()); @@ -229,6 +244,10 @@ public function destroy() Logger::debug("FFMPEG finished, last message was: \n" . file_get_contents($this->getConversionLogFile())); $this->deleteConversionLogFile(); } + + foreach ($this->tmpFiles as $tmpFile) { + @unlink($tmpFile); + } } public function deleteConversionLogFile() diff --git a/lib/helper-functions.php b/lib/helper-functions.php index f07dd48d630..b6e12acde0b 100644 --- a/lib/helper-functions.php +++ b/lib/helper-functions.php @@ -455,14 +455,14 @@ function recursiveCopy($source, $destination) if ($item->isDir()) { \Pimcore\File::mkdir($destination . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); } else { - copy($item, $destination . DIRECTORY_SEPARATOR . $iterator->getSubPathName()); + copy($item, $destination . DIRECTORY_SEPARATOR . $iterator->getSubPathName(), \Pimcore\File::getContext()); } } } elseif (is_file($source)) { if (is_dir(dirname($destination))) { \Pimcore\File::mkdir(dirname($destination)); } - copy($source, $destination); + copy($source, $destination, \Pimcore\File::getContext()); } return true; diff --git a/models/Asset/Video.php b/models/Asset/Video.php index b7290d388c9..9592573cab3 100644 --- a/models/Asset/Video.php +++ b/models/Asset/Video.php @@ -193,7 +193,9 @@ protected function getDurationFromBackend(?string $filePath = null) $converter = \Pimcore\Video::getInstance(); $converter->load($filePath); - return $converter->getDuration(); + $duration = $converter->getDuration(); + $converter->destroy(); + return $duration; } return null; @@ -210,7 +212,9 @@ protected function getDimensionsFromBackend() $converter = \Pimcore\Video::getInstance(); $converter->load($this->getFileSystemPath()); - return $converter->getDimensions(); + $dimensions = $converter->getDimensions(); + $converter->destroy(); + return $dimensions; } return null; diff --git a/models/Asset/Video/ImageThumbnail.php b/models/Asset/Video/ImageThumbnail.php index 44911c756f5..117f9a85cf3 100644 --- a/models/Asset/Video/ImageThumbnail.php +++ b/models/Asset/Video/ImageThumbnail.php @@ -176,10 +176,23 @@ public function generate() Model\Tool\Lock::release($lockKey); } + $converter->destroy(); + if ($this->getConfig()) { $this->getConfig()->setFilenameSuffix('time-' . $timeOffset); try { + // The path can be remote. In that case, the processor will create a local copy of the asset, which is the video itself. + // That is not what is intended, as we are tying to generate a thumbnail based on the already existing video still that + // the converter created earlier. To prevent the processor from doing that, we will create a local copy here if needed + $tmpFile = null; + if (!stream_is_local($path)) { + $tmpFile = PIMCORE_SYSTEM_TEMP_DIRECTORY . '/video-thumbnail-' . uniqid() . '.png'; + + recursiveCopy($path, $tmpFile); + $path = $tmpFile; + } + $path = Image\Thumbnail\Processor::process( $this->asset, $this->getConfig(), @@ -188,6 +201,10 @@ public function generate() true, $generated ); + + if ($tmpFile) { + @unlink($tmpFile); + } } catch (\Exception $e) { Logger::error("Couldn't create image-thumbnail of video " . $this->asset->getRealFullPath()); Logger::error($e);