1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-05 02:39:46 +02:00
This commit is contained in:
Daniel Neto 2024-12-03 14:56:56 -03:00
parent 51cb12d2ee
commit f38a9536da
3 changed files with 151 additions and 123 deletions

View file

@ -525,6 +525,25 @@ function getFFMPEGRemoteLog($keyword)
} }
} }
function stopFFMPEGRemote($keyword)
{
$obj = AVideoPlugin::getDataObjectIfEnabled('API');
if(!empty($obj) && !empty($obj->standAloneFFMPEG)){
$url = "{$obj->standAloneFFMPEG}";
$codeToExec = array('stop'=>1, 'keyword'=>$keyword, 'time'=>time());
$codeToExecEncrypted = encryptString(json_encode($codeToExec));
$url = addQueryStringParameter($url, 'APISecret', $obj->APISecret);
$url = addQueryStringParameter($url, 'codeToExecEncrypted', $codeToExecEncrypted);
_error_log("execFFMPEGAsyncOrRemote: URL $url");
return json_decode(url_get_contents($url));
}else{
return false;
}
}
// Function to find the process by keyword using the pid file // Function to find the process by keyword using the pid file
function findProcess($keyword) function findProcess($keyword)
{ {

View file

@ -1,4 +1,5 @@
<?php <?php
/** /**
* FFMPEG Command Execution Script with API Secret Validation * FFMPEG Command Execution Script with API Secret Validation
* ----------------------------------------------------------- * -----------------------------------------------------------
@ -87,68 +88,70 @@
* Replace `https://yourSite.com/` with your actual website URL. * Replace `https://yourSite.com/` with your actual website URL.
*/ */
$global_timeLimit = 300; $global_timeLimit = 300;
ini_set("memory_limit", -1); ini_set("memory_limit", -1);
ini_set('default_socket_timeout', $global_timeLimit); ini_set('default_socket_timeout', $global_timeLimit);
set_time_limit($global_timeLimit); set_time_limit($global_timeLimit);
ini_set('max_execution_time', $global_timeLimit); ini_set('max_execution_time', $global_timeLimit);
ini_set("memory_limit", "-1"); ini_set("memory_limit", "-1");
header('Content-Type: application/json'); header('Content-Type: application/json');
require_once __DIR__ . "/../../../objects/functionsStandAlone.php"; require_once __DIR__ . "/../../../objects/functionsStandAlone.php";
if (empty($streamerURL)) { if (empty($streamerURL)) {
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']); echo json_encode(['error' => true, 'message' => 'streamerURL not defined']);
exit; exit;
} }
function _decryptString($string) function _decryptString($string)
{ {
global $global; global $global;
$url = "{$global['webSiteRootURL']}plugin/API/get.json.php?APIName=decryptString&string={$string}"; $url = "{$global['webSiteRootURL']}plugin/API/get.json.php?APIName=decryptString&string={$string}";
$content = file_get_contents($url); $content = file_get_contents($url);
$json = json_decode($content); $json = json_decode($content);
if (!empty($json) && empty($json->error)) { if (!empty($json) && empty($json->error)) {
$json2 = json_decode($json->message); $json2 = json_decode($json->message);
if ($json2->time > strtotime('30 seconds ago')) { if ($json2->time > strtotime('30 seconds ago')) {
return $json2; return $json2;
} }
} }
return $json2; return $json2;
return false; return false;
} }
// Function to safely get inputs from either command line or request // Function to safely get inputs from either command line or request
function getInput($key, $default = '') { function getInput($key, $default = '')
global $argv; {
global $argv;
// Check if running from command line or HTTP request
if (php_sapi_name() === 'cli') { // Check if running from command line or HTTP request
foreach ($argv as $arg) { if (php_sapi_name() === 'cli') {
if (strpos($arg, "{$key}=") === 0) { foreach ($argv as $arg) {
return substr($arg, strlen("{$key}=")); if (strpos($arg, "{$key}=") === 0) {
} return substr($arg, strlen("{$key}="));
} }
} else { }
return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default; } else {
} return isset($_REQUEST[$key]) ? $_REQUEST[$key] : $default;
}
return $default;
} return $default;
}
// Validate and sanitize the ffmpegCommand
function sanitizeFFmpegCommand($command) { // Validate and sanitize the ffmpegCommand
function sanitizeFFmpegCommand($command)
{
$allowedPrefixes = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg']; $allowedPrefixes = ['ffmpeg', '/usr/bin/ffmpeg', '/bin/ffmpeg'];
// Remove dangerous characters // Remove dangerous characters
$command = str_replace('&&', '', $command); $command = str_replace('&&', '', $command);
$command = str_replace('rtmp://live/', 'rtmp://vlu.me/', $command); $command = str_replace('rtmp://live/', 'rtmp://vlu.me/', $command);
$command = str_replace('https://live:8443/', 'https://vlu.me:8443/', $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') // 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('/\s*>.*(?:2>&1)?/', '', $command);
$command = preg_replace('/[;|`<>]/', '', $command); $command = preg_replace('/[;|`<>]/', '', $command);
@ -164,22 +167,22 @@
return ''; return '';
} }
// Fetch and sanitize inputs // Fetch and sanitize inputs
$codeToExecEncrypted = getInput('codeToExecEncrypted', ''); $codeToExecEncrypted = getInput('codeToExecEncrypted', '');
$codeToExec = _decryptString($codeToExecEncrypted); $codeToExec = _decryptString($codeToExecEncrypted);
if (empty($codeToExec)) { if (empty($codeToExec)) {
die('Invalid Request'); die('Invalid Request');
} }
$ffmpegCommand = sanitizeFFmpegCommand($codeToExec->ffmpegCommand); $ffmpegCommand = sanitizeFFmpegCommand($codeToExec->ffmpegCommand);
$keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword); $keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword);
// Kill processes associated with the keyword // Kill processes associated with the keyword
if (!empty($keyword)) { if (!empty($keyword)) {
killProcessFromKeyword($keyword); killProcessFromKeyword($keyword);
} }
// Get the system's temporary directory // Get the system's temporary directory
$tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/"; $tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/";
@ -191,56 +194,65 @@ $tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
// Create a unique log file path // Create a unique log file path
$logFile = "{$tempDir}ffmpeg_{$keyword}.log"; $logFile = "{$tempDir}ffmpeg_{$keyword}.log";
$time = time(); if (!empty($codeToExec->log)) {
$modified = @filemtime($logFile); $time = time();
$secondsAgo = $time - $obj->modified; $modified = @filemtime($logFile);
$isActive = $secondsAgo < 10; $secondsAgo = $time - $obj->modified;
$isActive = $secondsAgo < 10;
if (!empty($codeToExec->log)) {
echo json_encode([ echo json_encode([
'error' => !file_exists($logFile), 'error' => !file_exists($logFile),
'msg' => '', 'msg' => '',
'logFile' => $logFile, 'logFile' => $logFile,
'time' =>$time, 'time' => $time,
'modified' =>$modified, 'modified' => $modified,
'secondsAgo' =>$secondsAgo, 'secondsAgo' => $secondsAgo,
'isActive' =>$isActive, 'isActive' => $isActive,
]); ]);
exit; exit;
}else } else if (!empty($codeToExec->stop) && !empty($keyword)) {
// Validate that ffmpegCommand is not empty after sanitization $cmd = "pkill -f 'ffmpeg.*$keyword'";
if (empty($ffmpegCommand)) { echo json_encode([
echo json_encode([ 'error' => !file_exists($logFile),
'error' => true, 'msg' => '',
'msg' => 'Invalid or empty ffmpeg command', 'logFile' => $logFile,
'codeToExec' => $codeToExec, 'kill' => exec("pkill -f 'ffmpeg.*$keyword'"),
]); 'keyword' => $keyword,
exit; 'unlink' => unlink($logFile),
} ]);
exit;
} else
// Redirect all output to the log file // Validate that ffmpegCommand is not empty after sanitization
$ffmpegCommand .= " > {$logFile} 2>&1"; if (empty($ffmpegCommand)) {
echo json_encode([
// Debug output (optional) 'error' => true,
error_log("Constructed FFMPEG Command [$keyword]: $ffmpegCommand"); 'msg' => 'Invalid or empty ffmpeg command',
'codeToExec' => $codeToExec,
try { ]);
$pid = execAsync($ffmpegCommand, $keyword); exit;
echo json_encode([ }
'error' => false,
'msg' => 'Command executed',
'command' => $ffmpegCommand, // Redirect all output to the log file
'pid' => $pid, $ffmpegCommand .= " > {$logFile} 2>&1";
'logFile' => $logFile,
]); // Debug output (optional)
} catch (Exception $e) { error_log("Constructed FFMPEG Command [$keyword]: $ffmpegCommand");
echo json_encode([
'error' => true, try {
'msg' => 'Failed to execute command', $pid = execAsync($ffmpegCommand, $keyword);
'errorMsg' => $e->getMessage(), echo json_encode([
'logFile' => $logFile, 'error' => false,
]); 'msg' => 'Command executed',
} 'command' => $ffmpegCommand,
exit; 'pid' => $pid,
'logFile' => $logFile,
]);
} catch (Exception $e) {
echo json_encode([
'error' => true,
'msg' => 'Failed to execute command',
'errorMsg' => $e->getMessage(),
'logFile' => $logFile,
]);
}
exit;

View file

@ -1,10 +1,7 @@
<?php <?php
includeConfigLog(__LINE__, basename(__FILE__));
require_once $global['systemRootPath'] . 'locale/function.php'; require_once $global['systemRootPath'] . 'locale/function.php';
includeConfigLog(__LINE__, basename(__FILE__));
require_once $global['systemRootPath'] . 'objects/plugin.php'; require_once $global['systemRootPath'] . 'objects/plugin.php';
includeConfigLog(__LINE__, basename(__FILE__));
abstract class PluginAbstract { abstract class PluginAbstract {