<?php
namespace App\Subscriber\Content;
use App\Dictionary\ContentVideoMode;
use App\Event\Content\ContentVideoEncodingFinishedEvent;
use App\Event\Content\ContentVideoEncodingProgressedEvent;
use App\Event\Content\VideoFileUploadedEvent;
use App\Lib\Content\ContentVideoServiceAwareInterface;
use App\Lib\System\Job\VideoEncodingJob;
use App\Service\Content\VideoEncoderService;
use App\Service\Content\VideoService;
use App\Service\System\JobService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class ContentVideoEncodingSubscriber implements EventSubscriberInterface, ContentVideoServiceAwareInterface
{
protected VideoService $videoService;
protected JobService $jobService;
protected VideoEncoderService $encoderService;
/**
* ContentVideoEncodingSubscriber constructor.
*/
public function __construct(VideoService $videoService, VideoEncoderService $encoderService, JobService $jobService)
{
$this->setContentVideoService($videoService);
$this->jobService = $jobService;
$this->encoderService = $encoderService;
}
public function getContentVideoService(): VideoService
{
return $this->videoService;
}
/**
* @return $this|ContentVideoServiceAwareInterface
*/
public function setContentVideoService(VideoService $service): ContentVideoServiceAwareInterface
{
$this->videoService = $service;
return $this;
}
public static function getSubscribedEvents(): array
{
return [
VideoFileUploadedEvent::class => [
['onVideoFileUploadedCreateEncodeJobs', 9996],
],
ContentVideoEncodingProgressedEvent::class => [
['onEncodingProgressedUpdateJob', 0],
],
ContentVideoEncodingFinishedEvent::class => [
['onEncodingFinishedUpdateQualityFlag', 0],
],
];
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onVideoFileUploadedCreateEncodeJobs(VideoFileUploadedEvent $event)
{
$video = $event->getEntity();
if (!$meta = $video->getVideoMeta()) {
return;
}
$modes = [
ContentVideoMode::QUALITY_360P,
ContentVideoMode::QUALITY_720P,
ContentVideoMode::QUALITY_1080P,
];
foreach ($modes as $mode) {
if ($this->encoderService->videoSatisfiesMode($meta, $mode)) {
$job = new VideoEncodingJob($video->getId(), $mode);
$queue = VideoEncodingJob::queue;
$this->jobService->createSaveAndSchedule($job, '', null, $queue);
}
}
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onEncodingProgressedUpdateJob(ContentVideoEncodingProgressedEvent $event)
{
$job = $event->getEntity();
$progress = $event->getProgress();
$this->jobService->updateJobEntityProgress($job, $progress);
}
/**
* @throws \Doctrine\ORM\ORMException
* @throws \Doctrine\ORM\OptimisticLockException
*/
public function onEncodingFinishedUpdateQualityFlag(ContentVideoEncodingFinishedEvent $event)
{
$video = $event->getEntity();
$mode = $event->getVideoMode();
if (ContentVideoMode::QUALITY_1080P == $mode) {
$video->setIs1080p(true);
}
if (ContentVideoMode::QUALITY_720P == $mode) {
$video->setIs720p(true);
}
if (ContentVideoMode::QUALITY_360P == $mode) {
$video->setIs360p(true);
}
$this->getContentVideoService()->storeContentVideo($video);
}
}