mirror of
https://github.com/DanielnetoDotCom/YouPHPTube
synced 2025-10-03 01:39:24 +02:00
Update
This commit is contained in:
parent
42f5d3c36c
commit
67ae23b855
11 changed files with 178 additions and 35 deletions
|
@ -6,6 +6,7 @@ $AVideoEncoder_UA = "AVideoEncoder";
|
|||
$AVideoEncoderNetwork_UA = "AVideoEncoderNetwork";
|
||||
$AVideoStreamer_UA = "AVideoStreamer";
|
||||
$AVideoStorage_UA = "AVideoStorage";
|
||||
$AVideoRestreamer_UA = "AVideoRestreamer";
|
||||
|
||||
function isAVideoMobileApp($user_agent = "")
|
||||
{
|
||||
|
|
|
@ -570,7 +570,7 @@ function buildFFMPEGRemoteURL($actionParams)
|
|||
return $url;
|
||||
}
|
||||
|
||||
function execFFMPEGAsyncOrRemote($command, $keyword = null)
|
||||
function execFFMPEGAsyncOrRemote($command, $keyword)
|
||||
{
|
||||
$url = buildFFMPEGRemoteURL(['ffmpegCommand' => $command, 'keyword' => $keyword]);
|
||||
if ($url) {
|
||||
|
@ -586,8 +586,9 @@ function execFFMPEGAsyncOrRemote($command, $keyword = null)
|
|||
function getFFMPEGRemoteLog($keyword)
|
||||
{
|
||||
$url = buildFFMPEGRemoteURL(['log' => 1, 'keyword' => $keyword]);
|
||||
//var_dump($url);
|
||||
if ($url) {
|
||||
_error_log("getFFMPEGRemoteLog: URL $url");
|
||||
_error_log("getFFMPEGRemoteLog: URL $url ".json_encode(debug_backtrace()));
|
||||
return json_decode(url_get_contents($url));
|
||||
} else {
|
||||
return false;
|
||||
|
|
|
@ -498,7 +498,7 @@ class sqlDAL
|
|||
global $crc, $fetchAllAssoc_cache, $isStandAlone;
|
||||
|
||||
if($isStandAlone){
|
||||
return false;
|
||||
return array();
|
||||
}
|
||||
if (!isset($fetchAllAssoc_cache)) {
|
||||
$fetchAllAssoc_cache = [];
|
||||
|
|
|
@ -1338,6 +1338,12 @@ class PlayList extends ObjectYPT
|
|||
$values[] = $playlists_id;
|
||||
}
|
||||
|
||||
if (!empty($users_id)) {
|
||||
$sql .= " AND pl.users_id = ? ";
|
||||
$formats .= "i";
|
||||
$values[] = $users_id;
|
||||
}
|
||||
|
||||
if (!empty($status)) {
|
||||
$sql .= " AND status = ? ";
|
||||
$formats .= "s";
|
||||
|
|
|
@ -11,6 +11,6 @@ header('Content-Type: application/json');
|
|||
_session_write_close();
|
||||
setRowCount(10);
|
||||
//mysqlBeginTransaction();
|
||||
$row = PlayList::getAll('public', @$_REQUEST['Playlists_id']);
|
||||
$row = PlayList::getAll('public', @$_REQUEST['Playlists_id'], (User::isAdmin()?0:USer::getId()));
|
||||
//mysqlCommit();
|
||||
echo json_encode($row);
|
||||
|
|
|
@ -103,7 +103,7 @@ _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']);
|
||||
echo json_encode(['error' => true, 'msg' => 'streamerURL not defined']);
|
||||
exit;
|
||||
}
|
||||
|
||||
|
@ -124,6 +124,7 @@ function _decryptString($string)
|
|||
}
|
||||
}
|
||||
_error_log("Failed to decrypt string or invalid time");
|
||||
//return $json2;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -154,8 +155,9 @@ function sanitizeFFmpegCommand($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);
|
||||
$command = str_replace('rtmp://vlu.me/', 'rtmp://live/', $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('/[;|`<>]/', '', $command);
|
||||
|
||||
|
@ -171,34 +173,58 @@ function sanitizeFFmpegCommand($command)
|
|||
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...");
|
||||
$codeToExecEncrypted = getInput('codeToExecEncrypted', '');
|
||||
$codeToExec = _decryptString($codeToExecEncrypted);
|
||||
|
||||
if (empty($codeToExec)) {
|
||||
_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) : '';
|
||||
$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("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);
|
||||
}
|
||||
|
||||
$tempDir = "{$global['systemRootPath']}videos/ffmpegLogs/";
|
||||
make_path($tempDir);
|
||||
|
||||
$tempDir = rtrim($tempDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR;
|
||||
$logFile = "{$tempDir}ffmpeg_{$keyword}.log";
|
||||
_error_log("Log file set to: $logFile");
|
||||
//_error_log("Log file set to: $logFile");
|
||||
|
||||
if (!empty($codeToExec->test)) {
|
||||
$microtime = microtime(true);
|
||||
|
@ -229,13 +255,36 @@ if (!empty($codeToExec->test)) {
|
|||
exit;
|
||||
} else if (!empty($codeToExec->stop) && !empty($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([
|
||||
'error' => !file_exists($logFile),
|
||||
'msg' => '',
|
||||
'error' =>$processAfterKillCount !== 0, // Indicate if killing processes was successful
|
||||
'msg' => $processAfterKillCount !== 0 ? 'Processes killed successfully.' : 'Failed to kill processes.',
|
||||
'logFile' => $logFile,
|
||||
'kill' => exec("pkill -f 'ffmpeg.*$keyword'"),
|
||||
'kill' => $killResult, // Result of pkill command
|
||||
'keyword' => $keyword,
|
||||
'unlink' => unlink($logFile),
|
||||
'unlink' => $unlinkSuccess,
|
||||
'processToKillCount' => $processToKillCount,
|
||||
'processAfterKillCount' => $processAfterKillCount, // Number of processes killed
|
||||
'countCommand' => $countCommand,
|
||||
'killCommand' => $killCommand,
|
||||
'output' => $output,
|
||||
'killStatus' => $killStatus,
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
|
@ -250,6 +299,16 @@ if (empty($ffmpegCommand)) {
|
|||
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";
|
||||
_error_log("Executing FFMPEG Command [$keyword]: $ffmpegCommand");
|
||||
|
||||
|
|
|
@ -150,6 +150,7 @@ class Live_restreams_logs extends ObjectYPT
|
|||
} else {
|
||||
$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);
|
||||
}
|
||||
|
||||
|
|
|
@ -87,7 +87,7 @@ foreach ($logFiles as $logFile) {
|
|||
echo "kill_ffmpeg_restream.php The file too large logFiles $logFile "._humanFileSize($filesize).PHP_EOL;
|
||||
continue;
|
||||
}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);
|
||||
|
||||
|
@ -114,7 +114,7 @@ foreach ($logFiles as $logFile) {
|
|||
$lastUrlOpened = '';
|
||||
$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
|
||||
foreach ($logContent as $key => $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 ($foundTsFile) {
|
||||
echo "Found .ts file in log, process will not be killed for log file: $logFile (last modified on $lastModifiedFormatted).\n";
|
||||
|
|
|
@ -77,6 +77,8 @@ if (!empty($_REQUEST['tokenForAction'])) {
|
|||
$json = verifyTokenForAction($_REQUEST['tokenForAction']);
|
||||
//var_dump($json);exit;
|
||||
if (!empty($json) && isset($json->error) && empty($json->error)) {
|
||||
$keyword = 'restream_' . md5(basename($json->logFile));
|
||||
$obj->keyword = $keyword;
|
||||
$obj->error = false;
|
||||
error_log("Restreamer.json.php token verified " . json_encode($json));
|
||||
switch ($json->action) {
|
||||
|
@ -85,7 +87,6 @@ if (!empty($_REQUEST['tokenForAction'])) {
|
|||
$obj->logName = str_replace($logFileLocation, '', $json->logFile);
|
||||
$obj->logName = preg_replace('/[^a-z0-9_.-]/i', '', $obj->logName);
|
||||
|
||||
$keyword ='restream_'. md5($json->logFile);
|
||||
$resp = getFFMPEGRemoteLog($keyword);
|
||||
if (!empty($resp) && empty($resp->error)) {
|
||||
$obj->modified = $resp->modified;
|
||||
|
@ -107,11 +108,20 @@ if (!empty($_REQUEST['tokenForAction'])) {
|
|||
exit;
|
||||
break;
|
||||
case 'stop':
|
||||
|
||||
$resp = stopFFMPEGRemote($keyword);
|
||||
$obj->remoteResponse = $resp;
|
||||
if (!empty($resp) && empty($resp->error)) {
|
||||
$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);
|
||||
exit;
|
||||
break;
|
||||
|
@ -646,9 +656,10 @@ function startRestream($m3u8, $restreamsDestinations, $logFile, $robj, $tries =
|
|||
_make_path($logFile);
|
||||
file_put_contents($logFile, $command . PHP_EOL);
|
||||
if (empty($isATest)) {
|
||||
$keyword = md5($logFile);
|
||||
$keyword = 'restream_' . md5(basename($logFile));
|
||||
$robj->keyword = $keyword;
|
||||
// use remote ffmpeg here
|
||||
execFFMPEGAsyncOrRemote($command . ' > ' . $logFile, 'restream_'.$keyword);
|
||||
execFFMPEGAsyncOrRemote($command . ' > ' . $logFile, $keyword);
|
||||
}
|
||||
error_log("Restreamer.json.php startRestream finish");
|
||||
}
|
||||
|
|
|
@ -57,7 +57,7 @@ if (empty($obj->url)) {
|
|||
}
|
||||
|
||||
debugLog(__LINE__);
|
||||
unset($obj->url);
|
||||
//unset($obj->url);
|
||||
|
||||
$obj->end = number_format(microtime(true) - $obj->start, 2);
|
||||
die(json_encode($obj));
|
||||
|
|
|
@ -585,10 +585,9 @@ class Scheduler extends PluginAbstract
|
|||
|
||||
// Run the function to delete files older than 7 days from /var/www/tmp
|
||||
$this->deleteOldFiles();
|
||||
self::manageLogFile();
|
||||
}
|
||||
|
||||
|
||||
|
||||
function deleteOldFiles($directory = '/var/www/tmp', $days = 7)
|
||||
{
|
||||
// Check if the directory exists
|
||||
|
@ -639,4 +638,69 @@ class Scheduler extends PluginAbstract
|
|||
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue