diff --git a/appinfo/routes.php b/appinfo/routes.php index 6915ed88..b5d367ba 100644 --- a/appinfo/routes.php +++ b/appinfo/routes.php @@ -58,7 +58,7 @@ return [ ['name' => 'Archive#archive', 'url' => '/api/archive/{id}', 'verb' => 'PATCH'], - ['name' => 'Video#transcode', 'url' => '/api/video/transcode/{fileid}/{profile}', 'verb' => 'GET'], + ['name' => 'Video#transcode', 'url' => '/api/video/transcode/{client}/{fileid}/{profile}', 'verb' => 'GET'], // Config API ['name' => 'Other#setUserConfig', 'url' => '/api/config/{key}', 'verb' => 'PUT'], diff --git a/lib/Command/VideoSetup.php b/lib/Command/VideoSetup.php index 752858c9..6afa8669 100644 --- a/lib/Command/VideoSetup.php +++ b/lib/Command/VideoSetup.php @@ -82,34 +82,33 @@ class VideoSetup extends Command return $this->suggestDisable($output); } - // Check go-transcode binary - $output->writeln('Checking for go-transcode binary'); + // Check go-vod binary + $output->writeln('Checking for go-vod binary'); // Detect architecture $arch = \OCA\Memories\Util::getArch(); - $libc = \OCA\Memories\Util::getLibc(); - if (!$arch || !$libc) { - $output->writeln('Compatible go-transcode binary not found'); - $this->suggestGoTranscode($output); + if (!$arch) { + $output->writeln('Compatible go-vod binary not found'); + $this->suggestGoVod($output); return $this->suggestDisable($output); } - $goTranscodePath = realpath(__DIR__."/../../exiftool-bin/go-transcode-{$arch}-{$libc}"); - $output->writeln("Trying go-transcode from {$goTranscodePath}"); - chmod($goTranscodePath, 0755); + $goVodPath = realpath(__DIR__."/../../exiftool-bin/go-vod-{$arch}"); + $output->writeln("Trying go-vod from {$goVodPath}"); + chmod($goVodPath, 0755); - $goTranscode = shell_exec($goTranscodePath.' --help'); - if (!$goTranscode || false === strpos($goTranscode, 'Available Commands')) { - $output->writeln('go-transcode could not be run'); - $this->suggestGoTranscode($output); + $goVod = shell_exec($goVodPath.' test'); + if (!$goVod || false === strpos($goVod, 'test successful')) { + $output->writeln('go-vod could not be run'); + $this->suggestGoVod($output); return $this->suggestDisable($output); } // Go transcode is working. Yay! - $output->writeln('go-transcode is installed!'); + $output->writeln('go-vod is installed!'); $output->writeln(''); $output->writeln('You can use transcoding and HLS streaming'); $output->writeln('This is recommended for better performance, but has implications if'); @@ -127,10 +126,7 @@ class VideoSetup extends Command return 0; } - $tConfig = realpath(__DIR__.'/../../transcoder.yaml'); - - $this->config->setSystemValue('memories.transcoder', $goTranscodePath); - $this->config->setSystemValue('memories.transcoder_config', $tConfig); + $this->config->setSystemValue('memories.transcoder', $goVodPath); $this->config->setSystemValue('memories.no_transcode', false); $output->writeln('Transcoding and HLS are now enabled!'); @@ -153,10 +149,10 @@ class VideoSetup extends Command return 0; } - protected function suggestGoTranscode(OutputInterface $output): void + protected function suggestGoVod(OutputInterface $output): void { - $output->writeln('You may build go-transcode from source'); - $output->writeln('It can be downloaded from https://github.com/pulsejet/go-transcode'); + $output->writeln('You may build go-vod from source'); + $output->writeln('It can be downloaded from https://github.com/pulsejet/go-vod'); $output->writeln('Once built, point the path to the binary in the config for `memories.transcoder`'); } diff --git a/lib/Controller/VideoController.php b/lib/Controller/VideoController.php index 07ada043..66f14345 100644 --- a/lib/Controller/VideoController.php +++ b/lib/Controller/VideoController.php @@ -36,12 +36,9 @@ class VideoController extends ApiBase * * Transcode a video to HLS by proxy * - * @param string fileid - * @param string video profile - * * @return JSONResponse an empty JSONResponse with respective http status code */ - public function transcode(string $fileid, string $profile): Http\Response + public function transcode(string $client, string $fileid, string $profile): Http\Response { $user = $this->userSession->getUser(); if (null === $user) { @@ -53,6 +50,11 @@ class VideoController extends ApiBase return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN); } + // Check client identifier is 8 characters or more + if (\strlen($client) < 8) { + return new JSONResponse(['message' => 'Invalid client identifier'], Http::STATUS_BAD_REQUEST); + } + // Get file $files = $this->rootFolder->getUserFolder($user->getUID())->getById($fileid); if (0 === \count($files)) { @@ -78,14 +80,13 @@ class VideoController extends ApiBase } // Make upstream request - [$data, $contentType, $returnCode] = $this->getUpstream($path, $profile); + [$data, $contentType, $returnCode] = $this->getUpstream($client, $path, $profile); // If status code was 0, it's likely the server is down // Make one attempt to start if we can't find the process if (0 === $returnCode) { $transcoder = $this->config->getSystemValue('memories.transcoder', false); - $tConfig = $this->config->getSystemValue('memories.transcoder_config', false); - if (!$transcoder || !$tConfig) { + if (!$transcoder) { return new JSONResponse(['message' => 'Transcoder not configured'], Http::STATUS_INTERNAL_SERVER_ERROR); } @@ -97,15 +98,12 @@ 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("{$env} nohup {$transcoder} serve --config {$tConfig} > {$tmpDir}/transcoder/run.log 2>&1 & > /dev/null"); - } + shell_exec("pkill {$transcoder}"); + shell_exec("{$env} nohup {$transcoder} > {$tmpDir}/go-vod.log 2>&1 & > /dev/null"); - // wait for 2s and try again - sleep(2); - [$data, $contentType, $returnCode] = $this->getUpstream($path, $profile); + // wait for 1s and try again + sleep(1); + [$data, $contentType, $returnCode] = $this->getUpstream($client, $path, $profile); } // Check data was received @@ -117,15 +115,15 @@ class VideoController extends ApiBase $response = new DataDisplayResponse($data, Http::STATUS_OK, [ 'Content-Type' => $contentType, ]); - $response->cacheFor(3600 * 24, false, false); + $response->cacheFor(0, false, false); return $response; } - private function getUpstream($path, $profile) + private function getUpstream($client, $path, $profile) { $path = rawurlencode($path); - $ch = curl_init("http://127.0.0.1:47788/vod/{$path}/{$profile}"); + $ch = curl_init("http://127.0.0.1:47788/{$client}{$path}/{$profile}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_HEADER, 0); diff --git a/scripts/get-exiftool.sh b/scripts/get-exiftool.sh index 44217fc2..363b3fc8 100755 --- a/scripts/get-exiftool.sh +++ b/scripts/get-exiftool.sh @@ -17,11 +17,9 @@ mv "exiftool-$exifver" exiftool rm -rf *.zip exiftool/t exiftool/html chmod 755 exiftool/exiftool -gotranscode="v0.0.3" -wget -q "https://github.com/pulsejet/go-transcode/releases/download/$gotranscode/go-transcode-amd64-musl" -wget -q "https://github.com/pulsejet/go-transcode/releases/download/$gotranscode/go-transcode-amd64-glibc" -wget -q "https://github.com/pulsejet/go-transcode/releases/download/$gotranscode/go-transcode-aarch64-musl" -wget -q "https://github.com/pulsejet/go-transcode/releases/download/$gotranscode/go-transcode-aarch64-glibc" -chmod 755 go-transcode-* +govod="0.0.2" +wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-amd64" +wget -q "https://github.com/pulsejet/go-vod/releases/download/$govod/go-vod-aarch64" +chmod 755 go-vod-* cd .. diff --git a/src/components/PsVideo.ts b/src/components/PsVideo.ts index b9660dc7..25a652d7 100644 --- a/src/components/PsVideo.ts +++ b/src/components/PsVideo.ts @@ -14,6 +14,10 @@ const config_noTranscode = loadState( "UNSET" ) as boolean | string; +// Generate client id for this instance +// Does not need to be cryptographically secure +const clientId = Math.random().toString(36).substring(2, 15).padEnd(12, "0"); + /** * Check if slide has video content * @@ -89,7 +93,7 @@ class VideoContentSetup { // Create hls sources if enabled let sources: any[] = []; const baseUrl = generateUrl( - `/apps/memories/api/video/transcode/${fileid}` + `/apps/memories/api/video/transcode/${clientId}/${fileid}` ); if (!config_noTranscode) { diff --git a/transcoder.yaml b/transcoder.yaml deleted file mode 100644 index 063b40e7..00000000 --- a/transcoder.yaml +++ /dev/null @@ -1,59 +0,0 @@ -# allow debug outputs -debug: false - -# mount debug pprof endpoint at /debug/pprof/ -pprof: false - -# bind server to IP:PORT (use :47788 for all connections) -# DO NOT expose this port to the world -bind: localhost:47788 - -# X-Forwarded-For headers will be used to determine the client IP -proxy: true - -# For static files -vod: - # Root directory for media - media-dir: / - - # Temporary transcode output directory, if empty, default tmp folder will be used - transcode-dir: /tmp/transcoder/data - - # Available video profiles - # Do not change these - video-profiles: - 360p: - width: 640 # px - height: 360 # px - bitrate: 800 # kbps - 480p: - width: 640 - height: 480 - bitrate: 1200 - 720p: - width: 1280 - height: 720 - bitrate: 2800 - 1080p: - width: 1920 - height: 1080 - bitrate: 5000 - - # Use video keyframes as existing reference for chunks split - # Using this might cause long probing times in order to get - # all keyframes - therefore they should be cached - video-keyframes: false - - # Single audio profile used - audio-profile: - bitrate: 192 # kbps - - # If cache is enabled - cache: true - # If dir is empty, cache will be stored in the same directory as media source - # If not empty, cache files will be saved to specified directory - cache-dir: /tmp/transcoder/cache - - # OPTIONAL: Use custom ffmpeg & ffprobe binary paths - ffmpeg-binary: ffmpeg - ffprobe-binary: ffprobe