From 567d20a165d59900d6cfc9db4aad2cfbfe202cfb Mon Sep 17 00:00:00 2001 From: Varun Patil Date: Wed, 9 Nov 2022 02:42:42 -0800 Subject: [PATCH] Add transcode checks --- lib/Command/VideoSetup.php | 16 ++++++++----- lib/Controller/PageController.php | 3 +++ lib/Controller/PublicController.php | 12 ++++++++++ lib/Controller/VideoController.php | 10 +++++---- src/components/PsVideo.ts | 35 ++++++++++++++++++++++++----- 5 files changed, 61 insertions(+), 15 deletions(-) diff --git a/lib/Command/VideoSetup.php b/lib/Command/VideoSetup.php index abdb0eb3..719d414a 100644 --- a/lib/Command/VideoSetup.php +++ b/lib/Command/VideoSetup.php @@ -52,8 +52,9 @@ class VideoSetup extends Command { // Check nohup binary $nohup = shell_exec('nohup --version'); - if (!$nohup || strpos($nohup, 'nohup') === false) { + if (!$nohup || false === strpos($nohup, 'nohup')) { $output->writeln('nohup binary not found. Please install nohup.'); + return $this->suggestDisable($output); } @@ -77,6 +78,7 @@ class VideoSetup extends Command if (null === $ffmpeg || null === $ffprobe) { $output->writeln('ffmpeg and ffprobe are required for video transcoding'); + return $this->suggestDisable($output); } @@ -90,16 +92,18 @@ class VideoSetup extends Command if (!$arch || !$libc) { $output->writeln('Compatible go-transcode binary not found'); $this->suggestGoTranscode($output); + return $this->suggestDisable($output); } $goTranscodePath = realpath(__DIR__."/../../exiftool-bin/go-transcode-{$arch}-{$libc}"); - $output->writeln("Trying go-transcode from $goTranscodePath"); + $output->writeln("Trying go-transcode from {$goTranscodePath}"); - $goTranscode = shell_exec($goTranscodePath . ' --help'); + $goTranscode = shell_exec($goTranscodePath.' --help'); if (!$goTranscode || false === strpos($goTranscode, 'Available Commands')) { $output->writeln('go-transcode could not be run'); $this->suggestGoTranscode($output); + return $this->suggestDisable($output); } @@ -120,10 +124,11 @@ class VideoSetup extends Command if ('n' === trim($line)) { $this->config->setSystemValue('memories.no_transcode', true); $output->writeln('Transcoding and HLS are now disabled'); + return 0; } - $tConfig = realpath(__DIR__."/../../transcoder.yaml"); + $tConfig = realpath(__DIR__.'/../../transcoder.yaml'); $this->config->setSystemValue('memories.transcoder', $goTranscodePath); $this->config->setSystemValue('memories.transcoder_config', $tConfig); @@ -140,7 +145,8 @@ class VideoSetup extends Command $output->writeln('Once built, point the path to the binary in the config for `memories.transcoder`'); } - protected function suggestDisable(OutputInterface $output) { + protected function suggestDisable(OutputInterface $output) + { $output->writeln('Without transcoding, video playback may be slow and limited'); $output->writeln('Do you want to disable transcoding and HLS streaming? [y/N]'); $handle = fopen('php://stdin', 'r'); diff --git a/lib/Controller/PageController.php b/lib/Controller/PageController.php index 2da07c25..8097d721 100644 --- a/lib/Controller/PageController.php +++ b/lib/Controller/PageController.php @@ -91,6 +91,9 @@ class PageController extends Controller // App version $this->initialState->provideInitialState('version', $this->appManager->getAppInfo('memories')['version']); + // Video configuration + $this->initialState->provideInitialState('notranscode', $this->config->getSystemValue('memories.no_transcode', 'UNSET')); + $policy = new ContentSecurityPolicy(); $policy->addAllowedWorkerSrcDomain("'self'"); $policy->addAllowedScriptDomain("'self'"); diff --git a/lib/Controller/PublicController.php b/lib/Controller/PublicController.php index 1e6eaa9f..e546742a 100644 --- a/lib/Controller/PublicController.php +++ b/lib/Controller/PublicController.php @@ -105,10 +105,22 @@ class PublicController extends AuthPublicShareController // App version $this->initialState->provideInitialState('version', $this->appManager->getAppInfo('memories')['version']); + // Video configuration + $this->initialState->provideInitialState('notranscode', $this->config->getSystemValue('memories.no_transcode', 'UNSET')); + $policy = new ContentSecurityPolicy(); $policy->addAllowedWorkerSrcDomain("'self'"); $policy->addAllowedScriptDomain("'self'"); + // Video player + $policy->addAllowedWorkerSrcDomain('blob:'); + $policy->addAllowedScriptDomain('blob:'); + $policy->addAllowedMediaDomain('blob:'); + + // Allow nominatim for metadata + $policy->addAllowedConnectDomain('nominatim.openstreetmap.org'); + $policy->addAllowedFrameDomain('www.openstreetmap.org'); + $response = new TemplateResponse($this->appName, 'main'); $response->setContentSecurityPolicy($policy); diff --git a/lib/Controller/VideoController.php b/lib/Controller/VideoController.php index 463860a5..28f7b7d0 100644 --- a/lib/Controller/VideoController.php +++ b/lib/Controller/VideoController.php @@ -49,7 +49,7 @@ class VideoController extends ApiBase } // Make sure not running in read-only mode - if ($this->config->getSystemValue('memories.no_transcode', 'UNSET') !== false) { + if (false !== $this->config->getSystemValue('memories.no_transcode', 'UNSET')) { return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN); } @@ -92,8 +92,8 @@ class VideoController extends ApiBase // Check if already running exec('ps a | grep go-transcode | grep -v grep', $procs); if (0 === \count($procs)) { - shell_exec("mkdir -p $tmpDir/transcoder"); // php func has some weird problems - shell_exec("nohup $transcoder serve --config $tConfig > $tmpDir/transcoder/run.log 2>&1 & > /dev/null"); + shell_exec("mkdir -p {$tmpDir}/transcoder"); // php func has some weird problems + shell_exec("nohup {$transcoder} serve --config {$tConfig} > {$tmpDir}/transcoder/run.log 2>&1 & > /dev/null"); } // wait for 2s and try again @@ -115,7 +115,8 @@ class VideoController extends ApiBase return $response; } - private function getUpstream($path, $profile) { + private function getUpstream($path, $profile) + { $ch = curl_init("http://localhost:47788/vod/{$path}/{$profile}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); @@ -124,6 +125,7 @@ class VideoController extends ApiBase $contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $returnCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); + return [$data, $contentType, $returnCode]; } } diff --git a/src/components/PsVideo.ts b/src/components/PsVideo.ts index 12ede6aa..cef0bee7 100644 --- a/src/components/PsVideo.ts +++ b/src/components/PsVideo.ts @@ -1,11 +1,18 @@ import PhotoSwipe from "photoswipe"; import { generateUrl } from "@nextcloud/router"; +import { loadState } from "@nextcloud/initial-state"; import videojs from "video.js"; import "video.js/dist/video-js.min.css"; import "videojs-contrib-quality-levels"; import "videojs-hls-quality-selector"; +const config_noTranscode = loadState( + "memories", + "notranscode", + "UNSET" +) as boolean | string; + /** * Check if slide has video content * @@ -71,10 +78,11 @@ class VideoContentSetup { // do not append video on nearby slides pswp.on("appendHeavy", (e) => { if (isVideoContent(e.slide)) { + const content = e.slide.content; + if (!e.slide.isActive) { e.preventDefault(); - } else { - const content = e.slide.content; + } else if (content.videoElement) { const fileid = content.data.photo.fileid; // Create hls sources if enabled @@ -82,10 +90,13 @@ class VideoContentSetup { const baseUrl = generateUrl( `/apps/memories/api/video/transcode/${fileid}` ); - hlsSources.push({ - src: `${baseUrl}/index.m3u8`, - type: "application/x-mpegURL", - }); + + if (!config_noTranscode) { + hlsSources.push({ + src: `${baseUrl}/index.m3u8`, + type: "application/x-mpegURL", + }); + } const overrideNative = !videojs.browser.IS_SAFARI; content.videojs = videojs(content.videoElement, { @@ -246,6 +257,18 @@ class VideoContentSetup { return; } + if (config_noTranscode === "UNSET") { + content.element = document.createElement("div"); + content.element.innerHTML = + "Video not configured. Run occ memories:video-setup"; + content.element.style.color = "red"; + content.element.style.display = "flex"; + content.element.style.alignItems = "center"; + content.element.style.justifyContent = "center"; + content.onLoaded(); + return; + } + content.state = "loading"; content.type = "video"; // TODO: move this to pswp core?