<?php
namespace App\Subscriber\Content;
use App\Entity\ContentVideo;
use App\Event\Content\ContentVideoDeleteEvent;
use App\Event\Content\SnapshotsCreatedEvent;
use App\Event\Content\VideoFileUploadedEvent;
use App\Lib\System\Job\VideoSnapshotGeneratorJob;
use App\Service\Content\ContentService;
use App\Service\Content\SnapshotService;
use App\Service\Media\StorageLayer;
use App\Service\System\JobService;
use Liip\ImagineBundle\Service\FilterService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class VideoSnapshotSubscriber implements EventSubscriberInterface
{
protected SnapshotService $service;
protected ContentService $contentService;
protected FilterService $filterService;
protected JobService $jobService;
protected StorageLayer $storageLayer;
/**
* VideoSnapshotSubscriber constructor.
*/
public function __construct(SnapshotService $service, ContentService $contentService,
FilterService $filterService, JobService $jobService,
StorageLayer $layer)
{
$this->service = $service;
$this->contentService = $contentService;
$this->filterService = $filterService;
$this->jobService = $jobService;
$this->storageLayer = $layer;
}
public static function getSubscribedEvents(): array
{
return [
VideoFileUploadedEvent::class => [
['onVideoUploadedCreateSnapshots', 9997],
],
SnapshotsCreatedEvent::class => [
['onSnapshotsCreatedUpdateContent', 0],
],
ContentVideoDeleteEvent::class => [
// remove liipimagine cache files first.
// later, snapshot originals would not exist anymore.
['onVideoDeleteRemoveSnapshots', 9999],
],
];
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onVideoUploadedCreateSnapshots(VideoFileUploadedEvent $event)
{
$video = $event->getEntity();
// reset in DB if they will be re-created
if ($video->getPreviewsCreatedAt()) {
$video->setPreviewsCreatedAt(null);
$this->contentService->storeEntity($video);
}
$job = new VideoSnapshotGeneratorJob($video->getId());
$this->jobService->createSaveAndSchedule($job, '', null, VideoSnapshotGeneratorJob::queue);
}
public function onVideoDeleteRemoveSnapshots(ContentVideoDeleteEvent $event)
{
/**
* @var $video ContentVideo
*/
$video = $event->getEntity();
foreach ($this->service->getSnapshots($video) as $snapshot) {
$number = $snapshot->getFilenameNumber();
$basename = 'snapshot.'.$number.'.png';
$resolvePath = $this->storageLayer->getContentPublicFilePath($video, $basename);
foreach (['preview_small', 'preview_big'] as $filter) {
$this->filterService->bustCache($resolvePath, $filter);
}
}
if ($content = $video->getContent()) {
$this->service->deleteSnapshotsForContent($content);
}
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onSnapshotsCreatedUpdateContent(SnapshotsCreatedEvent $event)
{
$video = $event->getEntity();
$video->setPreviewsCreatedAt(new \DateTime());
$this->contentService->storeEntity($video);
}
}