diff --git a/plugin/API/standAlone/ffmpeg.json.php b/plugin/API/standAlone/ffmpeg.json.php index 9a1c1e123f..0097db397e 100644 --- a/plugin/API/standAlone/ffmpeg.json.php +++ b/plugin/API/standAlone/ffmpeg.json.php @@ -87,7 +87,6 @@ * * Replace `https://yourSite.com/` with your actual website URL. */ - $global_timeLimit = 300; ini_set("memory_limit", -1); @@ -100,7 +99,10 @@ header('Content-Type: application/json'); require_once __DIR__ . "/../../../objects/functionsStandAlone.php"; +_error_log("Script initiated: FFMPEG command execution script started"); + if (empty($streamerURL)) { + _error_log("Error: streamerURL is not defined"); echo json_encode(['error' => true, 'message' => 'streamerURL not defined']); exit; } @@ -109,6 +111,7 @@ function _decryptString($string) { global $global; $url = "{$global['webSiteRootURL']}plugin/API/get.json.php?APIName=decryptString&string={$string}"; + _error_log("Decrypting string using URL: $url"); $content = file_get_contents($url); $json = json_decode($content); @@ -116,10 +119,11 @@ function _decryptString($string) if (!empty($json) && empty($json->error)) { $json2 = json_decode($json->message); if ($json2->time > strtotime('30 seconds ago')) { + _error_log("String decrypted successfully"); return $json2; } } - return $json2; + _error_log("Failed to decrypt string or invalid time"); return false; } @@ -146,65 +150,59 @@ function getInput($key, $default = '') function sanitizeFFmpegCommand($command) { $allowedPrefixes = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg']; + _error_log("Sanitizing FFMPEG command: $command"); // Remove dangerous characters $command = str_replace('&&', '', $command); $command = str_replace('rtmp://live/', 'rtmp://vlu.me/', $command); $command = str_replace('https://live:8443/', 'https://vlu.me:8443/', $command); - - // Remove existing log file redirection (e.g., '> /path/to/log 2>&1' or '> /path/to/log') $command = preg_replace('/\s*>.*(?:2>&1)?/', '', $command); $command = preg_replace('/[;|`<>]/', '', $command); // Ensure it starts with an allowed prefix foreach ($allowedPrefixes as $prefix) { if (strpos(trim($command), $prefix) === 0) { + _error_log("Command sanitized successfully"); return $command; } } - // If it doesn't start with an allowed prefix, return an empty string + _error_log("Sanitization failed: Command does not start with an allowed prefix"); return ''; } - -// Fetch and sanitize inputs +_error_log("Fetching inputs..."); $codeToExecEncrypted = getInput('codeToExecEncrypted', ''); $codeToExec = _decryptString($codeToExecEncrypted); if (empty($codeToExec)) { + _error_log("Invalid or missing codeToExecEncrypted"); die('Invalid Request'); } -if(!empty($codeToExec->ffmpegCommand)){ - $ffmpegCommand = sanitizeFFmpegCommand($codeToExec->ffmpegCommand); -}else{ - $ffmpegCommand = ''; -} +$ffmpegCommand = !empty($codeToExec->ffmpegCommand) ? sanitizeFFmpegCommand($codeToExec->ffmpegCommand) : ''; +$keyword = !empty($codeToExec->keyword) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword) : ''; -if(!empty($codeToExec->keyword)){ - $keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword); -}else{ - $keyword = ''; -} +_error_log("Code to Execute: " . json_encode($codeToExec)); +_error_log("Sanitized FFMPEG Command: $ffmpegCommand"); +_error_log("Keyword: $keyword"); // Kill processes associated with the keyword if (!empty($keyword)) { + _error_log("Killing process with keyword: $keyword"); killProcessFromKeyword($keyword); } -// Get the system's temporary directory $tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/"; make_path($tempDir); -// Ensure the temp directory ends with a directory separator $tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; - -// Create a unique log file path $logFile = "{$tempDir}ffmpeg_{$keyword}.log"; +_error_log("Log file set to: $logFile"); if (!empty($codeToExec->test)) { $microtime = microtime(true); + _error_log("Test mode triggered"); echo json_encode([ 'error' => false, 'msg' => sprintf('Remote FFmpeg responded successfully in %.4f seconds.', $microtime - $codeToExec->microtime), @@ -214,9 +212,10 @@ if (!empty($codeToExec->test)) { ]); exit; } else if (!empty($codeToExec->log)) { + _error_log("Log retrieval mode triggered"); $time = time(); $modified = @filemtime($logFile); - $secondsAgo = $time - $obj->modified; + $secondsAgo = $time - $modified; $isActive = $secondsAgo < 10; echo json_encode([ 'error' => !file_exists($logFile), @@ -228,8 +227,8 @@ if (!empty($codeToExec->test)) { 'isActive' => $isActive, ]); exit; -} else if (!empty($codeToExec->stop) && !empty($keyword)) { - $cmd = "pkill -f 'ffmpeg.*$keyword'"; +} else if (!empty($codeToExec->stop) && !empty($keyword)) { + _error_log("Stop mode triggered for keyword: $keyword"); echo json_encode([ 'error' => !file_exists($logFile), 'msg' => '', @@ -239,26 +238,24 @@ if (!empty($codeToExec->test)) { 'unlink' => unlink($logFile), ]); exit; -} else - // Validate that ffmpegCommand is not empty after sanitization - if (empty($ffmpegCommand)) { - echo json_encode([ - 'error' => true, - 'msg' => 'Invalid or empty ffmpeg command', - 'codeToExec' => $codeToExec, - ]); - exit; - } +} +if (empty($ffmpegCommand)) { + _error_log("Error: Invalid or empty FFMPEG command"); + echo json_encode([ + 'error' => true, + 'msg' => 'Invalid or empty ffmpeg command', + 'codeToExec' => $codeToExec, + ]); + exit; +} -// Redirect all output to the log file $ffmpegCommand .= " > {$logFile} 2>&1"; - -// Debug output (optional) -error_log("Constructed FFMPEG Command [$keyword]: $ffmpegCommand"); +_error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand"); try { $pid = execAsync($ffmpegCommand, $keyword); + _error_log("Command executed successfully with PID: $pid"); echo json_encode([ 'error' => false, 'msg' => 'Command executed', @@ -267,6 +264,7 @@ try { 'logFile' => $logFile, ]); } catch (Exception $e) { + _error_log("Error executing command: " . $e->getMessage()); echo json_encode([ 'error' => true, 'msg' => 'Failed to execute command',