diff --git a/objects/Object.php b/objects/Object.php
index 180d09f678..ddf7734b83 100644
--- a/objects/Object.php
+++ b/objects/Object.php
@@ -107,13 +107,7 @@ abstract class ObjectYPT implements ObjectInterface
$res = sqlDAL::readSql($sql);
$fullData = sqlDAL::fetchAllAssoc($res);
sqlDAL::close($res);
- $rows = [];
- if ($res !== false) {
- foreach ($fullData as $row) {
- $rows[] = $row;
- }
- }
- return $rows;
+ return $fullData;
}
public static function getAllActive()
@@ -128,13 +122,7 @@ abstract class ObjectYPT implements ObjectInterface
$res = sqlDAL::readSql($sql);
$fullData = sqlDAL::fetchAllAssoc($res);
sqlDAL::close($res);
- $rows = [];
- if ($res !== false) {
- foreach ($fullData as $row) {
- $rows[] = $row;
- }
- }
- return $rows;
+ return $fullData;
}
public static function getTotal()
@@ -299,6 +287,7 @@ abstract class ObjectYPT implements ObjectInterface
_error_log("Save error, table " . static::getTableName() . " MySQL Error", AVideoLog::$ERROR);
return false;
}
+ //_error_log("Save ".static::getTableName().' '.json_encode($fieldsName));
$formats = '';
$values = [];
if (!empty($this->id)) {
@@ -475,6 +464,7 @@ abstract class ObjectYPT implements ObjectInterface
'ai_responses',
'ai_metatags_responses',
'ai_transcribe_responses',
+ 'ai_responses_json',
'playlists_schedules'
];
return in_array(static::getTableName(), $ignoreArray);
diff --git a/objects/functionExec.php b/objects/functionExec.php
new file mode 100644
index 0000000000..70c01c5564
--- /dev/null
+++ b/objects/functionExec.php
@@ -0,0 +1,390 @@
+&1', $output, $return_val);
+ if ($return_val !== 0) {
+ error_log('{"status":"error", "msg":' . json_encode($output) . ' ,"return_val":' . json_encode($return_val) . ', "where":"getDuration", "cmd":"' . $cmd . '"}');
+ // fix ffprobe
+ $duration = "EE:EE:EE";
+ } else {
+ preg_match("/([0-9]+:[0-9]+:[0-9]{2})/", $output[0], $match);
+ if (!empty($match[1])) {
+ $duration = $match[1];
+ } else {
+ error_log('{"status":"error", "msg":' . json_encode($output) . ' ,"match_not_found":' . json_encode($match) . ' ,"return_val":' . json_encode($return_val) . ', "where":"getDuration", "cmd":"' . $cmd . '"}');
+ $duration = "EE:EE:EE";
+ }
+ }
+ error_log("Duration found: {$duration}");
+ if ($duration !== 'EE:EE:EE') {
+ $getDurationFromFile[$file] = $duration;
+ }
+ return $duration;
+}
+
+function wget($url, $filename, $debug = false)
+{
+ if (empty($url) || $url == "php://input" || !isValidURL($url)) {
+ return false;
+ }
+ if ($lockfilename = wgetIsLocked($url)) {
+ if ($debug) {
+ _error_log("wget: ERROR the url is already downloading {$lockfilename} $url, $filename");
+ }
+ return false;
+ }
+ wgetLock($url);
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ $content = @file_get_contents($url);
+ if (!empty($content) && file_put_contents($filename, $content) > 100) {
+ wgetRemoveLock($url);
+ return true;
+ }
+ wgetRemoveLock($url);
+ return false;
+ }
+
+ $filename = escapeshellarg($filename);
+ $url = escapeshellarg($url);
+ $cmd = "wget --tries=1 {$url} -O {$filename} --no-check-certificate";
+ if ($debug) {
+ _error_log("wget Start ({$cmd}) ");
+ }
+ //echo $cmd;
+ exec($cmd);
+ wgetRemoveLock($url);
+ if (!file_exists($filename)) {
+ _error_log("wget: ERROR the url does not download $url, $filename");
+ return false;
+ }
+ if ($_SERVER['SCRIPT_NAME'] !== '/plugin/Live/m3u8.php' && empty(filesize($filename))) {
+ _error_log("wget: ERROR the url download but is empty $url, $filename");
+ return true;
+ }
+ return false;
+}
+
+function getDirSize($dir, $forceNew = false)
+{
+ global $_getDirSize;
+
+ if (!isset($_getDirSize)) {
+ $_getDirSize = [];
+ }
+ if (empty($forceNew) && isset($_getDirSize[$dir])) {
+ return $_getDirSize[$dir];
+ }
+
+ _error_log("getDirSize: start {$dir}");
+
+ if (isWindows()) {
+ $return = foldersize($dir);
+ $_getDirSize[$dir] = $return;
+ return $return;
+ } else {
+ $command = "du -sb {$dir}";
+ exec($command . " < /dev/null 2>&1", $output, $return_val);
+ if ($return_val !== 0) {
+ _error_log("getDirSize: ERROR ON Command {$command}");
+ $return = 0;
+ $_getDirSize[$dir] = $return;
+ return $return;
+ } else {
+ if (!empty($output[0])) {
+ preg_match("/^([0-9]+).*/", $output[0], $matches);
+ }
+ if (!empty($matches[1])) {
+ _error_log("getDirSize: found {$matches[1]} from - {$output[0]}");
+ $return = intval($matches[1]);
+ $_getDirSize[$dir] = $return;
+ return $return;
+ }
+
+ _error_log("getDirSize: ERROR on pregmatch {$output[0]}");
+ $return = 0;
+ $_getDirSize[$dir] = $return;
+ return $return;
+ }
+ }
+}
+
+function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile = '', $try = 0)
+{
+ $parts = explode('?', $fromFileLocation);
+ $localFileLock = getCacheDir() . 'convertVideoFileWithFFMPEG_' . md5($parts[0]) . ".lock";
+ $ageInSeconds = time() - @filemtime($localFileLock);
+ if ($ageInSeconds > 60) {
+ _error_log("convertVideoFileWithFFMPEG: age: {$ageInSeconds} too long without change, unlock it " . $fromFileLocation);
+ @unlink($localFileLock);
+ } elseif (file_exists($localFileLock)) {
+ _error_log("convertVideoFileWithFFMPEG: age: {$ageInSeconds} download from CDN There is a process running for " . $fromFileLocation);
+ 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') {
+ switch ($try) {
+ case 0:
+ $command = get_ffmpeg() . " -i \"{$fromFileLocation}\" -c:a libmp3lame \"{$toFileLocation}\"";
+ break;
+ default:
+ return false;
+ break;
+ }
+ } else {
+ if ($try === 0 && preg_match('/_offline\.mp4/', $toFileLocation)) {
+ $try = 'offline';
+ $fromFileLocationEscaped = "\"$fromFileLocation\"";
+ $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -crf 30 {$toFileLocationEscaped}";
+ } else {
+ switch ($try) {
+ case 0:
+ $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -c:v libx264 -preset veryfast -crf 23 -c:a aac -b:a 128k {$toFileLocationEscaped}";
+ break;
+ case 1:
+ $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -c copy {$toFileLocationEscaped}";
+ break;
+ case 2:
+ $command = get_ffmpeg() . " -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() . " -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;
+ }
+ $progressFileEscaped = escapeshellarg($progressFile);
+ $command .= " 1> {$progressFileEscaped} 2>&1";
+ $command = removeUserAgentIfNotURL($command);
+ _error_log("convertVideoFileWithFFMPEG try[{$try}]: " . $command . ' ' . json_encode(debug_backtrace()));
+ _session_write_close();
+ _mysql_close();
+ exec($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];
+}
+
+function rrmdirCommandLine($dir, $async = false)
+{
+ if (is_dir($dir)) {
+ $dir = escapeshellarg($dir);
+ if (isWindows()) {
+ $command = ('rd /s /q ' . $dir);
+ } else {
+ $command = ('rm -fR ' . $dir);
+ }
+
+ if ($async) {
+ return execAsync($command);
+ } else {
+ return exec($command);
+ }
+ }
+}
+
+function unzipDirectory($filename, $destination)
+{
+ // Set memory limit and execution time to avoid issues with large files
+ ini_set('memory_limit', '-1');
+ set_time_limit(0);
+
+ // Escape the input parameters to prevent command injection attacks
+ $filename = escapeshellarg($filename);
+ $destination = escapeshellarg($destination);
+
+ // Build the command for unzipping the file
+ $cmd = "unzip -q -o {$filename} -d {$destination} 2>&1";
+
+ // Log the command for debugging purposes
+ _error_log("unzipDirectory: {$cmd}");
+
+ // Execute the command and check the return value
+ exec($cmd, $output, $return_val);
+
+ if ($return_val !== 0) {
+ // If the unzip command fails, try using PHP's ZipArchive class as a fallback
+ if (class_exists('ZipArchive')) {
+ $zip = new ZipArchive();
+ if ($zip->open($filename) === true) {
+ $zip->extractTo($destination);
+ $zip->close();
+ _error_log("unzipDirectory: Success {$destination}");
+ } else {
+ _error_log("unzipDirectory: Error opening zip archive: {$filename}");
+ }
+ } else {
+ _error_log("unzipDirectory: Error: ZipArchive class is not available");
+ }
+ } else {
+ _error_log("unzipDirectory: Success {$destination}");
+ }
+
+ // Delete the original zip file
+ _error_log("unzipDirectory($filename) unlink line=" . __LINE__);
+ @unlink($filename);
+}
+
+function getPIDUsingPort($port)
+{
+ $port = intval($port);
+ if (empty($port)) {
+ return false;
+ }
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
+ $command = 'netstat -ano | findstr ' . $port;
+ exec($command, $output, $retval);
+ $pid = 0;
+ foreach ($output as $value) {
+ if (preg_match('/LISTENING[^0-9]+([0-9]+)/i', $value, $matches)) {
+ if (!empty($matches[1])) {
+ $pid = intval($matches[1]);
+ return $pid;
+ }
+ }
+ }
+ } else {
+ $command = 'lsof -n -i :' . $port . ' | grep LISTEN';
+ exec($command, $output, $retval);
+ $pid = 0;
+ foreach ($output as $value) {
+ if (preg_match('/[^ ] +([0-9]+).*/i', $value, $matches)) {
+ if (!empty($matches[1])) {
+ $pid = intval($matches[1]);
+ return $pid;
+ }
+ } elseif (preg_match('/lsof: not found/i', $value)) {
+ die('Please install lsof running this command: "sudo apt-get install lsof"');
+ }
+ }
+ }
+ return false;
+}
+
+function execAsync($command)
+{
+ //$command = escapeshellarg($command);
+ // If windows, else
+ if (isWindows()) {
+ //echo $command;
+ //$pid = system("start /min ".$command. " > NUL");
+ //$commandString = "start /B " . $command;
+ //pclose($pid = popen($commandString, "r"));
+ _error_log($command);
+ $pid = exec($command, $output, $retval);
+ _error_log('execAsync Win: ' . json_encode($output) . ' ' . $retval);
+ } else {
+ $newCommand = $command . " > /dev/null 2>&1 & echo $!; ";
+ _error_log('execAsync Linux: ' . $newCommand);
+ $pid = exec($newCommand);
+ }
+ return $pid;
+}
+
+function killProcess($pid)
+{
+ $pid = intval($pid);
+ if (empty($pid)) {
+ return false;
+ }
+ if (isWindows()) {
+ exec("taskkill /F /PID $pid");
+ } else {
+ exec("kill -9 $pid");
+ }
+ return true;
+}
diff --git a/objects/functions.php b/objects/functions.php
index be77dde86c..e6682c1e61 100644
--- a/objects/functions.php
+++ b/objects/functions.php
@@ -1896,48 +1896,6 @@ function decideMoveUploadedToVideos($tmp_name, $filename, $type = "video")
return $destinationFile;
}
-function unzipDirectory($filename, $destination)
-{
- // Set memory limit and execution time to avoid issues with large files
- ini_set('memory_limit', '-1');
- set_time_limit(0);
-
- // Escape the input parameters to prevent command injection attacks
- $filename = escapeshellarg($filename);
- $destination = escapeshellarg($destination);
-
- // Build the command for unzipping the file
- $cmd = "unzip -q -o {$filename} -d {$destination} 2>&1";
-
- // Log the command for debugging purposes
- _error_log("unzipDirectory: {$cmd}");
-
- // Execute the command and check the return value
- exec($cmd, $output, $return_val);
-
- if ($return_val !== 0) {
- // If the unzip command fails, try using PHP's ZipArchive class as a fallback
- if (class_exists('ZipArchive')) {
- $zip = new ZipArchive();
- if ($zip->open($filename) === true) {
- $zip->extractTo($destination);
- $zip->close();
- _error_log("unzipDirectory: Success {$destination}");
- } else {
- _error_log("unzipDirectory: Error opening zip archive: {$filename}");
- }
- } else {
- _error_log("unzipDirectory: Error: ZipArchive class is not available");
- }
- } else {
- _error_log("unzipDirectory: Success {$destination}");
- }
-
- // Delete the original zip file
- _error_log("unzipDirectory($filename) unlink line=".__LINE__);
- @unlink($filename);
-}
-
function make_path($path)
{
$created = false;
@@ -3485,23 +3443,6 @@ function rrmdir($dir)
}
}
-function rrmdirCommandLine($dir, $async = false)
-{
- if (is_dir($dir)) {
- $dir = escapeshellarg($dir);
- if (isWindows()) {
- $command = ('rd /s /q ' . $dir);
- } else {
- $command = ('rm -fR ' . $dir);
- }
-
- if ($async) {
- return execAsync($command);
- } else {
- return exec($command);
- }
- }
-}
/**
* You can now configure it on the configuration.php
@@ -4587,50 +4528,6 @@ function getUsageFromURL($url)
return (int) $result;
}
-function getDirSize($dir, $forceNew = false)
-{
- global $_getDirSize;
-
- if (!isset($_getDirSize)) {
- $_getDirSize = [];
- }
- if (empty($forceNew) && isset($_getDirSize[$dir])) {
- return $_getDirSize[$dir];
- }
-
- _error_log("getDirSize: start {$dir}");
-
- if (isWindows()) {
- $return = foldersize($dir);
- $_getDirSize[$dir] = $return;
- return $return;
- } else {
- $command = "du -sb {$dir}";
- exec($command . " < /dev/null 2>&1", $output, $return_val);
- if ($return_val !== 0) {
- _error_log("getDirSize: ERROR ON Command {$command}");
- $return = 0;
- $_getDirSize[$dir] = $return;
- return $return;
- } else {
- if (!empty($output[0])) {
- preg_match("/^([0-9]+).*/", $output[0], $matches);
- }
- if (!empty($matches[1])) {
- _error_log("getDirSize: found {$matches[1]} from - {$output[0]}");
- $return = intval($matches[1]);
- $_getDirSize[$dir] = $return;
- return $return;
- }
-
- _error_log("getDirSize: ERROR on pregmatch {$output[0]}");
- $return = 0;
- $_getDirSize[$dir] = $return;
- return $return;
- }
- }
-}
-
function foldersize($path)
{
$total_size = 0;
@@ -5784,48 +5681,6 @@ function reloadSearchVar()
}
}
-function wget($url, $filename, $debug = false)
-{
- if (empty($url) || $url == "php://input" || !isValidURL($url)) {
- return false;
- }
- if ($lockfilename = wgetIsLocked($url)) {
- if ($debug) {
- _error_log("wget: ERROR the url is already downloading {$lockfilename} $url, $filename");
- }
- return false;
- }
- wgetLock($url);
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $content = @file_get_contents($url);
- if (!empty($content) && file_put_contents($filename, $content) > 100) {
- wgetRemoveLock($url);
- return true;
- }
- wgetRemoveLock($url);
- return false;
- }
-
- $filename = escapeshellarg($filename);
- $url = escapeshellarg($url);
- $cmd = "wget --tries=1 {$url} -O {$filename} --no-check-certificate";
- if ($debug) {
- _error_log("wget Start ({$cmd}) ");
- }
- //echo $cmd;
- exec($cmd);
- wgetRemoveLock($url);
- if (!file_exists($filename)) {
- _error_log("wget: ERROR the url does not download $url, $filename");
- return false;
- }
- if ($_SERVER['SCRIPT_NAME'] !== '/plugin/Live/m3u8.php' && empty(filesize($filename))) {
- _error_log("wget: ERROR the url download but is empty $url, $filename");
- return true;
- }
- return false;
-}
-
/**
* Copy remote file over HTTP one small chunk at a time.
*
@@ -7250,73 +7105,7 @@ function get_ffprobe() {
return $ffprobe.$complement;
}
-function getDurationFromFile($file)
- {
- global $config, $getDurationFromFile;
- if (empty($file)) {
- return "EE:EE:EE";
- }
-
- if (!isset($getDurationFromFile)) {
- $getDurationFromFile = [];
- }
-
- if (!empty($getDurationFromFile[$file])) {
- // I need to check again because I am recreating the file on the AI
- //return $getDurationFromFile[$file];
- }
-
- $hls = str_replace(".zip", "/index.m3u8", $file);
- $file = str_replace(".zip", ".mp4", $file);
-
- // get movie duration HOURS:MM:SS.MICROSECONDS
- $videoFile = $file;
- if (!file_exists($videoFile)) {
- $file_headers = @get_headers($videoFile);
- if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
- error_log('getDurationFromFile try 1, File (' . $videoFile . ') Not Found');
- $videoFile = $hls;
- }
- }
- if (!file_exists($videoFile)) {
- $file_headers = @get_headers($videoFile);
- if (!$file_headers || $file_headers[0] == 'HTTP/1.1 404 Not Found') {
- error_log('getDurationFromFile try 2, File (' . $videoFile . ') Not Found');
- $videoFile = '';
- }
- }
- if (empty($videoFile)) {
- return "EE:EE:EE";
- }
- $videoFile = escapeshellarg($videoFile);
- /**
- * @var string $cmd
- */
- //$cmd = 'ffprobe -i ' . $file . ' -sexagesimal -show_entries format=duration -v quiet -of csv="p=0"';
- eval('$cmd=get_ffprobe()." -i {$videoFile} -sexagesimal -show_entries format=duration -v quiet -of csv=\\"p=0\\"";');
- $cmd = removeUserAgentIfNotURL($cmd);
- exec($cmd . ' 2>&1', $output, $return_val);
- if ($return_val !== 0) {
- error_log('{"status":"error", "msg":' . json_encode($output) . ' ,"return_val":' . json_encode($return_val) . ', "where":"getDuration", "cmd":"' . $cmd . '"}');
- // fix ffprobe
- $duration = "EE:EE:EE";
- } else {
- preg_match("/([0-9]+:[0-9]+:[0-9]{2})/", $output[0], $match);
- if (!empty($match[1])) {
- $duration = $match[1];
- } else {
- error_log('{"status":"error", "msg":' . json_encode($output) . ' ,"match_not_found":' . json_encode($match) . ' ,"return_val":' . json_encode($return_val) . ', "where":"getDuration", "cmd":"' . $cmd . '"}');
- $duration = "EE:EE:EE";
- }
- }
- error_log("Duration found: {$duration}");
- if ($duration !== 'EE:EE:EE') {
- $getDurationFromFile[$file] = $duration;
- }
- return $duration;
- }
-
-function removeUserAgentIfNotURL($cmd)
+ function removeUserAgentIfNotURL($cmd)
{
if (!preg_match('/ -i [\'"]?https?:/', $cmd)) {
$cmd = preg_replace('/-user_agent "[^"]+"/', '', $cmd);
@@ -7360,82 +7149,6 @@ function convertVideoToMP3FileIfNotExists($videos_id)
}
}
-function convertVideoFileWithFFMPEG($fromFileLocation, $toFileLocation, $logFile = '', $try = 0)
-{
- $parts = explode('?', $fromFileLocation);
- $localFileLock = getCacheDir() . 'convertVideoFileWithFFMPEG_' . md5($parts[0]) . ".lock";
- $ageInSeconds = time() - @filemtime($localFileLock);
- if ($ageInSeconds > 60) {
- _error_log("convertVideoFileWithFFMPEG: age: {$ageInSeconds} too long without change, unlock it " . $fromFileLocation);
- @unlink($localFileLock);
- } elseif (file_exists($localFileLock)) {
- _error_log("convertVideoFileWithFFMPEG: age: {$ageInSeconds} download from CDN There is a process running for " . $fromFileLocation);
- 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') {
- switch ($try) {
- case 0:
- $command = get_ffmpeg() . " -i \"{$fromFileLocation}\" -c:a libmp3lame \"{$toFileLocation}\"";
- break;
- default:
- return false;
- break;
- }
- } else {
- if ($try === 0 && preg_match('/_offline\.mp4/', $toFileLocation)) {
- $try = 'offline';
- $fromFileLocationEscaped = "\"$fromFileLocation\"";
- $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -crf 30 {$toFileLocationEscaped}";
- } else {
- switch ($try) {
- case 0:
- $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -c:v libx264 -preset veryfast -crf 23 -c:a aac -b:a 128k {$toFileLocationEscaped}";
- break;
- case 1:
- $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -c copy {$toFileLocationEscaped}";
- break;
- case 2:
- $command = get_ffmpeg() . " -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() . " -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;
- }
- $progressFileEscaped = escapeshellarg($progressFile);
- $command .= " 1> {$progressFileEscaped} 2>&1";
- $command = removeUserAgentIfNotURL($command);
- _error_log("convertVideoFileWithFFMPEG try[{$try}]: " . $command . ' '.json_encode(debug_backtrace()));
- _session_write_close();
- _mysql_close();
- exec($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];
-}
-
function m3u8ToMP4($input)
{
$videosDir = getVideosDir();
@@ -7806,81 +7519,11 @@ function sendSocketMessageToNone($msg, $callbackJSFunction = "")
return sendSocketMessage($msg, $callbackJSFunction, -1);
}
-function execAsync($command)
-{
- //$command = escapeshellarg($command);
- // If windows, else
- if (isWindows()) {
- //echo $command;
- //$pid = system("start /min ".$command. " > NUL");
- //$commandString = "start /B " . $command;
- //pclose($pid = popen($commandString, "r"));
- _error_log($command);
- $pid = exec($command, $output, $retval);
- _error_log('execAsync Win: ' . json_encode($output) . ' ' . $retval);
- } else {
- $newCommand = $command . " > /dev/null 2>&1 & echo $!; ";
- _error_log('execAsync Linux: ' . $newCommand);
- $pid = exec($newCommand);
- }
- return $pid;
-}
-
-function killProcess($pid)
-{
- $pid = intval($pid);
- if (empty($pid)) {
- return false;
- }
- if (isWindows()) {
- exec("taskkill /F /PID $pid");
- } else {
- exec("kill -9 $pid");
- }
- return true;
-}
-
function isWindows()
{
return strtoupper(substr(PHP_OS, 0, 3)) === 'WIN';
}
-function getPIDUsingPort($port)
-{
- $port = intval($port);
- if (empty($port)) {
- return false;
- }
- if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
- $command = 'netstat -ano | findstr ' . $port;
- exec($command, $output, $retval);
- $pid = 0;
- foreach ($output as $value) {
- if (preg_match('/LISTENING[^0-9]+([0-9]+)/i', $value, $matches)) {
- if (!empty($matches[1])) {
- $pid = intval($matches[1]);
- return $pid;
- }
- }
- }
- } else {
- $command = 'lsof -n -i :' . $port . ' | grep LISTEN';
- exec($command, $output, $retval);
- $pid = 0;
- foreach ($output as $value) {
- if (preg_match('/[^ ] +([0-9]+).*/i', $value, $matches)) {
- if (!empty($matches[1])) {
- $pid = intval($matches[1]);
- return $pid;
- }
- } elseif (preg_match('/lsof: not found/i', $value)) {
- die('Please install lsof running this command: "sudo apt-get install lsof"');
- }
- }
- }
- return false;
-}
-
function isURL200($url, $forceRecheck = false)
{
global $_isURL200;
@@ -10572,4 +10215,5 @@ function checkFileModified($filePath) {
require_once __DIR__.'/functionSecurity.php';
require_once __DIR__.'/functionMySQL.php';
require_once __DIR__.'/functionDocker.php';
-require_once __DIR__.'/functionImages.php';
\ No newline at end of file
+require_once __DIR__.'/functionImages.php';
+require_once __DIR__.'/functionExec.php';
\ No newline at end of file
diff --git a/objects/video.php b/objects/video.php
index 98a37bfa72..26045e1a5d 100644
--- a/objects/video.php
+++ b/objects/video.php
@@ -4147,6 +4147,7 @@ if (!class_exists('Video')) {
return $__getPaths[$videoFilename];
}
$cleanVideoFilename = self::getCleanFilenameFromFile($videoFilename);
+ //var_dump('--'.$cleanVideoFilename, '++'.$videoFilename);
$videosDir = self::getStoragePath();
$path = addLastSlash("{$videosDir}{$cleanVideoFilename}");
@@ -4193,6 +4194,7 @@ if (!class_exists('Video')) {
if (!empty($parts[1]) && $parts[1] == 'index.m3u8') {
$videoFilename = $parts[1];
}
+ //var_dump('--'.$videoFilename, $paths);
return "{$paths['url']}{$videoFilename}";
}
@@ -4336,6 +4338,10 @@ if (!class_exists('Video')) {
$path_parts = pathinfo($filename);
if (!empty($path_parts['extension'])) {
if ($path_parts['extension'] == 'vtt' || $path_parts['extension'] == 'srt') {
+ $search = ['.Chapters'];
+ foreach ($search as $value) {
+ $path_parts['filename'] = str_ireplace($value, '', $path_parts['filename']);
+ }
$p = explode('.', $path_parts['filename']);
if (count($p) > 1) {
array_pop($p);
diff --git a/plugin/AI/AI.php b/plugin/AI/AI.php
index 2f3c6a4d6a..809a5f4652 100644
--- a/plugin/AI/AI.php
+++ b/plugin/AI/AI.php
@@ -5,11 +5,12 @@ require_once $global['systemRootPath'] . 'plugin/Plugin.abstract.php';
require_once $global['systemRootPath'] . 'plugin/AI/Objects/Ai_responses.php';
require_once $global['systemRootPath'] . 'plugin/AI/Objects/Ai_metatags_responses.php';
require_once $global['systemRootPath'] . 'plugin/AI/Objects/Ai_transcribe_responses.php';
+require_once $global['systemRootPath'] . 'plugin/AI/Objects/Ai_responses_json.php';
+require_once $global['systemRootPath'] . 'plugin/AI/Objects/Ai_scheduler.php';
+class AI extends PluginAbstract
+{
-
-class AI extends PluginAbstract {
-
static $typeTranslation = 'translation';
static $typeTranscription = 'transcription';
static $typeBasic = 'basic';
@@ -47,41 +48,48 @@ class AI extends PluginAbstract {
'uk' => 'Ukrainian',
'vi' => 'Vietnamese'
];
-
+
static $isTest = 0;
static $url = 'https://ai.ypt.me/';
static $url_test = 'http://192.168.0.2:81/AI/';
- static function getMetadataURL(){
+ static function getMetadataURL()
+ {
self::$isTest = ($_SERVER["SERVER_NAME"] == "vlu.me");
- return self::$isTest?self::$url_test:self::$url;
+ return self::$isTest ? self::$url_test : self::$url;
}
- static function getPricesURL(){
- return self::$url.'prices.json.php';
+ static function getPricesURL()
+ {
+ return self::$url . 'prices.json.php';
}
- public function getDescription() {
+ public function getDescription()
+ {
$desc = "Optimize video visibility with AI-driven meta-tag suggestions and automatic transcription for enhanced SEO performance.";
$help = "
Help";
-
+
//$desc .= $this->isReadyLabel(array('YPTWallet'));
- return $desc.$help;
+ return $desc . $help;
}
- public function getName() {
+ public function getName()
+ {
return "AI";
}
- public function getUUID() {
+ public function getUUID()
+ {
return "AI-5ee8405eaaa16";
}
- public function getPluginVersion() {
- return "4.0";
+ public function getPluginVersion()
+ {
+ return "6.0";
}
- public function getEmptyDataObject() {
+ public function getEmptyDataObject()
+ {
$obj = new stdClass();
$obj->AccessToken = "";
/*
@@ -102,7 +110,8 @@ class AI extends PluginAbstract {
return $obj;
}
- static function getVideoTranslationMetadata($videos_id, $lang, $langName){
+ static function getVideoShortsMetadata($videos_id)
+ {
global $global;
$obj = new stdClass();
$obj->error = true;
@@ -114,7 +123,42 @@ class AI extends PluginAbstract {
return $obj;
}
- if(!Video::canEdit($videos_id)){
+ if (!Video::canEdit($videos_id)) {
+ $obj->msg = 'you cannot edit this video';
+ return $obj;
+ }
+
+ $trascription = Ai_responses::getTranscriptionVtt($videos_id);
+
+ if (empty($trascription)) {
+ $obj->msg = 'empty transcription';
+ return $obj;
+ }
+
+ //var_dump($paths);exit;
+ $obj->response = array(
+ 'type' => AI::$typeShorts,
+ 'transcription' => $trascription,
+ );
+
+ $obj->error = false;
+ return $obj;
+ }
+
+ static function getVideoTranslationMetadata($videos_id, $lang, $langName)
+ {
+ global $global;
+ $obj = new stdClass();
+ $obj->error = true;
+ $obj->msg = '';
+ $obj->response = array();
+
+ if (empty($videos_id)) {
+ $obj->msg = 'empty videos id';
+ return $obj;
+ }
+
+ if (!Video::canEdit($videos_id)) {
$obj->msg = 'you cannot edit this video';
return $obj;
}
@@ -122,12 +166,12 @@ class AI extends PluginAbstract {
$video = new Video('', '', $videos_id);
$filename = $video->getFilename();
- if(AVideoPlugin::isEnabledByName('SubtitleSwitcher')){
+ if (AVideoPlugin::isEnabledByName('SubtitleSwitcher')) {
SubtitleSwitcher::transcribe($videos_id, false);
}
$firstVTTPath = AI::getFirstVTTFile($videos_id);
- $vttURL = str_replace($global['systemRootPath'], $global['webSiteRootURL'],$firstVTTPath);
+ $vttURL = str_replace($global['systemRootPath'], $global['webSiteRootURL'], $firstVTTPath);
//var_dump($paths);exit;
$obj->response = array(
@@ -142,7 +186,8 @@ class AI extends PluginAbstract {
return $obj;
}
- static function getVideoBasicMetadata($videos_id){
+ static function getVideoBasicMetadata($videos_id)
+ {
global $global;
$obj = new stdClass();
$obj->error = true;
@@ -154,7 +199,7 @@ class AI extends PluginAbstract {
return $obj;
}
- if(!Video::canEdit($videos_id)){
+ if (!Video::canEdit($videos_id)) {
$obj->msg = 'you cannot edit this video';
return $obj;
}
@@ -162,13 +207,13 @@ class AI extends PluginAbstract {
$video = new Video('', '', $videos_id);
$filename = $video->getFilename();
- if(AVideoPlugin::isEnabledByName('SubtitleSwitcher')){
+ if (AVideoPlugin::isEnabledByName('SubtitleSwitcher')) {
SubtitleSwitcher::transcribe($videos_id, false);
}
/*
*/
$firstVTTPath = AI::getFirstVTTFile($videos_id);
- $vttURL = str_replace(getVideosDir(), $global['webSiteRootURL'],$firstVTTPath);
+ $vttURL = str_replace(getVideosDir(), $global['webSiteRootURL'], $firstVTTPath);
//var_dump($paths);exit;
$obj->response = array(
'type' => AI::$typeBasic,
@@ -185,7 +230,8 @@ class AI extends PluginAbstract {
return $obj;
}
- static function getVideoTranscriptionMetadata($videos_id, $lang){
+ static function getVideoTranscriptionMetadata($videos_id, $lang)
+ {
$obj = new stdClass();
$obj->error = true;
$obj->msg = '';
@@ -196,7 +242,7 @@ class AI extends PluginAbstract {
return $obj;
}
- if(!Video::canEdit($videos_id)){
+ if (!Video::canEdit($videos_id)) {
$obj->msg = 'you cannot edit this video';
return $obj;
}
@@ -205,7 +251,7 @@ class AI extends PluginAbstract {
$mp3 = false;
$mp3s = self::getLowerMP3($videos_id);
$fsize = 0;
- if($mp3s['isValid']){
+ if ($mp3s['isValid']) {
$mp3 = $mp3s['lower']['paths']['url'];
$fsize = filesize($mp3s['lower']['paths']['path']);
}
@@ -225,7 +271,8 @@ class AI extends PluginAbstract {
return $obj;
}
- static function getTokenForVideo($videos_id, $ai_responses_id, $param){
+ static function getTokenForVideo($videos_id, $ai_responses_id, $param)
+ {
global $global;
$obj = new stdClass();
$obj->videos_id = $videos_id;
@@ -237,47 +284,51 @@ class AI extends PluginAbstract {
return encryptString(_json_encode($obj));
}
-
- static function getTokenFromRequest(){
- if(empty($_REQUEST['token'])){
+ static function getTokenFromRequest()
+ {
+
+ if (empty($_REQUEST['token'])) {
return false;
}
$string = decryptString($_REQUEST['token']);
-
- if(empty($string)){
+
+ if (empty($string)) {
return false;
}
$json = _json_decode($string);
- if(empty($json)){
+ if (empty($json)) {
return false;
}
-
+
return $json;
}
- static function getMP3Path($videos_id){
+ static function getMP3Path($videos_id)
+ {
$convert = convertVideoToMP3FileIfNotExists($videos_id);
- if(empty($convert) || empty($convert['url'])){
+ if (empty($convert) || empty($convert['url'])) {
return false;
}
return $convert;
}
- static function getMP3LowerPath($videos_id){
+ static function getMP3LowerPath($videos_id)
+ {
$convert = self::getMP3Path($videos_id);
- if(empty($convert) || empty($convert['url'])){
+ if (empty($convert) || empty($convert['url'])) {
return false;
}
$convert['path'] = str_replace('.mp3', '_Low.mp3', $convert['path']);
$convert['url'] = str_replace('.mp3', '_Low.mp3', $convert['url']);
return $convert;
}
-
- static function getMP3RegularAndLower($videos_id){
+
+ static function getMP3RegularAndLower($videos_id)
+ {
$arrayRegular = array(
'paths' => false,
'duration' => false,
@@ -292,7 +343,7 @@ class AI extends PluginAbstract {
);
$paths = self::getMP3Path($videos_id);
- if(!empty($paths)){
+ if (!empty($paths)) {
$duration = getDurationFromFile($paths['path']);
$durationInSeconds = durationToSeconds($duration);
$video = new Video('', '', $videos_id);
@@ -306,7 +357,7 @@ class AI extends PluginAbstract {
'isValid' => false,
'msg' => "Length does not match (Video/MP3) video = {$videoDuration} seconds MP3 = $durationInSeconds seconds",
);
- return $response;
+ return $response;
}
$arrayRegular = array(
@@ -315,9 +366,9 @@ class AI extends PluginAbstract {
'durationInSeconds' => $durationInSeconds,
'isValid' => !empty($durationInSeconds),
);
-
- $pathsLower = self::getMP3LowerPath($videos_id);
- if(!empty($pathsLower )){
+
+ $pathsLower = self::getMP3LowerPath($videos_id);
+ if (!empty($pathsLower)) {
$duration = getDurationFromFile($pathsLower['path']);
$durationInSeconds = durationToSeconds($duration);
$arrayLower = array(
@@ -326,24 +377,24 @@ class AI extends PluginAbstract {
'durationInSeconds' => $durationInSeconds,
'isValid' => !empty($durationInSeconds),
);
-
- $pathsLower = self::getMP3LowerPath($videos_id);
+
+ $pathsLower = self::getMP3LowerPath($videos_id);
}
}
$msg = '';
$isValid = false;
- if($arrayRegular['isValid'] && $arrayLower['isValid']){
+ if ($arrayRegular['isValid'] && $arrayLower['isValid']) {
$diff = abs($arrayRegular['durationInSeconds'] - $arrayLower['durationInSeconds']);
if ($diff <= 2) {
$isValid = true;
- }else{
+ } else {
$msg = "durationInSeconds are not the same regular={$arrayRegular['durationInSeconds']} lower={$arrayLower['durationInSeconds']}";
}
- }else{
- if(!$arrayRegular['isValid']){
+ } else {
+ if (!$arrayRegular['isValid']) {
$msg = 'Regular MP3 is invalid';
}
- if(!$arrayRegular['isValid']){
+ if (!$arrayRegular['isValid']) {
$msg .= ' Lower MP3 is invalid';
}
}
@@ -357,33 +408,35 @@ class AI extends PluginAbstract {
return $response;
}
- static function getLowerMP3($videos_id, $try = 0){
+ static function getLowerMP3($videos_id, $try = 0)
+ {
$mp3s = self::getMP3RegularAndLower($videos_id);
- if($mp3s['regular']['isValid']){
- if(!$mp3s['isValid']){
- ini_set('max_execution_time', 300);
+ if ($mp3s['regular']['isValid']) {
+ if (!$mp3s['isValid']) {
+ ini_set('max_execution_time', 300);
set_time_limit(300);
- if(file_exists($mp3s['lower']['paths']['path'])){
+ if (file_exists($mp3s['lower']['paths']['path'])) {
unlink($mp3s['lower']['paths']['path']);
}
$fromFileLocationEscaped = escapeshellarg($mp3s['regular']['paths']['path']);
$toFileLocationEscaped = escapeshellarg($mp3s['lower']['paths']['path']);
- $command = get_ffmpeg()." -i {$fromFileLocationEscaped} -ar 16000 -ac 1 -b:a 16k {$toFileLocationEscaped}";
+ $command = get_ffmpeg() . " -i {$fromFileLocationEscaped} -ar 16000 -ac 1 -b:a 16k {$toFileLocationEscaped}";
$command = removeUserAgentIfNotURL($command);
exec($command, $output);
- _error_log('getLowerMP3: '.json_encode($output));
+ _error_log('getLowerMP3: ' . json_encode($output));
return self::getMP3RegularAndLower($videos_id);
}
- }else{
+ } else {
return $mp3s;
}
return $mp3s;
}
-
-
- public function getPluginMenu() {
+
+
+ public function getPluginMenu()
+ {
global $global;
- return '';
+ return '';
}
public function getVideosManagerListButton()
@@ -398,18 +451,19 @@ class AI extends PluginAbstract {
return $btn;
}
- public static function getTagTypeId() {
+ public static function getTagTypeId()
+ {
$VideoTags = AVideoPlugin::isEnabledByName('VideoTags');
- if(empty($VideoTags)){
+ if (empty($VideoTags)) {
return false;
- }
+ }
$typeName = 'Keywords';
$row = TagsTypes::getFromName($typeName);
- if(empty($row)){
+ if (empty($row)) {
$tagType = new TagsTypes(0);
- $tagType->setName($typeName );
+ $tagType->setName($typeName);
return $tagType->save();
- }else{
+ } else {
return $row['id'];
}
}
@@ -424,16 +478,17 @@ class AI extends PluginAbstract {
$global['lastQuery'] = $sql;
sqlDAL::writeSql($sql);
}
-
+
return true;
}
- static function getVTTLanguageCodes($videos_id) {
+ static function getVTTLanguageCodes($videos_id)
+ {
$video = new Video('', '', $videos_id);
- $dir = getVideosDir().DIRECTORY_SEPARATOR.$video->getFilename();
+ $dir = getVideosDir() . DIRECTORY_SEPARATOR . $video->getFilename();
$languageCodes = [];
$filePattern = '/video_[\w\d]+\.([\w\d_]+)\.vtt$/';
-
+
if (is_dir($dir) && ($handle = opendir($dir))) {
while (false !== ($entry = readdir($handle))) {
if (is_file($dir . '/' . $entry) && preg_match($filePattern, $entry, $matches)) {
@@ -442,46 +497,98 @@ class AI extends PluginAbstract {
}
closedir($handle);
}
-
+
return array_unique($languageCodes); // Return unique language codes
}
- public function getFooterCode() {
+ public function getFooterCode()
+ {
global $global;
include $global['systemRootPath'] . 'plugin/AI/footer.php';
}
- static function getVTTFiles($videos_id) {
+ static function getVTTFiles($videos_id)
+ {
$video = new Video('', '', $videos_id);
$filename = $video->getFilename();
$dir = getVideosDir() . "{$filename}/";
-
+
// Find all .vtt files in the directory
$vttFiles = glob($dir . "*.vtt");
-
+
// Return the array of .vtt files
return $vttFiles;
}
-
- static function getFirstVTTFile($videos_id){
+
+ static function getFirstVTTFile($videos_id)
+ {
$vttFiles = self::getVTTFiles($videos_id);
- if(empty($vttFiles)){
+ if (empty($vttFiles)) {
return false;
}
return $vttFiles[0];
}
- static function getProgressBarHTML($classname, $text){
+ static function getProgressBarHTML($classname, $text)
+ {
return '
-