diff --git a/scripts/thumbnail.sh b/scripts/thumbnail.sh new file mode 100755 index 0000000..272f0ed --- /dev/null +++ b/scripts/thumbnail.sh @@ -0,0 +1,6 @@ +#!/bin/sh + +dir="content/$1/" +mkdir -p "$dir" + +ffmpeg -i "landingzone/$1.vid" -vf "thumbnail,scale=640:360" -frames:v 1 "$dir/thumb.png" \ No newline at end of file diff --git a/scripts/transcode.sh b/scripts/transcode.sh index bfb7e52..ccccc06 100755 --- a/scripts/transcode.sh +++ b/scripts/transcode.sh @@ -1,7 +1,7 @@ #!/bin/sh dir="content/$1/" -mkdir "$dir" +mkdir -p "$dir" mkdir "$dir/360p/" mkdir "$dir/480p/" mkdir "$dir/720p/" diff --git a/src/Command/TranscodeCommand.php b/src/Command/TranscodeCommand.php index 51bbc79..23dfa56 100644 --- a/src/Command/TranscodeCommand.php +++ b/src/Command/TranscodeCommand.php @@ -42,16 +42,28 @@ class TranscodeCommand extends Command private function handleVideo(Video $video, OutputInterface $output) { - $this->videoService->setVideoState($video, Video::PROCESSING_TRANSCODE); + $output->writeln("starting creation of thumbnail..."); + $this->videoService->setVideoState($video, Video::PROCESSING_THUMBNAIL); + if ($this->callScript("thumbnail.sh", [$video->getId()->toString()])) { + $output->writeln("thumbnail creation successful"); + } else { + $output->writeln("thumbnail creation failed"); + $this->videoService->setVideoState($video, Video::FAIL); + return; + } + $output->writeln("starting transcoding..."); + $this->videoService->setVideoState($video, Video::PROCESSING_TRANSCODE); if ($this->callScript("transcode.sh", [$video->getId()->toString()])) { $output->writeln("transcoding successful"); - $this->videoService->setVideoState($video, Video::DONE); } else { $output->writeln("transcoding failed"); $this->videoService->setVideoState($video, Video::FAIL); + return; } + + $this->videoService->setVideoState($video, Video::DONE); } protected function execute(InputInterface $input, OutputInterface $output): int diff --git a/src/Controller/WatchController.php b/src/Controller/WatchController.php index 7d9416b..706ccae 100644 --- a/src/Controller/WatchController.php +++ b/src/Controller/WatchController.php @@ -26,6 +26,7 @@ class WatchController extends AbstractController private const PLAYLIST_MIME_TYPE = "application/x-mpegURL"; private const TS_FILE_MIME_TYPE = "video/MP2T"; + private const THUMBNAIL_MIME_TYPE = "image/png"; private const TS_FILE_FORMAT = "seg-%06d-ts"; @@ -122,7 +123,7 @@ class WatchController extends AbstractController /** * @Route("/{linkId}/{videoId}/{quality}/seg-{tsFileId}-ts", name="app_watch_segment", requirements={"quality"="360|480|720|1080", "tsFileId"="\d+"}) */ - public function tsFiles($videoId, $linkId, int $quality, int $tsFileId): Response + public function tsFile($videoId, $linkId, int $quality, int $tsFileId): Response { $data = $this->checkRequestData($videoId, $linkId); @@ -134,6 +135,21 @@ class WatchController extends AbstractController return $response; } + /** + * @Route("/{linkId}/{videoId}/thumb", name="app_watch_thumbnail") + */ + public function thumbnail($videoId, $linkId): Response + { + $data = $this->checkRequestData($videoId, $linkId); + + $file = self::CONTENT_DIRECTORY . $data["video"]->getId() . "/" . "thumb.png"; + + $response = new BinaryFileResponse($file); + $response->headers->set("Content-Type", self::THUMBNAIL_MIME_TYPE); + + return $response; + } + /** * @Route("/{linkId}/{videoId}/", name="app_watch_page") */ @@ -142,7 +158,10 @@ class WatchController extends AbstractController $data = $this->checkRequestData($videoId, $linkId); return $this->render("watch/watch.html.twig", [ - "thumbnail" => "thumbnail.jpg", + "thumbnail" => $this->generateUrl("app_watch_thumbnail", [ + "linkId" => $linkId, + "videoId" => $videoId + ]), "global" => $this->generateUrl("app_watch_global", [ "linkId" => $linkId, "videoId" => $videoId diff --git a/templates/watch/watch.html.twig b/templates/watch/watch.html.twig index e267fd2..2abf392 100644 --- a/templates/watch/watch.html.twig +++ b/templates/watch/watch.html.twig @@ -5,7 +5,7 @@ {% block stylesheets %} - +