mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 01:39:24 +02:00
Improve FFMPEG external
This commit is contained in:
parent
2879e60bf4
commit
48b97ad126
7 changed files with 373 additions and 103 deletions
|
@ -346,7 +346,7 @@ abstract class ObjectYPT implements ObjectInterface
|
|||
}
|
||||
} elseif (strtolower($value) == 'timezone') {
|
||||
if (empty($this->$value)) {
|
||||
$this->$value = date_default_timezone_get();
|
||||
eval('$this->' . $value . ' = date_default_timezone_get();');
|
||||
}
|
||||
$formats .= 's';
|
||||
$values[] = $this->$value;
|
||||
|
@ -384,20 +384,22 @@ abstract class ObjectYPT implements ObjectInterface
|
|||
}
|
||||
} elseif (is_string($value) && strtolower($value) == 'timezone') {
|
||||
if (empty($this->$value)) {
|
||||
$this->$value = date_default_timezone_get();
|
||||
eval('$this->' . $value . ' = date_default_timezone_get();');
|
||||
|
||||
}
|
||||
$formats .= 's';
|
||||
$values[] = $this->$value;
|
||||
$fields[] = " ? ";
|
||||
} elseif (strtolower($value) == 'created_php_time') {
|
||||
if (empty($this->$value)) {
|
||||
$this->$value = time();
|
||||
eval('$this->' . $value . ' = time();');
|
||||
|
||||
}
|
||||
$formats .= 'i';
|
||||
$values[] = $this->$value;
|
||||
$fields[] = " ? ";
|
||||
} elseif (strtolower($value) == 'modified_php_time') {
|
||||
$this->$value = time();
|
||||
eval('$this->' . $value . ' = time();');
|
||||
$formats .= 'i';
|
||||
$values[] = $this->$value;
|
||||
$fields[] = " ? ";
|
||||
|
|
|
@ -57,11 +57,11 @@ function convertVideoToMP3FileIfNotExists($videos_id, $forceTry = 0)
|
|||
$mp3HLSFile = "{$paths['path']}index.mp3";
|
||||
$mp3File = "{$paths['path']}{$video['filename']}.mp3";
|
||||
|
||||
if($forceTry){
|
||||
if(file_exists($mp3HLSFile)){
|
||||
if ($forceTry) {
|
||||
if (file_exists($mp3HLSFile)) {
|
||||
unlink($mp3HLSFile);
|
||||
}
|
||||
if(file_exists($mp3File)){
|
||||
if (file_exists($mp3File)) {
|
||||
unlink($mp3File);
|
||||
}
|
||||
}
|
||||
|
@ -245,6 +245,77 @@ function m3u8ToMP4($input, $makeItPermanent = false, $force = false)
|
|||
}
|
||||
|
||||
|
||||
function m3u8ToMP4RemoteFFMpeg($input, $callback)
|
||||
{
|
||||
$videosDir = getVideosDir();
|
||||
$outputfilename = str_replace($videosDir, "", $input);
|
||||
$parts = explode("/", $outputfilename);
|
||||
$resolution = Video::getResolutionFromFilename($input);
|
||||
$video_filename = $parts[count($parts) - 2];
|
||||
|
||||
$outputfilename = "index.mp4";
|
||||
$outputpathDir = "{$videosDir}{$video_filename}/";
|
||||
|
||||
make_path($outputpathDir);
|
||||
$outputpath = "{$outputpathDir}{$outputfilename}";
|
||||
$msg = '';
|
||||
$error = true;
|
||||
|
||||
if (empty($outputfilename)) {
|
||||
$msg = "downloadHLS: empty outputfilename {$outputfilename}";
|
||||
_error_log($msg);
|
||||
return ['error' => $error, 'msg' => $msg];
|
||||
}
|
||||
|
||||
_error_log("downloadHLS: m3u8ToMP4($input)");
|
||||
$ism3u8 = preg_match('/.m3u8$/i', $input);
|
||||
|
||||
if (!preg_match('/^http/i', $input) && (filesize($input) <= 10 || $ism3u8)) { // dummy file
|
||||
$filepath = pathToRemoteURL($input, true, true);
|
||||
if ($ism3u8 && !preg_match('/.m3u8$/i', $filepath)) {
|
||||
$filepath = addLastSlash($filepath) . 'index.m3u8';
|
||||
}
|
||||
|
||||
$token = getToken(60);
|
||||
$filepath = addQueryStringParameter($filepath, 'globalToken', $token);
|
||||
} else {
|
||||
$filepath = escapeshellcmdURL($input);
|
||||
}
|
||||
|
||||
if (is_dir($filepath)) {
|
||||
$filepath = addLastSlash($filepath) . 'index.m3u8';
|
||||
}
|
||||
|
||||
if (!file_exists($outputpath)) {
|
||||
$return = convertVideoFileWithFFMPEGAsyncOrRemote($filepath, $outputpath, 'm3u8ToMP4RemoteFFMpeg_'.md5($input), $callback);
|
||||
|
||||
if (empty($return)) {
|
||||
$msg3 = "downloadHLS: ERROR 2 ";
|
||||
$finalMsg = $msg . PHP_EOL . $msg3;
|
||||
_error_log($msg3);
|
||||
return ['error' => $error,
|
||||
'msg' => $finalMsg,
|
||||
'path' => $outputpath,
|
||||
'filename' => $outputfilename
|
||||
];
|
||||
} else {
|
||||
return [
|
||||
'error' => false,
|
||||
'msg' => '',
|
||||
'return' => $return,
|
||||
'path' => $outputpath,
|
||||
'filename' => $outputfilename
|
||||
];
|
||||
}
|
||||
} else {
|
||||
$msg = "downloadHLS: outputpath already exists ({$outputpath})";
|
||||
_error_log($msg);
|
||||
}
|
||||
|
||||
$error = false;
|
||||
return ['error' => $error, 'msg' => $msg, 'path' => $outputpath, 'filename' => $outputfilename];
|
||||
}
|
||||
|
||||
function getConvertVideoFileWithFFMPEGProgressFilename($toFileLocation)
|
||||
{
|
||||
$progressFile = $toFileLocation . '.log';
|
||||
|
@ -371,12 +442,10 @@ function convertVideoFileWithFFMPEGIsLockedInfo($toFileLocation)
|
|||
);
|
||||
}
|
||||
|
||||
function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile = '', $try = 0)
|
||||
function buildFFMPEGCommand($fromFileLocation, $toFileLocation, $try = 0, $cpuUsagePercentage = 80)
|
||||
{
|
||||
global $global, $advancedCustom;
|
||||
if (empty($advancedCustom)) {
|
||||
$advancedCustom = AVideoPlugin::getDataObject('CustomizeAdvanced');
|
||||
}
|
||||
global $advancedCustom;
|
||||
|
||||
// Dynamically get the number of CPU cores
|
||||
$threads = 1; // Default to 1 thread
|
||||
if (function_exists('shell_exec')) {
|
||||
|
@ -384,34 +453,21 @@ function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile
|
|||
if (!$cpuCores) {
|
||||
$cpuCores = (int)shell_exec('sysctl -n hw.ncpu 2>/dev/null'); // macOS
|
||||
}
|
||||
if ($cpuCores > 1) {
|
||||
$threads = $cpuCores - 1;
|
||||
|
||||
if ($cpuCores > 0) {
|
||||
// Calculate the number of threads based on the percentage
|
||||
$threads = max(1, (int)($cpuCores * ($cpuUsagePercentage / 100)));
|
||||
} else {
|
||||
_error_log("convertVideoFileWithFFMPEG: Unable to detect CPU cores. Defaulting to 1 thread.");
|
||||
_error_log("buildFFMPEGCommand: Unable to detect CPU cores. Defaulting to 1 thread.");
|
||||
}
|
||||
} else {
|
||||
_error_log("convertVideoFileWithFFMPEG: shell_exec is disabled. Defaulting to 1 thread.");
|
||||
}
|
||||
|
||||
$f = convertVideoFileWithFFMPEGIsLockedInfo($toFileLocation);
|
||||
$localFileLock = $f['localFileLock'];
|
||||
if ($f['isOld']) {
|
||||
_error_log("convertVideoFileWithFFMPEG: age: {$f['ageInSeconds']} too long without change, unlock it " . $fromFileLocation . ' ' . json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
|
||||
@unlink($localFileLock);
|
||||
} elseif ($f['file_exists']) {
|
||||
_error_log("convertVideoFileWithFFMPEG: age: {$f['ageInSeconds']} download from CDN There is a process running for {$fromFileLocation} localFileLock=$localFileLock log=$logFile");
|
||||
return false;
|
||||
} else {
|
||||
_error_log("convertVideoFileWithFFMPEG: creating file: localFileLock: {$localFileLock} toFileLocation: {$toFileLocation}");
|
||||
}
|
||||
make_path($toFileLocation);
|
||||
file_put_contents($localFileLock, time());
|
||||
$fromFileLocationEscaped = escapeshellarg($fromFileLocation);
|
||||
$toFileLocationEscaped = escapeshellarg($toFileLocation);
|
||||
|
||||
$format = pathinfo($toFileLocation, PATHINFO_EXTENSION);
|
||||
|
||||
if ($format == 'mp3') {
|
||||
// Generate the FFmpeg command based on format and try count
|
||||
if ($format === 'mp3') {
|
||||
switch ($try) {
|
||||
case 0:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -i {$fromFileLocationEscaped} -c:a libmp3lame -b:a 128k -ar 44100 -ac 2 {$toFileLocationEscaped}";
|
||||
|
@ -419,24 +475,8 @@ function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile
|
|||
case 1:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -i {$fromFileLocationEscaped} -c:a libmp3lame -b:a 192k -ar 48000 -ac 2 {$toFileLocationEscaped}";
|
||||
break;
|
||||
case 2:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -probesize 50M -analyzeduration 100M -i {$fromFileLocationEscaped} -c:a libmp3lame -b:a 128k -ar 44100 -ac 2 {$toFileLocationEscaped}";
|
||||
break;
|
||||
case 3:
|
||||
$uniqueID = uniqid('temp_audio_', true);
|
||||
$tempAudioFile = escapeshellarg("/tmp/{$uniqueID}.aac");
|
||||
$command = get_ffmpeg() . " -threads {$threads} -i {$fromFileLocationEscaped} -vn -acodec copy {$tempAudioFile}";
|
||||
exec($command, $output, $return);
|
||||
|
||||
if ($return === 0) {
|
||||
$command = get_ffmpeg() . " -threads {$threads} -i {$tempAudioFile} -c:a libmp3lame -b:a 128k -ar 44100 -ac 2 {$toFileLocationEscaped}";
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
switch ($try) {
|
||||
|
@ -446,55 +486,42 @@ function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile
|
|||
case 1:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -i {$fromFileLocationEscaped} -c copy {$toFileLocationEscaped}";
|
||||
break;
|
||||
case 2:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -allowed_extensions ALL -y -i {$fromFileLocationEscaped} -c:v copy -c:a copy -bsf:a aac_adtstoasc -strict -2 {$toFileLocationEscaped}";
|
||||
break;
|
||||
case 3:
|
||||
$command = get_ffmpeg() . " -threads {$threads} -y -i {$fromFileLocationEscaped} -c:v copy -c:a copy -bsf:a aac_adtstoasc -strict -2 {$toFileLocationEscaped}";
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($logFile)) {
|
||||
$progressFile = getConvertVideoFileWithFFMPEGProgressFilename($toFileLocation);
|
||||
} else {
|
||||
$progressFile = $logFile;
|
||||
}
|
||||
if (empty($progressFile)) {
|
||||
$progressFile = "{$toFileLocation}.log";
|
||||
return $command;
|
||||
}
|
||||
|
||||
function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile = '', $try = 0)
|
||||
{
|
||||
$command = buildFFMPEGCommand($fromFileLocation, $toFileLocation, $try);
|
||||
|
||||
if (!$command) {
|
||||
_error_log("convertVideoFileWithFFMPEG: Failed to build command");
|
||||
return false;
|
||||
}
|
||||
|
||||
$command = removeUserAgentIfNotURL($command);
|
||||
|
||||
if (!isCommandLineInterface()) {
|
||||
$command .= " > {$progressFile} 2>&1";
|
||||
}
|
||||
|
||||
_session_write_close();
|
||||
_mysql_close();
|
||||
_error_log("convertVideoFileWithFFMPEG try[{$try}]: " . $command . ' ' . json_encode(debug_backtrace()));
|
||||
|
||||
if (isCommandLineInterface()) {
|
||||
echo "convertVideoFileWithFFMPEG {$command} ";
|
||||
}
|
||||
$command .= " > {$logFile} 2>&1";
|
||||
exec($command, $output, $return);
|
||||
|
||||
if (!empty($tempAudioFile)) {
|
||||
unlink($tempAudioFile);
|
||||
_error_log("convertVideoFileWithFFMPEG: Command executed with return code {$return}");
|
||||
return ['return' => $return, 'output' => $output, 'command' => $command];
|
||||
}
|
||||
|
||||
function convertVideoFileWithFFMPEGAsyncOrRemote($fromFileLocation, $toFileLocation, $keyword, $callback = '')
|
||||
{
|
||||
$command = buildFFMPEGCommand($fromFileLocation, $toFileLocation, 0);
|
||||
|
||||
if (!$command) {
|
||||
_error_log("convertVideoFileWithFFMPEGAsyncOrRemote: Failed to build command");
|
||||
return false;
|
||||
}
|
||||
|
||||
$global['lastFFMPEG'] = array($command, $output, $return);
|
||||
|
||||
_session_start();
|
||||
_mysql_connect();
|
||||
_error_log("convertVideoFileWithFFMPEG try[{$try}] output: " . json_encode($output));
|
||||
|
||||
unlink($localFileLock);
|
||||
|
||||
return ['return' => $return, 'output' => $output, 'command' => $command, 'fromFileLocation' => $fromFileLocation, 'toFileLocation' => $toFileLocation, 'progressFile' => $progressFile];
|
||||
$result = execFFMPEGAsyncOrRemote($command, $keyword, $callback);
|
||||
_error_log("convertVideoFileWithFFMPEGAsyncOrRemote: Command executed remotely or asynchronously");
|
||||
return $result;
|
||||
}
|
||||
|
||||
|
||||
|
@ -568,7 +595,7 @@ function cutVideoWithFFmpeg($inputFile, $startTimeInSeconds, $endTimeInSeconds,
|
|||
}
|
||||
|
||||
|
||||
function buildFFMPEGRemoteURL($actionParams)
|
||||
function buildFFMPEGRemoteURL($actionParams, $callback='')
|
||||
{
|
||||
$obj = AVideoPlugin::getDataObjectIfEnabled('API');
|
||||
if (empty($obj) || empty($obj->standAloneFFMPEG)) {
|
||||
|
@ -576,15 +603,17 @@ function buildFFMPEGRemoteURL($actionParams)
|
|||
}
|
||||
$url = "{$obj->standAloneFFMPEG}";
|
||||
$actionParams['time'] = time();
|
||||
$actionParams['notifyCode'] = encryptString(time());
|
||||
$actionParams['callback'] = encryptString($callback);
|
||||
$encryptedParams = encryptString(json_encode($actionParams));
|
||||
$url = addQueryStringParameter($url, 'APISecret', $obj->APISecret);
|
||||
$url = addQueryStringParameter($url, 'codeToExecEncrypted', $encryptedParams);
|
||||
return $url;
|
||||
}
|
||||
|
||||
function execFFMPEGAsyncOrRemote($command, $keyword)
|
||||
function execFFMPEGAsyncOrRemote($command, $keyword, $callback)
|
||||
{
|
||||
$url = buildFFMPEGRemoteURL(['ffmpegCommand' => $command, 'keyword' => $keyword]);
|
||||
$url = buildFFMPEGRemoteURL(['ffmpegCommand' => $command, 'keyword' => $keyword], $callback);
|
||||
if ($url) {
|
||||
_error_log("execFFMPEGAsyncOrRemote: URL $command");
|
||||
_error_log("execFFMPEGAsyncOrRemote: URL $url");
|
||||
|
@ -600,7 +629,7 @@ function getFFMPEGRemoteLog($keyword)
|
|||
$url = buildFFMPEGRemoteURL(['log' => 1, 'keyword' => $keyword]);
|
||||
//var_dump($url);
|
||||
if ($url) {
|
||||
_error_log("getFFMPEGRemoteLog: URL $url ".json_encode(debug_backtrace()));
|
||||
_error_log("getFFMPEGRemoteLog: URL $url " . json_encode(debug_backtrace()));
|
||||
return json_decode(url_get_contents($url));
|
||||
} else {
|
||||
return false;
|
||||
|
@ -629,3 +658,24 @@ function testFFMPEGRemote()
|
|||
}
|
||||
}
|
||||
|
||||
function deleteFolderFFMPEGRemote($videoFilename)
|
||||
{
|
||||
$url = buildFFMPEGRemoteURL(['deleteFolder' => $videoFilename]);
|
||||
if ($url) {
|
||||
_error_log("deleteFolderFFMPEGRemote: URL $url");
|
||||
return json_decode(url_get_contents($url));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function deleteFileFFMPEGRemote($filePath)
|
||||
{
|
||||
$url = buildFFMPEGRemoteURL(['deleteFile' => $filePath]);
|
||||
if ($url) {
|
||||
_error_log("deleteFileFFMPEGRemote: URL $url");
|
||||
return json_decode(url_get_contents($url));
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,7 +46,7 @@ if($_SERVER["HTTP_HOST"] === 'localhost' || $_SERVER["HTTP_HOST"] === '127.0.0.1
|
|||
if (!empty($global['stopBotsList']) && is_array($global['stopBotsList'])) {
|
||||
foreach ($global['stopBotsList'] as $value) {
|
||||
if (empty($_SERVER['HTTP_USER_AGENT'])) {
|
||||
continue;
|
||||
break;
|
||||
}
|
||||
if (stripos($_SERVER['HTTP_USER_AGENT'], $value) !== false) {
|
||||
if (!empty($global['stopBotsWhiteList']) && is_array($global['stopBotsWhiteList'])) {
|
||||
|
|
|
@ -2373,8 +2373,8 @@ if (!class_exists('Video')) {
|
|||
return false;
|
||||
}
|
||||
TimeLogStart("Video::updateFilesize {$videos_id}");
|
||||
ini_set('max_execution_time', 300); // 5
|
||||
set_time_limit(300);
|
||||
//ini_set('max_execution_time', 300); // 5
|
||||
//set_time_limit(300);
|
||||
$video = new Video("", "", $videos_id, true);
|
||||
$_type = $video->getType();
|
||||
if ($_type !== 'video' && $_type !== 'audio') {
|
||||
|
|
97
plugin/API/notify.ffmpeg.json.php
Normal file
97
plugin/API/notify.ffmpeg.json.php
Normal file
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
$configFile = __DIR__ . '/../../videos/configuration.php';
|
||||
require_once $configFile;
|
||||
header('Content-Type: application/json');
|
||||
|
||||
if (empty($_REQUEST['notifyCode'])) {
|
||||
forbiddenPage('Empty notifyCode');
|
||||
}
|
||||
|
||||
$notifyCode = decryptString($_REQUEST['notifyCode']);
|
||||
if (empty($notifyCode)) {
|
||||
forbiddenPage('Invalid notifyCode');
|
||||
}
|
||||
|
||||
if (empty($_REQUEST['notify'])) {
|
||||
forbiddenPage('Empty notify');
|
||||
}
|
||||
|
||||
$notify = json_decode($_REQUEST['notify'], true);
|
||||
if (empty($notify)) {
|
||||
forbiddenPage('Invalid notify');
|
||||
}
|
||||
|
||||
_error_log("notify.ffmpeg start ".json_encode($_REQUEST));
|
||||
|
||||
if (!empty($notify['avideoPath'])) {
|
||||
_error_log("notify.ffmpeg: Received notification for path: {$notify['avideoPath']}");
|
||||
|
||||
$format = pathinfo($notify['avideoPath'], PATHINFO_EXTENSION);
|
||||
_error_log("notify.ffmpeg: File format detected: $format");
|
||||
|
||||
if ($format == 'mp4' || $format == 'mp3') {
|
||||
_error_log("notify.ffmpeg: Format is valid for processing: $format");
|
||||
|
||||
$obj = AVideoPlugin::getDataObjectIfEnabled('API');
|
||||
|
||||
$localPath = "{$global['systemRootPath']}{$notify['avideoRelativePath']}";
|
||||
if(file_exists($localPath)){
|
||||
_error_log("notify.ffmpeg: this is a local call for ffmpeg, no download and not delete needed");
|
||||
}else if (!empty($obj) && !empty($obj->standAloneFFMPEG)) {
|
||||
_error_log("notify.ffmpeg: API Plugin and standAloneFFMPEG URL detected");
|
||||
|
||||
$url = str_replace('plugin/API/standAlone/ffmpeg.json.php', '', $obj->standAloneFFMPEG);
|
||||
$url = "{$url}{$notify['avideoRelativePath']}";
|
||||
_error_log("notify.ffmpeg: Constructed URL: $url");
|
||||
|
||||
$content = url_get_contents($url);
|
||||
if ($content === false) {
|
||||
_error_log("notify.ffmpeg: Failed to fetch content from URL: $url");
|
||||
} else {
|
||||
_error_log("notify.ffmpeg: Successfully fetched content. Content length: " . strlen($content));
|
||||
}
|
||||
if(!empty($content)){
|
||||
$filePath = "{$global['systemRootPath']}{$notify['avideoRelativePath']}";
|
||||
$bytes = file_put_contents($filePath, $content);
|
||||
if ($bytes === false) {
|
||||
_error_log("notify.ffmpeg: Failed to save content to file: $filePath");
|
||||
} else {
|
||||
_error_log("notify.ffmpeg: Successfully saved file. Bytes written: $bytes");
|
||||
}
|
||||
}else{
|
||||
_error_log("notify.ffmpeg: error, empty content");
|
||||
}
|
||||
|
||||
_error_log("notify.ffmpeg: Attempting to delete remote folder for: {$notify['avideoFilename']}");
|
||||
$deleteStatus = deleteFolderFFMPEGRemote($notify['avideoFilename']);
|
||||
_error_log("notify.ffmpeg: Remote folder delete status: " . json_encode($deleteStatus));
|
||||
} else {
|
||||
_error_log("notify.ffmpeg: API Plugin or standAloneFFMPEG URL is not configured");
|
||||
}
|
||||
} else {
|
||||
_error_log("notify.ffmpeg: Unsupported file format: $format");
|
||||
}
|
||||
} else {
|
||||
_error_log("notify.ffmpeg: No avideoPath provided in the notification");
|
||||
}
|
||||
|
||||
// Collect and print JSON response with relevant information
|
||||
$response = [
|
||||
'error' => empty($bytes),
|
||||
'avideoPath' => $notify['avideoPath'] ?? null,
|
||||
'format' => $format ?? null,
|
||||
'standAloneFFMPEG' => $obj->standAloneFFMPEG ?? null,
|
||||
'constructedURL' => $url ?? null,
|
||||
'contentLength' => isset($content) ? strlen($content) : null,
|
||||
'bytesWritten' => $bytes ?? null,
|
||||
'filePath' => $filePath ?? null,
|
||||
'deleteStatus' => $deleteStatus ?? null,
|
||||
];
|
||||
|
||||
$callback = decryptString($_REQUEST['callback']);
|
||||
if(!empty($callback)){
|
||||
_error_log("notify.ffmpeg: eval callback $callback");
|
||||
eval($callback);
|
||||
}
|
||||
|
||||
echo json_encode($response, JSON_PRETTY_PRINT);
|
|
@ -173,7 +173,8 @@ function sanitizeFFmpegCommand($command)
|
|||
return '';
|
||||
}
|
||||
|
||||
function addKeywordToFFmpegCommand(string $command, string $keyword): string {
|
||||
function addKeywordToFFmpegCommand(string $command, string $keyword): string
|
||||
{
|
||||
// Escape the keyword to avoid shell injection
|
||||
$escapedKeyword = escapeshellarg($keyword);
|
||||
|
||||
|
@ -195,6 +196,21 @@ function addKeywordToFFmpegCommand(string $command, string $keyword): string {
|
|||
return implode(' ', $commandParts);
|
||||
}
|
||||
|
||||
$notify = getInput('notify', '');
|
||||
$notifyCode = getInput('notifyCode', '');
|
||||
$callback = getInput('callback', '');
|
||||
if (!empty($notify) && !empty($notifyCode)) {
|
||||
$url = "{$global['webSiteRootURL']}plugin/API/notify.ffmpeg.json.php?notify=" . urlencode($notify) . "¬ifyCode={$notifyCode}&callback={$callback}";
|
||||
$content = file_get_contents($url);
|
||||
_error_log("ffmpeg.json Notify URL: $url $content");
|
||||
|
||||
if(!empty($output['avideoPath'])){
|
||||
_error_log("{$output['avideoPath']} created: ".humanFileSize(filesize($output['avideoPath'])));
|
||||
}
|
||||
$json = json_decode($content);
|
||||
die($content);
|
||||
}
|
||||
|
||||
_error_log("Fetching inputs...");
|
||||
$codeToExecEncrypted = getInput('codeToExecEncrypted', '');
|
||||
$codeToExec = _decryptString($codeToExecEncrypted);
|
||||
|
@ -214,7 +230,31 @@ if (empty($codeToExec->keyword)) {
|
|||
$keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword);
|
||||
}
|
||||
|
||||
_error_log("Code to Execute: " . json_encode($codeToExec));
|
||||
$output = array();
|
||||
$output['avideoPath'] = '';
|
||||
$output['avideoRelativePath'] = '';
|
||||
$output['avideoFilename'] = '';
|
||||
$output['videoBasename'] = '';
|
||||
$output['avideoExstension'] = '';
|
||||
|
||||
preg_match('/ [\'"]?(\/[0-9a-z_\/-]+\/videos\/([0-9a-z_\/-]+)\/([0-9a-z_-]+\.(mp4|mp3)))[\'"]?/i', $ffmpegCommand, $matches);
|
||||
|
||||
if (!empty($matches)) {
|
||||
$output = array();
|
||||
$output['avideoPath'] = $matches[1];
|
||||
$output['avideoRelativePath'] = str_replace($global['systemRootPath'], '', $output['avideoPath']);
|
||||
$output['avideoFilename'] = $matches[2];
|
||||
$output['videoBasename'] = $matches[3];
|
||||
$output['avideoExstension'] = $matches[4];
|
||||
|
||||
$directory = dirname($output['avideoPath']);
|
||||
|
||||
make_path($directory);
|
||||
} else {
|
||||
_error_log("matches not found: {$ffmpegCommand}");
|
||||
}
|
||||
|
||||
_error_log("Code to Execute: " . json_encode(array($output, $codeToExec)));
|
||||
_error_log("Sanitized FFMPEG Command: $ffmpegCommand");
|
||||
_error_log("Keyword: $keyword");
|
||||
|
||||
|
@ -273,18 +313,74 @@ if (!empty($codeToExec->test)) {
|
|||
}
|
||||
|
||||
echo json_encode([
|
||||
'error' =>$processAfterKillCount !== 0, // Indicate if killing processes was successful
|
||||
'error' => $processAfterKillCount !== 0, // Indicate if killing processes was successful
|
||||
'msg' => $processAfterKillCount !== 0 ? 'Processes killed successfully.' : 'Failed to kill processes.',
|
||||
'logFile' => $logFile,
|
||||
'kill' => $killResult, // Result of pkill command
|
||||
'keyword' => $keyword,
|
||||
'unlink' => $unlinkSuccess,
|
||||
'processToKillCount' => $processToKillCount,
|
||||
'processToKillCount' => $processToKillCount,
|
||||
'processAfterKillCount' => $processAfterKillCount, // Number of processes killed
|
||||
'countCommand' => $countCommand,
|
||||
'killCommand' => $killCommand,
|
||||
'output' => $output,
|
||||
'killStatus' => $killStatus,
|
||||
'killStatus' => $killStatus,
|
||||
]);
|
||||
exit;
|
||||
} else if (!empty($codeToExec->deleteFolder)) {
|
||||
if(empty($isStandAlone)){
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'This is not a stand alone, do not delete folder',
|
||||
'deleteFolder' => $codeToExec->deleteFolder,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
_error_log("deleteFolder triggered");
|
||||
|
||||
$folderName = preg_replace('/[^a-z0-9_-]/i', '', $codeToExec->deleteFolder);
|
||||
$folderPath = "{$global['systemRootPath']}videos/{$folderName}";
|
||||
$rrmdir = false;
|
||||
if (!empty($folderName) && is_dir($folderPath)) {
|
||||
$rrmdir = rrmdir($folderPath);
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'error' => !is_dir($folderPath),
|
||||
'msg' => '',
|
||||
'folderPath' => $folderPath,
|
||||
'folderName' => $folderName,
|
||||
'rrmdir' => $rrmdir,
|
||||
]);
|
||||
exit;
|
||||
} else if (!empty($codeToExec->deleteFile)) {
|
||||
if(empty($isStandAlone)){
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => 'This is not a stand alone, do not delete file',
|
||||
'deleteFile' => $codeToExec->deleteFile,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
_error_log("deleteFiler triggered");
|
||||
|
||||
$filePath = str_replace('../', '', $codeToExec->deleteFile);
|
||||
$filePath = preg_replace('/[^a-z0-9_\/-]/i', '', $codeToExec->deleteFile);
|
||||
if (!empty($filePath) && file_exists($filePath)) {
|
||||
$unlink = unlink($folderPath);
|
||||
$folderPath = dirname($filePath); // Get the folder path
|
||||
|
||||
// Check if the folder is empty
|
||||
if (is_dir($folderPath) && count(scandir($folderPath)) === 2) { // 2 because '.' and '..' are always present
|
||||
rmdir($folderPath); // Remove the folder
|
||||
}
|
||||
}
|
||||
|
||||
echo json_encode([
|
||||
'error' => !file_exists($filePath),
|
||||
'msg' => '',
|
||||
'filePath' => $filePath,
|
||||
'unlink' => $unlink,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
@ -301,6 +397,18 @@ if (empty($ffmpegCommand)) {
|
|||
|
||||
// Kill processes associated with the keyword
|
||||
if (!empty($keyword)) {
|
||||
$countCommand = "pgrep -f 'ffmpeg.*$keyword' | wc -l";
|
||||
$processCount = intval(exec($countCommand));
|
||||
if($processCount){
|
||||
$msg = "There is something running [$processCount] with keyword [$keyword] already";
|
||||
_error_log($msg);
|
||||
echo json_encode([
|
||||
'error' => true,
|
||||
'msg' => $msg,
|
||||
'codeToExec' => $codeToExec,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
// if I kill it it will infinite loop the VideoPlaylistScheduler because the on_publish done
|
||||
//_error_log("Killing process with keyword: $keyword");
|
||||
//killProcessFromKeyword($keyword, 60);
|
||||
|
@ -309,10 +417,17 @@ if (!empty($keyword)) {
|
|||
|
||||
$ffmpegCommand = addKeywordToFFmpegCommand($ffmpegCommand, $keyword);
|
||||
|
||||
file_put_contents($logFile, $ffmpegCommand.PHP_EOL.PHP_EOL);
|
||||
|
||||
$ffmpegCommand .= " > {$logFile} 2>&1";
|
||||
_error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand ".json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
|
||||
$ffmpegCommand .= " > {$logFile} ";
|
||||
if (!empty($output['avideoPath'])) {
|
||||
if (file_exists($output['avideoPath'])) {
|
||||
unlink($output['avideoPath']);
|
||||
}
|
||||
$outputJson = escapeshellarg(json_encode($output));
|
||||
$ffmpegCommand .= " && php " . escapeshellarg(__DIR__ . "/ffmpeg.json.php") . " notify={$outputJson} notifyCode={$codeToExec->notifyCode} callback={$codeToExec->callback}";
|
||||
}
|
||||
$ffmpegCommand .= " 2>&1";
|
||||
file_put_contents($logFile, $ffmpegCommand . PHP_EOL . PHP_EOL);
|
||||
_error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand " . json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
|
||||
|
||||
try {
|
||||
$pid = execAsync($ffmpegCommand, $keyword);
|
||||
|
|
|
@ -77,7 +77,13 @@ if(!empty($_REQUEST['cacheDownload'])){
|
|||
_error_log("cacheDownload: $path");
|
||||
}else{
|
||||
$path = Video::getPathToFile($file);
|
||||
//var_dump($path, $file);exit;
|
||||
if(!file_exists($path) && !empty($_GET['folder'])){
|
||||
$folder = preg_replace('/[^a-z0-9_-]/i', '', $_GET['folder']);
|
||||
if(!empty($folder)){
|
||||
$path = "{$global['systemRootPath']}videos/{$folder}/{$file}";
|
||||
}
|
||||
}
|
||||
//var_dump($path, $file, $_GET);exit;
|
||||
}
|
||||
//header('Content-Type: application/json');var_dump(__LINE__, $_SERVER["REQUEST_URI"], $file, $path);exit;
|
||||
//header('Content-Type: application/json');var_dump($advancedCustom->doNotUseXsendFile);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue