Add transcode checks
parent
bae6662e37
commit
567d20a165
|
@ -52,8 +52,9 @@ class VideoSetup extends Command
|
||||||
{
|
{
|
||||||
// Check nohup binary
|
// Check nohup binary
|
||||||
$nohup = shell_exec('nohup --version');
|
$nohup = shell_exec('nohup --version');
|
||||||
if (!$nohup || strpos($nohup, 'nohup') === false) {
|
if (!$nohup || false === strpos($nohup, 'nohup')) {
|
||||||
$output->writeln('<error>nohup binary not found. Please install nohup.</error>');
|
$output->writeln('<error>nohup binary not found. Please install nohup.</error>');
|
||||||
|
|
||||||
return $this->suggestDisable($output);
|
return $this->suggestDisable($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -77,6 +78,7 @@ class VideoSetup extends Command
|
||||||
|
|
||||||
if (null === $ffmpeg || null === $ffprobe) {
|
if (null === $ffmpeg || null === $ffprobe) {
|
||||||
$output->writeln('ffmpeg and ffprobe are required for video transcoding');
|
$output->writeln('ffmpeg and ffprobe are required for video transcoding');
|
||||||
|
|
||||||
return $this->suggestDisable($output);
|
return $this->suggestDisable($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,16 +92,18 @@ class VideoSetup extends Command
|
||||||
if (!$arch || !$libc) {
|
if (!$arch || !$libc) {
|
||||||
$output->writeln('<error>Compatible go-transcode binary not found</error>');
|
$output->writeln('<error>Compatible go-transcode binary not found</error>');
|
||||||
$this->suggestGoTranscode($output);
|
$this->suggestGoTranscode($output);
|
||||||
|
|
||||||
return $this->suggestDisable($output);
|
return $this->suggestDisable($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
$goTranscodePath = realpath(__DIR__."/../../exiftool-bin/go-transcode-{$arch}-{$libc}");
|
$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')) {
|
if (!$goTranscode || false === strpos($goTranscode, 'Available Commands')) {
|
||||||
$output->writeln('<error>go-transcode could not be run</error>');
|
$output->writeln('<error>go-transcode could not be run</error>');
|
||||||
$this->suggestGoTranscode($output);
|
$this->suggestGoTranscode($output);
|
||||||
|
|
||||||
return $this->suggestDisable($output);
|
return $this->suggestDisable($output);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,10 +124,11 @@ class VideoSetup extends Command
|
||||||
if ('n' === trim($line)) {
|
if ('n' === trim($line)) {
|
||||||
$this->config->setSystemValue('memories.no_transcode', true);
|
$this->config->setSystemValue('memories.no_transcode', true);
|
||||||
$output->writeln('<error>Transcoding and HLS are now disabled</error>');
|
$output->writeln('<error>Transcoding and HLS are now disabled</error>');
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
$tConfig = realpath(__DIR__."/../../transcoder.yaml");
|
$tConfig = realpath(__DIR__.'/../../transcoder.yaml');
|
||||||
|
|
||||||
$this->config->setSystemValue('memories.transcoder', $goTranscodePath);
|
$this->config->setSystemValue('memories.transcoder', $goTranscodePath);
|
||||||
$this->config->setSystemValue('memories.transcoder_config', $tConfig);
|
$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`');
|
$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('Without transcoding, video playback may be slow and limited');
|
||||||
$output->writeln('Do you want to disable transcoding and HLS streaming? [y/N]');
|
$output->writeln('Do you want to disable transcoding and HLS streaming? [y/N]');
|
||||||
$handle = fopen('php://stdin', 'r');
|
$handle = fopen('php://stdin', 'r');
|
||||||
|
|
|
@ -91,6 +91,9 @@ class PageController extends Controller
|
||||||
// App version
|
// App version
|
||||||
$this->initialState->provideInitialState('version', $this->appManager->getAppInfo('memories')['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 = new ContentSecurityPolicy();
|
||||||
$policy->addAllowedWorkerSrcDomain("'self'");
|
$policy->addAllowedWorkerSrcDomain("'self'");
|
||||||
$policy->addAllowedScriptDomain("'self'");
|
$policy->addAllowedScriptDomain("'self'");
|
||||||
|
|
|
@ -105,10 +105,22 @@ class PublicController extends AuthPublicShareController
|
||||||
// App version
|
// App version
|
||||||
$this->initialState->provideInitialState('version', $this->appManager->getAppInfo('memories')['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 = new ContentSecurityPolicy();
|
||||||
$policy->addAllowedWorkerSrcDomain("'self'");
|
$policy->addAllowedWorkerSrcDomain("'self'");
|
||||||
$policy->addAllowedScriptDomain("'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 = new TemplateResponse($this->appName, 'main');
|
||||||
$response->setContentSecurityPolicy($policy);
|
$response->setContentSecurityPolicy($policy);
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ class VideoController extends ApiBase
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure not running in read-only mode
|
// 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);
|
return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -92,8 +92,8 @@ class VideoController extends ApiBase
|
||||||
// Check if already running
|
// Check if already running
|
||||||
exec('ps a | grep go-transcode | grep -v grep', $procs);
|
exec('ps a | grep go-transcode | grep -v grep', $procs);
|
||||||
if (0 === \count($procs)) {
|
if (0 === \count($procs)) {
|
||||||
shell_exec("mkdir -p $tmpDir/transcoder"); // php func has some weird problems
|
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("nohup {$transcoder} serve --config {$tConfig} > {$tmpDir}/transcoder/run.log 2>&1 & > /dev/null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// wait for 2s and try again
|
// wait for 2s and try again
|
||||||
|
@ -115,7 +115,8 @@ class VideoController extends ApiBase
|
||||||
return $response;
|
return $response;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getUpstream($path, $profile) {
|
private function getUpstream($path, $profile)
|
||||||
|
{
|
||||||
$ch = curl_init("http://localhost:47788/vod/{$path}/{$profile}");
|
$ch = curl_init("http://localhost:47788/vod/{$path}/{$profile}");
|
||||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||||
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
|
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);
|
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||||
$returnCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
$returnCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||||
curl_close($ch);
|
curl_close($ch);
|
||||||
|
|
||||||
return [$data, $contentType, $returnCode];
|
return [$data, $contentType, $returnCode];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,18 @@
|
||||||
import PhotoSwipe from "photoswipe";
|
import PhotoSwipe from "photoswipe";
|
||||||
import { generateUrl } from "@nextcloud/router";
|
import { generateUrl } from "@nextcloud/router";
|
||||||
|
import { loadState } from "@nextcloud/initial-state";
|
||||||
|
|
||||||
import videojs from "video.js";
|
import videojs from "video.js";
|
||||||
import "video.js/dist/video-js.min.css";
|
import "video.js/dist/video-js.min.css";
|
||||||
import "videojs-contrib-quality-levels";
|
import "videojs-contrib-quality-levels";
|
||||||
import "videojs-hls-quality-selector";
|
import "videojs-hls-quality-selector";
|
||||||
|
|
||||||
|
const config_noTranscode = loadState(
|
||||||
|
"memories",
|
||||||
|
"notranscode",
|
||||||
|
<string>"UNSET"
|
||||||
|
) as boolean | string;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if slide has video content
|
* Check if slide has video content
|
||||||
*
|
*
|
||||||
|
@ -71,10 +78,11 @@ class VideoContentSetup {
|
||||||
// do not append video on nearby slides
|
// do not append video on nearby slides
|
||||||
pswp.on("appendHeavy", (e) => {
|
pswp.on("appendHeavy", (e) => {
|
||||||
if (isVideoContent(e.slide)) {
|
if (isVideoContent(e.slide)) {
|
||||||
|
const content = <any>e.slide.content;
|
||||||
|
|
||||||
if (!e.slide.isActive) {
|
if (!e.slide.isActive) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
} else {
|
} else if (content.videoElement) {
|
||||||
const content = <any>e.slide.content;
|
|
||||||
const fileid = content.data.photo.fileid;
|
const fileid = content.data.photo.fileid;
|
||||||
|
|
||||||
// Create hls sources if enabled
|
// Create hls sources if enabled
|
||||||
|
@ -82,10 +90,13 @@ class VideoContentSetup {
|
||||||
const baseUrl = generateUrl(
|
const baseUrl = generateUrl(
|
||||||
`/apps/memories/api/video/transcode/${fileid}`
|
`/apps/memories/api/video/transcode/${fileid}`
|
||||||
);
|
);
|
||||||
hlsSources.push({
|
|
||||||
src: `${baseUrl}/index.m3u8`,
|
if (!config_noTranscode) {
|
||||||
type: "application/x-mpegURL",
|
hlsSources.push({
|
||||||
});
|
src: `${baseUrl}/index.m3u8`,
|
||||||
|
type: "application/x-mpegURL",
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const overrideNative = !videojs.browser.IS_SAFARI;
|
const overrideNative = !videojs.browser.IS_SAFARI;
|
||||||
content.videojs = videojs(content.videoElement, {
|
content.videojs = videojs(content.videoElement, {
|
||||||
|
@ -246,6 +257,18 @@ class VideoContentSetup {
|
||||||
return;
|
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.state = "loading";
|
||||||
content.type = "video"; // TODO: move this to pswp core?
|
content.type = "video"; // TODO: move this to pswp core?
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue