1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00
This commit is contained in:
Daniel Neto 2024-12-04 19:12:37 -03:00
parent 42f5d3c36c
commit 67ae23b855
11 changed files with 178 additions and 35 deletions

View file

@ -6,6 +6,7 @@ $AVideoEncoder_UA = "AVideoEncoder";
$AVideoEncoderNetwork_UA = "AVideoEncoderNetwork"; $AVideoEncoderNetwork_UA = "AVideoEncoderNetwork";
$AVideoStreamer_UA = "AVideoStreamer"; $AVideoStreamer_UA = "AVideoStreamer";
$AVideoStorage_UA = "AVideoStorage"; $AVideoStorage_UA = "AVideoStorage";
$AVideoRestreamer_UA = "AVideoRestreamer";
function isAVideoMobileApp($user_agent = "") function isAVideoMobileApp($user_agent = "")
{ {

View file

@ -570,7 +570,7 @@ function buildFFMPEGRemoteURL($actionParams)
return $url; return $url;
} }
function execFFMPEGAsyncOrRemote($command, $keyword = null) function execFFMPEGAsyncOrRemote($command, $keyword)
{ {
$url = buildFFMPEGRemoteURL(['ffmpegCommand' => $command, 'keyword' => $keyword]); $url = buildFFMPEGRemoteURL(['ffmpegCommand' => $command, 'keyword' => $keyword]);
if ($url) { if ($url) {
@ -586,8 +586,9 @@ function execFFMPEGAsyncOrRemote($command, $keyword = null)
function getFFMPEGRemoteLog($keyword) function getFFMPEGRemoteLog($keyword)
{ {
$url = buildFFMPEGRemoteURL(['log' => 1, 'keyword' => $keyword]); $url = buildFFMPEGRemoteURL(['log' => 1, 'keyword' => $keyword]);
//var_dump($url);
if ($url) { if ($url) {
_error_log("getFFMPEGRemoteLog: URL $url"); _error_log("getFFMPEGRemoteLog: URL $url ".json_encode(debug_backtrace()));
return json_decode(url_get_contents($url)); return json_decode(url_get_contents($url));
} else { } else {
return false; return false;

View file

@ -498,7 +498,7 @@ class sqlDAL
global $crc, $fetchAllAssoc_cache, $isStandAlone; global $crc, $fetchAllAssoc_cache, $isStandAlone;
if($isStandAlone){ if($isStandAlone){
return false; return array();
} }
if (!isset($fetchAllAssoc_cache)) { if (!isset($fetchAllAssoc_cache)) {
$fetchAllAssoc_cache = []; $fetchAllAssoc_cache = [];

View file

@ -1338,6 +1338,12 @@ class PlayList extends ObjectYPT
$values[] = $playlists_id; $values[] = $playlists_id;
} }
if (!empty($users_id)) {
$sql .= " AND pl.users_id = ? ";
$formats .= "i";
$values[] = $users_id;
}
if (!empty($status)) { if (!empty($status)) {
$sql .= " AND status = ? "; $sql .= " AND status = ? ";
$formats .= "s"; $formats .= "s";

View file

@ -11,6 +11,6 @@ header('Content-Type: application/json');
_session_write_close(); _session_write_close();
setRowCount(10); setRowCount(10);
//mysqlBeginTransaction(); //mysqlBeginTransaction();
$row = PlayList::getAll('public', @$_REQUEST['Playlists_id']); $row = PlayList::getAll('public', @$_REQUEST['Playlists_id'], (User::isAdmin()?0:USer::getId()));
//mysqlCommit(); //mysqlCommit();
echo json_encode($row); echo json_encode($row);

View file

@ -103,7 +103,7 @@ _error_log("Script initiated: FFMPEG command execution script started");
if (empty($streamerURL)) { if (empty($streamerURL)) {
_error_log("Error: streamerURL is not defined"); _error_log("Error: streamerURL is not defined");
echo json_encode(['error' => true, 'message' => 'streamerURL not defined']); echo json_encode(['error' => true, 'msg' => 'streamerURL not defined']);
exit; exit;
} }
@ -124,6 +124,7 @@ function _decryptString($string)
} }
} }
_error_log("Failed to decrypt string or invalid time"); _error_log("Failed to decrypt string or invalid time");
//return $json2;
return false; return false;
} }
@ -154,8 +155,9 @@ function sanitizeFFmpegCommand($command)
// 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://vlu.me/', 'rtmp://live/', $command);
$command = str_replace('https://live:8443/', 'https://vlu.me:8443/', $command); //$command = str_replace('rtmp://live/', 'rtmp://vlu.me/', $command);
//$command = str_replace('https://live:8443/', 'https://vlu.me:8443/', $command);
$command = preg_replace('/\s*>.*(?:2>&1)?/', '', $command); $command = preg_replace('/\s*>.*(?:2>&1)?/', '', $command);
$command = preg_replace('/[;|`<>]/', '', $command); $command = preg_replace('/[;|`<>]/', '', $command);
@ -171,34 +173,58 @@ function sanitizeFFmpegCommand($command)
return ''; return '';
} }
function addKeywordToFFmpegCommand(string $command, string $keyword): string {
// Escape the keyword to avoid shell injection
$escapedKeyword = escapeshellarg($keyword);
// Break the command into parts to safely insert the metadata
$commandParts = explode(' ', $command);
// Find the index of the output URL (typically the last argument in FFmpeg commands)
$outputUrlIndex = array_key_last($commandParts);
if (preg_match('/^(rtmp|http|https):\/\//', $commandParts[$outputUrlIndex])) {
// Insert metadata before the output URL
array_splice($commandParts, $outputUrlIndex, 0, ["-metadata", "keyword=$escapedKeyword"]);
} else {
// If no URL is found, append metadata at the end
$commandParts[] = "-metadata";
$commandParts[] = "keyword=$escapedKeyword";
}
// Reconstruct the command
return implode(' ', $commandParts);
}
_error_log("Fetching inputs..."); _error_log("Fetching inputs...");
$codeToExecEncrypted = getInput('codeToExecEncrypted', ''); $codeToExecEncrypted = getInput('codeToExecEncrypted', '');
$codeToExec = _decryptString($codeToExecEncrypted); $codeToExec = _decryptString($codeToExecEncrypted);
if (empty($codeToExec)) { if (empty($codeToExec)) {
_error_log("Invalid or missing codeToExecEncrypted"); _error_log("Invalid or missing codeToExecEncrypted");
die('Invalid Request'); die(json_encode(array('error' => true, 'msg' => 'Invalid or missing code')));
} }
$ffmpegCommand = !empty($codeToExec->ffmpegCommand) ? sanitizeFFmpegCommand($codeToExec->ffmpegCommand) : ''; $ffmpegCommand = !empty($codeToExec->ffmpegCommand) ? sanitizeFFmpegCommand($codeToExec->ffmpegCommand) : '';
$keyword = !empty($codeToExec->keyword) ? preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword) : date('Ymdhmi');
if (empty($codeToExec->keyword)) {
_error_log("keyword: is empty");
$keyword = date('Ymdhmi');
} else {
_error_log("keyword: found: {$codeToExec->keyword}");
$keyword = preg_replace('/[^a-zA-Z0-9_-]/', '', $codeToExec->keyword);
}
_error_log("Code to Execute: " . json_encode($codeToExec)); _error_log("Code to Execute: " . json_encode($codeToExec));
_error_log("Sanitized FFMPEG Command: $ffmpegCommand"); _error_log("Sanitized FFMPEG Command: $ffmpegCommand");
_error_log("Keyword: $keyword"); _error_log("Keyword: $keyword");
// Kill processes associated with the keyword
if (!empty($keyword)) {
_error_log("Killing process with keyword: $keyword");
killProcessFromKeyword($keyword);
}
$tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/"; $tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/";
make_path($tempDir); make_path($tempDir);
$tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
$logFile = "{$tempDir}ffmpeg_{$keyword}.log"; $logFile = "{$tempDir}ffmpeg_{$keyword}.log";
_error_log("Log file set to: $logFile"); //_error_log("Log file set to: $logFile");
if (!empty($codeToExec->test)) { if (!empty($codeToExec->test)) {
$microtime = microtime(true); $microtime = microtime(true);
@ -229,13 +255,36 @@ if (!empty($codeToExec->test)) {
exit; exit;
} else if (!empty($codeToExec->stop) && !empty($keyword)) { } else if (!empty($codeToExec->stop) && !empty($keyword)) {
_error_log("Stop mode triggered for keyword: $keyword"); _error_log("Stop mode triggered for keyword: $keyword");
// Count the number of processes with the keyword before killing them
$countCommand = "pgrep -f 'ffmpeg.*$keyword' | wc -l";
$processToKillCount = intval(exec($countCommand));
// Kill the processes matching the keyword
$killCommand = "pkill -f 'ffmpeg.*$keyword'";
$killResult = exec($killCommand, $output, $killStatus);
$processAfterKillCount = intval(exec($countCommand));
// Attempt to delete the log file
$unlinkSuccess = false;
if (file_exists($logFile)) {
$unlinkSuccess = unlink($logFile);
}
echo json_encode([ echo json_encode([
'error' => !file_exists($logFile), 'error' =>$processAfterKillCount !== 0, // Indicate if killing processes was successful
'msg' => '', 'msg' => $processAfterKillCount !== 0 ? 'Processes killed successfully.' : 'Failed to kill processes.',
'logFile' => $logFile, 'logFile' => $logFile,
'kill' => exec("pkill -f 'ffmpeg.*$keyword'"), 'kill' => $killResult, // Result of pkill command
'keyword' => $keyword, 'keyword' => $keyword,
'unlink' => unlink($logFile), 'unlink' => $unlinkSuccess,
'processToKillCount' => $processToKillCount,
'processAfterKillCount' => $processAfterKillCount, // Number of processes killed
'countCommand' => $countCommand,
'killCommand' => $killCommand,
'output' => $output,
'killStatus' => $killStatus,
]); ]);
exit; exit;
} }
@ -250,6 +299,16 @@ if (empty($ffmpegCommand)) {
exit; exit;
} }
// Kill processes associated with the keyword
if (!empty($keyword)) {
_error_log("Killing process with keyword: $keyword");
killProcessFromKeyword($keyword);
}
$ffmpegCommand = addKeywordToFFmpegCommand($ffmpegCommand, $keyword);
file_put_contents($logFile, $ffmpegCommand.PHP_EOL.PHP_EOL);
$ffmpegCommand .= " > {$logFile} 2>&1"; $ffmpegCommand .= " > {$logFile} 2>&1";
_error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand"); _error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand");

View file

@ -150,6 +150,7 @@ class Live_restreams_logs extends ObjectYPT
} else { } else {
$live_restreams_logs_id = $latest['id']; $live_restreams_logs_id = $latest['id'];
} }
//var_dump($live_transmitions_history_id, $live_restreams_id, $live_restreams_logs_id, $action);
return self::getURL($live_transmitions_history_id, $live_restreams_id, $live_restreams_logs_id, $action); return self::getURL($live_transmitions_history_id, $live_restreams_id, $live_restreams_logs_id, $action);
} }

View file

@ -87,7 +87,7 @@ foreach ($logFiles as $logFile) {
echo "kill_ffmpeg_restream.php The file too large logFiles $logFile "._humanFileSize($filesize).PHP_EOL; echo "kill_ffmpeg_restream.php The file too large logFiles $logFile "._humanFileSize($filesize).PHP_EOL;
continue; continue;
}else{ }else{
echo "kill_ffmpeg_restream.php logFiles $logFile "._humanFileSize($filesize).PHP_EOL; //echo "kill_ffmpeg_restream.php logFiles $logFile "._humanFileSize($filesize).PHP_EOL;
} }
$lastModifiedFormatted = formatLastModifiedTime($lastModified); $lastModifiedFormatted = formatLastModifiedTime($lastModified);
@ -114,7 +114,7 @@ foreach ($logFiles as $logFile) {
$lastUrlOpened = ''; $lastUrlOpened = '';
$foundTsFile = false; $foundTsFile = false;
echo "kill_ffmpeg_restream.php start.\n"; //echo "kill_ffmpeg_restream.php start.\n";
// Loop through the last N lines of the log file // Loop through the last N lines of the log file
foreach ($logContent as $key => $line) { foreach ($logContent as $key => $line) {
$line = str_replace(array("\r", "\n"), '', $line); $line = str_replace(array("\r", "\n"), '', $line);
@ -151,7 +151,7 @@ foreach ($logFiles as $logFile) {
} }
} }
} }
echo "kill_ffmpeg_restream.php done.\n"; //echo "kill_ffmpeg_restream.php done.\n";
// If any .ts file is found, do not kill the process // If any .ts file is found, do not kill the process
if ($foundTsFile) { if ($foundTsFile) {
echo "Found .ts file in log, process will not be killed for log file: $logFile (last modified on $lastModifiedFormatted).\n"; echo "Found .ts file in log, process will not be killed for log file: $logFile (last modified on $lastModifiedFormatted).\n";

View file

@ -77,6 +77,8 @@ if (!empty($_REQUEST['tokenForAction'])) {
$json = verifyTokenForAction($_REQUEST['tokenForAction']); $json = verifyTokenForAction($_REQUEST['tokenForAction']);
//var_dump($json);exit; //var_dump($json);exit;
if (!empty($json) && isset($json->error) && empty($json->error)) { if (!empty($json) && isset($json->error) && empty($json->error)) {
$keyword = 'restream_' . md5(basename($json->logFile));
$obj->keyword = $keyword;
$obj->error = false; $obj->error = false;
error_log("Restreamer.json.php token verified " . json_encode($json)); error_log("Restreamer.json.php token verified " . json_encode($json));
switch ($json->action) { switch ($json->action) {
@ -85,15 +87,14 @@ if (!empty($_REQUEST['tokenForAction'])) {
$obj->logName = str_replace($logFileLocation, '', $json->logFile); $obj->logName = str_replace($logFileLocation, '', $json->logFile);
$obj->logName = preg_replace('/[^a-z0-9_.-]/i', '', $obj->logName); $obj->logName = preg_replace('/[^a-z0-9_.-]/i', '', $obj->logName);
$keyword ='restream_'. md5($json->logFile);
$resp = getFFMPEGRemoteLog($keyword); $resp = getFFMPEGRemoteLog($keyword);
if(!empty($resp) && empty($resp->error)){ if (!empty($resp) && empty($resp->error)) {
$obj->modified = $resp->modified; $obj->modified = $resp->modified;
$obj->secondsAgo = $resp->secondsAgo; $obj->secondsAgo = $resp->secondsAgo;
$obj->isActive = $resp->isActive; $obj->isActive = $resp->isActive;
$obj->remoteLog = true; $obj->remoteLog = true;
$obj->resp = $resp; $obj->resp = $resp;
}else if (!empty($obj->logName)) { } else if (!empty($obj->logName)) {
$logFile = $logFileLocation . $obj->logName; $logFile = $logFileLocation . $obj->logName;
if (file_exists($logFile)) { if (file_exists($logFile)) {
$obj->modified = @filemtime($logFile); $obj->modified = @filemtime($logFile);
@ -107,11 +108,20 @@ if (!empty($_REQUEST['tokenForAction'])) {
exit; exit;
break; break;
case 'stop': case 'stop':
$obj->killIfIsRunning = killIfIsRunning($json);
$obj->logName = str_replace($logFileLocation, '', $json->logFile); $resp = stopFFMPEGRemote($keyword);
$obj->logName = preg_replace('/[^a-z0-9_.-]/i', '', $obj->logName); $obj->remoteResponse = $resp;
$logFile = $logFileLocation . $obj->logName; if (!empty($resp) && empty($resp->error)) {
unlink($logFile); $obj->remoteKill = true;
}else{
$obj->killIfIsRunning = killIfIsRunning($json);
$obj->logName = str_replace($logFileLocation, '', $json->logFile);
$obj->logName = preg_replace('/[^a-z0-9_.-]/i', '', $obj->logName);
$logFile = $logFileLocation . $obj->logName;
$obj->remoteKill = false;
unlink($logFile);
}
echo json_encode($obj); echo json_encode($obj);
exit; exit;
break; break;
@ -646,9 +656,10 @@ function startRestream($m3u8, $restreamsDestinations, $logFile, $robj, $tries =
_make_path($logFile); _make_path($logFile);
file_put_contents($logFile, $command . PHP_EOL); file_put_contents($logFile, $command . PHP_EOL);
if (empty($isATest)) { if (empty($isATest)) {
$keyword = md5($logFile); $keyword = 'restream_' . md5(basename($logFile));
$robj->keyword = $keyword;
// use remote ffmpeg here // use remote ffmpeg here
execFFMPEGAsyncOrRemote($command . ' > ' . $logFile, 'restream_'.$keyword); execFFMPEGAsyncOrRemote($command . ' > ' . $logFile, $keyword);
} }
error_log("Restreamer.json.php startRestream finish"); error_log("Restreamer.json.php startRestream finish");
} }

View file

@ -57,7 +57,7 @@ if (empty($obj->url)) {
} }
debugLog(__LINE__); debugLog(__LINE__);
unset($obj->url); //unset($obj->url);
$obj->end = number_format(microtime(true) - $obj->start, 2); $obj->end = number_format(microtime(true) - $obj->start, 2);
die(json_encode($obj)); die(json_encode($obj));

View file

@ -585,10 +585,9 @@ class Scheduler extends PluginAbstract
// Run the function to delete files older than 7 days from /var/www/tmp // Run the function to delete files older than 7 days from /var/www/tmp
$this->deleteOldFiles(); $this->deleteOldFiles();
self::manageLogFile();
} }
function deleteOldFiles($directory = '/var/www/tmp', $days = 7) function deleteOldFiles($directory = '/var/www/tmp', $days = 7)
{ {
// Check if the directory exists // Check if the directory exists
@ -639,4 +638,69 @@ class Scheduler extends PluginAbstract
return true; return true;
} }
static function manageLogFile()
{
global $global;
$logFilePath = $global['logfile'];
// Ensure the logfile is not empty and has a .log extension
if (empty($logFilePath)) {
_error_log("Log file path is empty; no action required.");
return;
}
if (pathinfo($logFilePath, PATHINFO_EXTENSION) !== 'log') {
_error_log("Log file path is not a .log file; no action required. [$logFilePath]");
return;
}
// Get yesterday's date
$yesterdayDate = date('Y-m-d', strtotime('-1 day'));
// Define the new logfile name with yesterday's date
$newLogFileName = $logFilePath . '.' . $yesterdayDate . '.log';
// Check if the current logfile exists
if (file_exists($logFilePath)) {
// Move the current logfile to a new file with yesterday's date
if (rename($logFilePath, $newLogFileName)) {
_error_log("Log file successfully moved to: $newLogFileName");
} else {
_error_log("Failed to move log file to: $newLogFileName");
}
} else {
_error_log("Log file does not exist: $logFilePath");
}
// Create a new empty logfile
if (touch($logFilePath)) {
_error_log("New log file created: $logFilePath");
// Ensure Apache can write to the new log file
if (chmod($logFilePath, 0666)) {
_error_log("Permissions set to 0666 for: $logFilePath");
} else {
_error_log("Failed to set permissions for: $logFilePath");
}
} else {
_error_log("Failed to create new log file: $logFilePath");
}
// Delete log files older than 30 days in the same directory
$logDir = dirname($logFilePath);
$files = glob($logDir . '/*.log'); // Get all .log files in the directory
$thirtyDaysAgo = time() - (30 * 24 * 60 * 60); // Timestamp for 30 days ago
foreach ($files as $file) {
if (filemtime($file) < $thirtyDaysAgo) {
if (unlink($file)) {
_error_log("Deleted old log file: $file");
} else {
_error_log("Failed to delete old log file: $file");
}
}
}
}
} }