vendor/pimcore/pimcore/models/Asset/Video/ImageThumbnail.php line 73

Open in your IDE?
  1. <?php
  2. /**
  3.  * Pimcore
  4.  *
  5.  * This source file is available under two different licenses:
  6.  * - GNU General Public License version 3 (GPLv3)
  7.  * - Pimcore Commercial License (PCL)
  8.  * Full copyright and license information is available in
  9.  * LICENSE.md which is distributed with this source code.
  10.  *
  11.  *  @copyright  Copyright (c) Pimcore GmbH (http://www.pimcore.org)
  12.  *  @license    http://www.pimcore.org/license     GPLv3 and PCL
  13.  */
  14. namespace Pimcore\Model\Asset\Video;
  15. use Pimcore\Event\AssetEvents;
  16. use Pimcore\Event\FrontendEvents;
  17. use Pimcore\File;
  18. use Pimcore\Logger;
  19. use Pimcore\Model;
  20. use Pimcore\Model\Asset\Image;
  21. use Pimcore\Tool\Storage;
  22. use Symfony\Component\EventDispatcher\GenericEvent;
  23. use Symfony\Component\Lock\LockFactory;
  24. /**
  25.  * @property Model\Asset\Video|null $asset
  26.  */
  27. final class ImageThumbnail
  28. {
  29.     use Model\Asset\Thumbnail\ImageThumbnailTrait;
  30.     /**
  31.      * @internal
  32.      *
  33.      * @var int|null
  34.      */
  35.     protected $timeOffset;
  36.     /**
  37.      * @internal
  38.      *
  39.      * @var Image|null
  40.      */
  41.     protected $imageAsset;
  42.     /**
  43.      * @param Model\Asset\Video|null $asset
  44.      * @param string|array|Image\Thumbnail\Config|null $config
  45.      * @param int|null $timeOffset
  46.      * @param Image|null $imageAsset
  47.      * @param bool $deferred
  48.      */
  49.     public function __construct($asset$config null$timeOffset null$imageAsset null$deferred true)
  50.     {
  51.         $this->asset $asset;
  52.         $this->timeOffset $timeOffset;
  53.         $this->imageAsset $imageAsset;
  54.         $this->config $this->createConfig($config);
  55.         $this->deferred $deferred;
  56.     }
  57.     /**
  58.      * @param bool $deferredAllowed
  59.      *
  60.      * @return string
  61.      */
  62.     public function getPath($deferredAllowed true)
  63.     {
  64.         $pathReference $this->getPathReference($deferredAllowed);
  65.         $path $this->convertToWebPath($pathReference);
  66.         $event = new GenericEvent($this, [
  67.             'pathReference' => $pathReference,
  68.             'frontendPath' => $path,
  69.         ]);
  70.         \Pimcore::getEventDispatcher()->dispatch($eventFrontendEvents::ASSET_VIDEO_IMAGE_THUMBNAIL);
  71.         $path $event->getArgument('frontendPath');
  72.         return $path;
  73.     }
  74.     /**
  75.      * @internal
  76.      *
  77.      * @param bool $deferredAllowed
  78.      *
  79.      * @throws \Exception
  80.      */
  81.     public function generate($deferredAllowed true)
  82.     {
  83.         $deferred $deferredAllowed && $this->deferred;
  84.         $generated false;
  85.         if ($this->asset && empty($this->pathReference)) {
  86.             $cs $this->asset->getCustomSetting('image_thumbnail_time');
  87.             $im $this->asset->getCustomSetting('image_thumbnail_asset');
  88.             if ($im || $this->imageAsset) {
  89.                 if ($this->imageAsset) {
  90.                     $im $this->imageAsset;
  91.                 } else {
  92.                     $im Model\Asset::getById($im);
  93.                 }
  94.                 if ($im instanceof Image) {
  95.                     $imageThumbnail $im->getThumbnail($this->getConfig());
  96.                     $this->pathReference $imageThumbnail->getPathReference();
  97.                 }
  98.             }
  99.             if (empty($this->pathReference)) {
  100.                 $timeOffset $this->timeOffset;
  101.                 if (!is_numeric($timeOffset) && is_numeric($cs)) {
  102.                     $timeOffset $cs;
  103.                 }
  104.                 // fallback
  105.                 if (!is_numeric($timeOffset) && $this->asset instanceof Model\Asset\Video) {
  106.                     $timeOffset ceil($this->asset->getDuration() / 3);
  107.                 }
  108.                 $storage Storage::get('asset_cache');
  109.                 $cacheFilePath sprintf(
  110.                     '%s/%s/image-thumb__%s__video_original_image/time_%s.png',
  111.                     rtrim($this->asset->getRealPath(), '/'),
  112.                     $this->asset->getId(),
  113.                     $this->asset->getId(),
  114.                     $timeOffset
  115.                 );
  116.                 if (!$storage->fileExists($cacheFilePath)) {
  117.                     $lock \Pimcore::getContainer()->get(LockFactory::class)->createLock($cacheFilePath);
  118.                     $lock->acquire(true);
  119.                     // after we got the lock, check again if the image exists in the meantime - if not - generate it
  120.                     if (!$storage->fileExists($cacheFilePath)) {
  121.                         $tempFile File::getLocalTempFilePath('png');
  122.                         $converter \Pimcore\Video::getInstance();
  123.                         $converter->load($this->asset->getLocalFile());
  124.                         $converter->saveImage($tempFile$timeOffset);
  125.                         $generated true;
  126.                         $storage->write($cacheFilePathfile_get_contents($tempFile));
  127.                         unlink($tempFile);
  128.                     }
  129.                     $lock->release();
  130.                 }
  131.                 $cacheFileStream $storage->readStream($cacheFilePath);
  132.                 if ($this->getConfig()) {
  133.                     $this->getConfig()->setFilenameSuffix('time-' $timeOffset);
  134.                     try {
  135.                         $this->pathReference Image\Thumbnail\Processor::process(
  136.                             $this->asset,
  137.                             $this->getConfig(),
  138.                             $cacheFileStream,
  139.                             $deferred,
  140.                             $generated
  141.                         );
  142.                     } catch (\Exception $e) {
  143.                         Logger::error("Couldn't create image-thumbnail of video " $this->asset->getRealFullPath());
  144.                         Logger::error($e->getMessage());
  145.                     }
  146.                 }
  147.             }
  148.             if (empty($this->pathReference)) {
  149.                 $this->pathReference = [
  150.                     'type' => 'error',
  151.                     'src' => '/bundles/pimcoreadmin/img/filetype-not-supported.svg',
  152.                 ];
  153.             }
  154.             $event = new GenericEvent($this, [
  155.                 'deferred' => $deferred,
  156.                 'generated' => $generated,
  157.             ]);
  158.             \Pimcore::getEventDispatcher()->dispatch($eventAssetEvents::VIDEO_IMAGE_THUMBNAIL);
  159.         }
  160.     }
  161.     /**
  162.      * Get the public path to the thumbnail image.
  163.      * This method is here for backwards compatility.
  164.      * Up to Pimcore 1.4.8 a thumbnail was returned as a path to an image.
  165.      *
  166.      * @return string Public path to thumbnail image.
  167.      */
  168.     public function __toString()
  169.     {
  170.         return $this->getPath();
  171.     }
  172.     /**
  173.      * @param string|array|Image\Thumbnail\Config $selector
  174.      *
  175.      * @return Image\Thumbnail\Config|null
  176.      *
  177.      * @throws Model\Exception\NotFoundException
  178.      */
  179.     private function createConfig($selector)
  180.     {
  181.         $thumbnailConfig Image\Thumbnail\Config::getByAutoDetect($selector);
  182.         if (!empty($selector) && $thumbnailConfig === null) {
  183.             throw new Model\Exception\NotFoundException('Thumbnail definition "' . (is_string($selector) ? $selector '') . '" does not exist');
  184.         }
  185.         return $thumbnailConfig;
  186.     }
  187.     /**
  188.      * @param string $name
  189.      * @param int $highRes
  190.      *
  191.      * @return Image\Thumbnail|null
  192.      *
  193.      * @throws \Exception
  194.      */
  195.     public function getMedia($name$highRes 1)
  196.     {
  197.         $thumbConfig $this->getConfig();
  198.         if ($thumbConfig instanceof Image\Thumbnail\Config) {
  199.             $mediaConfigs $thumbConfig->getMedias();
  200.             if (isset($mediaConfigs[$name])) {
  201.                 $thumbConfigRes = clone $thumbConfig;
  202.                 $thumbConfigRes->selectMedia($name);
  203.                 $thumbConfigRes->setHighResolution($highRes);
  204.                 $thumbConfigRes->setMedias([]);
  205.                 $imgId $this->asset->getCustomSetting('image_thumbnail_asset');
  206.                 $img Model\Asset::getById($imgId);
  207.                 if ($img instanceof Image) {
  208.                     $thumb $img->getThumbnail($thumbConfigRes);
  209.                 }
  210.                 return $thumb ?? null;
  211.             } else {
  212.                 throw new \Exception("Media query '" $name "' doesn't exist in thumbnail configuration: " $thumbConfig->getName());
  213.             }
  214.         }
  215.         return null;
  216.     }
  217. }