Start transcoding server
parent
007a8c3f4f
commit
bae6662e37
|
@ -50,8 +50,14 @@ class VideoSetup extends Command
|
|||
|
||||
protected function execute(InputInterface $input, OutputInterface $output): int
|
||||
{
|
||||
// Check nohup binary
|
||||
$nohup = shell_exec('nohup --version');
|
||||
if (!$nohup || strpos($nohup, 'nohup') === false) {
|
||||
$output->writeln('<error>nohup binary not found. Please install nohup.</error>');
|
||||
return $this->suggestDisable($output);
|
||||
}
|
||||
|
||||
// Get ffmpeg version
|
||||
$output->writeln('Checking for ffmpeg binary');
|
||||
$ffmpeg = shell_exec('ffmpeg -version');
|
||||
if (false === strpos($ffmpeg, 'ffmpeg version')) {
|
||||
$ffmpeg = null;
|
||||
|
@ -61,7 +67,6 @@ class VideoSetup extends Command
|
|||
}
|
||||
|
||||
// Get ffprobe version
|
||||
$output->writeln('Checking for ffprobe binary');
|
||||
$ffprobe = shell_exec('ffprobe -version');
|
||||
if (false === strpos($ffprobe, 'ffprobe version')) {
|
||||
$ffprobe = null;
|
||||
|
@ -102,8 +107,11 @@ class VideoSetup extends Command
|
|||
$output->writeln('go-transcode is installed!');
|
||||
$output->writeln('');
|
||||
$output->writeln('You can use transcoding and HLS streaming');
|
||||
$output->writeln('This is recommended for better performance, but not for very slow systems');
|
||||
$output->writeln('For more details see: https://github.com/pulsejet/memories/wiki/Configuration');
|
||||
$output->writeln('This is recommended for better performance, but has implications if');
|
||||
$output->writeln('you are using external storage or run Nextcloud on a slow system.');
|
||||
$output->writeln('');
|
||||
$output->writeln('Read the following documentation carefully before continuing:');
|
||||
$output->writeln('https://github.com/pulsejet/memories/wiki/Configuration');
|
||||
$output->writeln('');
|
||||
$output->writeln('Do you want to enable transcoding and HLS? [Y/n]');
|
||||
|
||||
|
@ -115,7 +123,10 @@ 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.no_transcode', false);
|
||||
$output->writeln('Transcoding and HLS are now enabled!');
|
||||
|
||||
|
|
|
@ -49,7 +49,7 @@ class VideoController extends ApiBase
|
|||
}
|
||||
|
||||
// Make sure not running in read-only mode
|
||||
if ($this->config->getSystemValue('memories.no_transcode', false)) {
|
||||
if ($this->config->getSystemValue('memories.no_transcode', 'UNSET') !== false) {
|
||||
return new JSONResponse(['message' => 'Transcoding disabled'], Http::STATUS_FORBIDDEN);
|
||||
}
|
||||
|
||||
|
@ -71,15 +71,35 @@ class VideoController extends ApiBase
|
|||
return new JSONResponse(['message' => 'File not found'], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Check if file starts with temp dir
|
||||
$tmpDir = sys_get_temp_dir();
|
||||
if (0 === strpos($path, $tmpDir)) {
|
||||
return new JSONResponse(['message' => 'File is in temp dir!'], Http::STATUS_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Make upstream request
|
||||
$ch = curl_init("http://localhost:9999/vod/{$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);
|
||||
$data = curl_exec($ch);
|
||||
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
$returnCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
[$data, $contentType, $returnCode] = $this->getUpstream($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) {
|
||||
return new JSONResponse(['message' => 'Transcoder not configured'], Http::STATUS_INTERNAL_SERVER_ERROR);
|
||||
}
|
||||
|
||||
// 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");
|
||||
}
|
||||
|
||||
// wait for 2s and try again
|
||||
sleep(2);
|
||||
[$data, $contentType, $returnCode] = $this->getUpstream($path, $profile);
|
||||
}
|
||||
|
||||
// Check data was received
|
||||
if ($returnCode >= 400 || false === $data) {
|
||||
|
@ -94,4 +114,16 @@ class VideoController extends ApiBase
|
|||
|
||||
return $response;
|
||||
}
|
||||
|
||||
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);
|
||||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||||
$data = curl_exec($ch);
|
||||
$contentType = curl_getinfo($ch, CURLINFO_CONTENT_TYPE);
|
||||
$returnCode = (int) curl_getinfo($ch, CURLINFO_HTTP_CODE);
|
||||
curl_close($ch);
|
||||
return [$data, $contentType, $returnCode];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ od=`pwd`
|
|||
|
||||
rm -rf /tmp/memories
|
||||
mkdir -p /tmp/memories
|
||||
cp -R appinfo l10n img js lib templates COPYING README.md exiftest* composer* /tmp/memories
|
||||
cp -R appinfo l10n img js lib templates COPYING README.md transcoder.yaml exiftest* composer* /tmp/memories
|
||||
|
||||
cd /tmp
|
||||
rm -f memories/appinfo/screencap* memories/js/*.map
|
||||
|
|
|
@ -0,0 +1,59 @@
|
|||
# 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
|
Loading…
Reference in New Issue