Start transcoding server

pull/221/head
Varun Patil 2022-11-09 02:26:51 -08:00
parent 007a8c3f4f
commit bae6662e37
4 changed files with 116 additions and 14 deletions

View File

@ -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!');

View File

@ -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];
}
}

View File

@ -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

59
transcoder.yaml 100644
View File

@ -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