diff --git a/objects/functions.php b/objects/functions.php index 1c2c77cb1..774df3410 100644 --- a/objects/functions.php +++ b/objects/functions.php @@ -1,7033 +1,7038 @@ 0 && $upload_max < $max_size) { $max_size = $upload_max; } } return $max_size; } function parse_size($size) { $unit = preg_replace('/[^bkmgtpezy]/i', '', $size); // Remove the non-unit characters from the size. $size = preg_replace('/[^0-9\.]/', '', $size); // Remove the non-numeric characters from the size. if ($unit) { // Find the position of the unit in the ordered string which is the power of magnitude to multiply a kilobyte by. return round($size * pow(1024, stripos('bkmgtpezy', $unit[0]))); } else { return round($size); } } function humanFileSize($size, $unit = "") { if ((!$unit && $size >= 1 << 30) || $unit == "GB") { return number_format($size / (1 << 30), 2) . "GB"; } if ((!$unit && $size >= 1 << 20) || $unit == "MB") { return number_format($size / (1 << 20), 2) . "MB"; } if ((!$unit && $size >= 1 << 10) || $unit == "KB") { return number_format($size / (1 << 10), 2) . "KB"; } return number_format($size) . " bytes"; } function get_max_file_size() { return humanFileSize(file_upload_max_size()); } function humanTiming($time, $precision = 0, $useDatabaseTime = true) { $time = secondsIntervalFromNow($time, $useDatabaseTime); return secondsToHumanTiming($time, $precision); } /** * * @param type $time * @param type $precision * @param type $useDatabaseTime good if you are checking the created time * @return type */ function humanTimingAgo($time, $precision = 0, $useDatabaseTime = true) { $time = secondsIntervalFromNow($time, $useDatabaseTime); if (empty($time)) { return __("Now"); } return secondsToHumanTiming($time, $precision) . " " . __("ago"); } function humanTimingAfterwards($time, $precision = 0, $useDatabaseTime = true) { $time = secondsIntervalFromNow($time, $useDatabaseTime); if (empty($time)) { return __("Now"); } return __('Coming in') . ' ' . secondsToHumanTiming($time, $precision); } function secondsToHumanTiming($time, $precision = 0) { if (empty($time)) { return __("Now"); } $time = ($time < 0) ? $time * -1 : $time; $time = ($time < 1) ? 1 : $time; $tokens = array( 31536000 => 'year', 2592000 => 'month', 604800 => 'week', 86400 => 'day', 3600 => 'hour', 60 => 'minute', 1 => 'second', ); /** * For detection propouse only */ __('year'); __('month'); __('week'); __('day'); __('hour'); __('minute'); __('second'); __('years'); __('months'); __('weeks'); __('days'); __('hours'); __('minutes'); __('seconds'); foreach ($tokens as $unit => $text) { if ($time < $unit) { continue; } $numberOfUnits = floor($time / $unit); if ($numberOfUnits > 1) { $text = __($text . "s"); } else { $text = __($text); } if ($precision) { $rest = $time % $unit; if ($rest) { $text .= ' ' . secondsToHumanTiming($rest, $precision - 1); } } return $numberOfUnits . ' ' . $text; } } function checkVideosDir() { $dir = "../videos"; if (file_exists($dir)) { return is_writable($dir); } return mkdir($dir); } function isApache() { return (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') !== false); } function isPHP($version = "'7.0.0'") { return (version_compare(PHP_VERSION, $version) >= 0); } function modEnabled($mod_name) { if (!function_exists('apache_get_modules')) { ob_start(); phpinfo(INFO_MODULES); $contents = ob_get_contents(); ob_end_clean(); return (strpos($contents, 'mod_' . $mod_name) !== false); } return in_array('mod_' . $mod_name, apache_get_modules()); } function modRewriteEnabled() { return modEnabled("rewrite"); } function modAliasEnabled() { return modEnabled("alias"); } function isFFMPEG() { return trim(shell_exec('which ffmpeg')); } function isUnzip() { return trim(shell_exec('which unzip')); } function isExifToo() { return trim(shell_exec('which exiftool')); } function getPathToApplication() { return str_replace("install/index.php", "", $_SERVER["SCRIPT_FILENAME"]); } function getURLToApplication() { $url = (isset($_SERVER['HTTPS']) ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; $url = explode("install/index.php", $url); return $url[0]; } //max_execution_time = 7200 function check_max_execution_time() { $max_size = ini_get('max_execution_time'); $recomended_size = 7200; return ($recomended_size <= $max_size); } //post_max_size = 100M function check_post_max_size() { $max_size = parse_size(ini_get('post_max_size')); $recomended_size = parse_size('100M'); return ($recomended_size <= $max_size); } //upload_max_filesize = 100M function check_upload_max_filesize() { $max_size = parse_size(ini_get('upload_max_filesize')); $recomended_size = parse_size('100M'); return ($recomended_size <= $max_size); } //memory_limit = 100M function check_memory_limit() { $max_size = parse_size(ini_get('memory_limit')); $recomended_size = parse_size('512M'); return ($recomended_size <= $max_size); } function check_mysqlnd() { return function_exists('mysqli_fetch_all'); } function base64DataToImage($imgBase64) { $img = $imgBase64; $img = str_replace('data:image/png;base64,', '', $img); $img = str_replace(' ', '+', $img); return base64_decode($img); } function getRealIpAddr() { if (!empty($_SERVER['HTTP_CLIENT_IP'])) { //check ip from share internet $ip = $_SERVER['HTTP_CLIENT_IP']; } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) { //to check ip is pass from proxy $ip = $_SERVER['HTTP_X_FORWARDED_FOR']; } elseif (!empty($_SERVER['REMOTE_ADDR'])) { $ip = $_SERVER['REMOTE_ADDR']; } else { $ip = "127.0.0.1"; } return $ip; } function cleanString($text) { $utf8 = array( '/[áàâãªä]/u' => 'a', '/[ÁÀÂÃÄ]/u' => 'A', '/[ÍÌÎÏ]/u' => 'I', '/[íìîï]/u' => 'i', '/[éèêë]/u' => 'e', '/[ÉÈÊË]/u' => 'E', '/[óòôõºö]/u' => 'o', '/[ÓÒÔÕÖ]/u' => 'O', '/[úùûü]/u' => 'u', '/[ÚÙÛÜ]/u' => 'U', '/ç/' => 'c', '/Ç/' => 'C', '/ñ/' => 'n', '/Ñ/' => 'N', '/–/' => '-', // UTF-8 hyphen to 'normal' hyphen '/[’‘‹›‚]/u' => ' ', // Literally a single quote '/[“”«»„]/u' => ' ', // Double quote '/ /' => ' ', // nonbreaking space (equiv. to 0x160) '/Є/' => 'YE', '/І/' => 'I', '/Ѓ/' => 'G', '/і/' => 'i', '/№/' => '#', '/є/' => 'ye', '/ѓ/' => 'g', '/А/' => 'A', '/Б/' => 'B', '/В/' => 'V', '/Г/' => 'G', '/Д/' => 'D', '/Е/' => 'E', '/Ё/' => 'YO', '/Ж/' => 'ZH', '/З/' => 'Z', '/И/' => 'I', '/Й/' => 'J', '/К/' => 'K', '/Л/' => 'L', '/М/' => 'M', '/Н/' => 'N', '/О/' => 'O', '/П/' => 'P', '/Р/' => 'R', '/С/' => 'S', '/Т/' => 'T', '/У/' => 'U', '/Ф/' => 'F', '/Х/' => 'H', '/Ц/' => 'C', '/Ч/' => 'CH', '/Ш/' => 'SH', '/Щ/' => 'SHH', '/Ъ/' => '', '/Ы/' => 'Y', '/Ь/' => '', '/Э/' => 'E', '/Ю/' => 'YU', '/Я/' => 'YA', '/а/' => 'a', '/б/' => 'b', '/в/' => 'v', '/г/' => 'g', '/д/' => 'd', '/е/' => 'e', '/ё/' => 'yo', '/ж/' => 'zh', '/з/' => 'z', '/и/' => 'i', '/й/' => 'j', '/к/' => 'k', '/л/' => 'l', '/м/' => 'm', '/н/' => 'n', '/о/' => 'o', '/п/' => 'p', '/р/' => 'r', '/с/' => 's', '/т/' => 't', '/у/' => 'u', '/ф/' => 'f', '/х/' => 'h', '/ц/' => 'c', '/ч/' => 'ch', '/ш/' => 'sh', '/щ/' => 'shh', '/ъ/' => '', '/ы/' => 'y', '/ь/' => '', '/э/' => 'e', '/ю/' => 'yu', '/я/' => 'ya', '/—/' => '-', '/«/' => '', '/»/' => '', '/…/' => '' ); return preg_replace(array_keys($utf8), array_values($utf8), $text); } function cleanURLName($name) { $name = preg_replace('/[!#$&\'()*+,\\/:;=?@[\\]%" ]+/', '-', trim(strtolower(cleanString($name)))); return trim(preg_replace('/[\x00-\x1F\x7F]/u', '', $name), "-"); } /** * @brief return true if running in CLI, false otherwise * if is set $_GET['ignoreCommandLineInterface'] will return false * @return boolean */ function isCommandLineInterface() { return (empty($_GET['ignoreCommandLineInterface']) && php_sapi_name() === 'cli'); } /** * @brief show status message as text (CLI) or JSON-encoded array (web) * * @param array $statusarray associative array with type/message pairs * @return string */ function status($statusarray) { if (isCommandLineInterface()) { foreach ($statusarray as $status => $message) { echo $status . ":" . $message . "\n"; } } else { echo json_encode(array_map(function ($text) { return nl2br($text); }, $statusarray)); } } /** * @brief show status message and die * * @param array $statusarray associative array with type/message pairs */ function croak($statusarray) { status($statusarray); die; } function getSecondsTotalVideosLength() { $configFile = dirname(__FILE__) . '/../videos/configuration.php'; require_once $configFile; global $global; if (!User::isLogged()) { return 0; } $sql = "SELECT * FROM videos v "; $formats = ""; $values = array(); if (!User::isAdmin()) { $id = User::getId(); $sql .= " WHERE users_id = ? "; $formats = "i"; $values = array($id); } $res = sqlDAL::readSql($sql, $formats, $values); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $seconds = 0; foreach ($fullData as $row) { $seconds += parseDurationToSeconds($row['duration']); } return $seconds; } function getMinutesTotalVideosLength() { $seconds = getSecondsTotalVideosLength(); return floor($seconds / 60); } function secondsToVideoTime($seconds) { if (!is_numeric($seconds)) { return $seconds; } $seconds = round($seconds); $hours = floor($seconds / 3600); $mins = floor($seconds / 60 % 60); $secs = floor($seconds % 60); return sprintf('%02d:%02d:%02d', $hours, $mins, $secs); } function parseSecondsToDuration($seconds) { return secondsToVideoTime($seconds); } function parseDurationToSeconds($str) { if (is_numeric($str)) { return intval($str); } $durationParts = explode(":", $str); if (empty($durationParts[1]) || $durationParts[0] == "EE") { return 0; } if (empty($durationParts[2])) { $durationParts[2] = 0; } $minutes = intval(($durationParts[0]) * 60) + intval($durationParts[1]); return intval($durationParts[2]) + ($minutes * 60); } function durationToSeconds($str) { return parseDurationToSeconds($str); } function secondsToDuration($seconds) { return parseSecondsToDuration($seconds); } /** * * @global type $global * @param type $mail * call it before send mail to let AVideo decide the method */ function setSiteSendMessage(&$mail) { global $global; if (empty($_POST["comment"])) { $_POST["comment"] = ""; } require_once $global['systemRootPath'] . 'objects/configuration.php'; $config = new Configuration(); $mail->CharSet = 'UTF-8'; if ($config->getSmtp()) { _error_log("Sending SMTP Email"); $mail->CharSet = 'UTF-8'; $mail->IsSMTP(); // enable SMTP if (!empty($_POST) && $_POST["comment"] == "Teste of comment" && User::isAdmin()) { $mail->SMTPDebug = 3; $mail->Debugoutput = function ($str, $level) { _error_log("SMTP ERROR $level; message: $str", AVideoLog::$ERROR); }; } $mail->SMTPOptions = array( 'ssl' => array( 'verify_peer' => false, 'verify_peer_name' => false, 'allow_self_signed' => true ) ); $mail->SMTPAuth = $config->getSmtpAuth(); // authentication enabled $mail->SMTPSecure = $config->getSmtpSecure(); // secure transfer enabled REQUIRED for Gmail $mail->Host = $config->getSmtpHost(); $mail->Port = $config->getSmtpPort(); $mail->Username = $config->getSmtpUsername(); $mail->Password = $config->getSmtpPassword(); //_error_log(print_r($config, true)); } else { _error_log("Sending SendMail Email"); $mail->isSendmail(); } } function array_iunique($array) { return array_intersect_key($array, array_unique(array_map("strtolower", $array))); } function partition(array $list, $totalItens) { $listlen = count($list); _error_log("partition: listlen={$listlen} totalItens={$totalItens}"); $p = ceil($listlen / $totalItens); $partlen = floor($listlen / $p); $partition = array(); $mark = 0; for ($index = 0; $index < $p; $index++) { $partition[$index] = array_slice($list, $mark, $totalItens); $mark += $totalItens; } return $partition; } function sendSiteEmail($to, $subject, $message) { global $advancedCustom; if (empty($to)) { return false; } if (!is_array($to)) { $to = array($to); } if (empty($advancedCustom)) { $advancedCustom = AVideoPlugin::loadPlugin("CustomizeAdvanced"); } $subject = UTF8encode($subject); $message = UTF8encode($message); $message = createEmailMessageFromTemplate($message); _error_log("sendSiteEmail [" . count($to) . "] {$subject}"); global $config, $global; //require_once $global['systemRootPath'] . 'objects/include_phpmailer.php'; $contactEmail = $config->getContactEmail(); $webSiteTitle = $config->getWebSiteTitle(); try { if (!is_array($to)) { $mail = new \PHPMailer\PHPMailer\PHPMailer; setSiteSendMessage($mail); $mail->setFrom($contactEmail, $webSiteTitle); $mail->Subject = $subject . " - " . $webSiteTitle; $mail->msgHTML($message); $mail->addAddress($to); $resp = $mail->send(); if (!$resp) { _error_log("sendSiteEmail Error Info: {$mail->ErrorInfo}"); } else { _error_log("sendSiteEmail Success Info: $subject " . json_encode($to)); } } else { $size = intval(@$advancedCustom->splitBulkEmailSend); if (empty($size)) { $size = 90; } $to = array_iunique($to); $pieces = partition($to, $size); foreach ($pieces as $piece) { $mail = new \PHPMailer\PHPMailer\PHPMailer; setSiteSendMessage($mail); $mail->setFrom($contactEmail, $webSiteTitle); $mail->Subject = $subject . " - " . $webSiteTitle; $mail->msgHTML($message); $count = 0; foreach ($piece as $value) { $count++; _error_log("sendSiteEmail::addBCC [{$count}] {$value}"); $mail->addBCC($value); } $resp = $mail->send(); if (!$resp) { _error_log("sendSiteEmail Error Info: {$mail->ErrorInfo}"); } else { _error_log("sendSiteEmail Success Info: $subject " . json_encode($to)); } } } //Set the subject line return $resp; } catch (phpmailerException $e) { _error_log($e->errorMessage()); //Pretty error messages from PHPMailer } catch (Exception $e) { _error_log($e->getMessage()); //Boring error messages from anything else! } } function sendSiteEmailAsync($to, $subject, $message) { global $global; $content = array('to' => $to, 'subject' => $subject, 'message' => $message); $tmpFile = getTmpFile(); file_put_contents($tmpFile, _json_encode($content)); //outputAndContinueInBackground(); $command = "php {$global['systemRootPath']}objects/sendSiteEmailAsync.php '$tmpFile'"; _error_log("sendSiteEmailAsync start ($command)"); $pid = execAsync($command); _error_log("sendSiteEmailAsync end {$pid}"); return $pid; } function createEmailMessageFromTemplate($message) { //check if the message already have a HTML body if (preg_match("/html>/i", $message)) { return $message; } global $global, $config; $text = file_get_contents("{$global['systemRootPath']}view/include/emailTemplate.html"); $siteTitle = $config->getWebSiteTitle(); $logo = "getLogo(true) . "\" alt=\"{$siteTitle}\">"; $words = array($logo, $message, $siteTitle); $replace = array('{logo}', '{message}', '{siteTitle}'); return str_replace($replace, $words, $text); } function sendEmailToSiteOwner($subject, $message) { global $advancedCustom; $subject = UTF8encode($subject); $message = UTF8encode($message); _error_log("sendEmailToSiteOwner {$subject}"); global $config, $global; require_once $global['systemRootPath'] . 'objects/include_phpmailer.php'; $contactEmail = $config->getContactEmail(); $webSiteTitle = $config->getWebSiteTitle(); try { $mail = new \PHPMailer\PHPMailer\PHPMailer; setSiteSendMessage($mail); $mail->setFrom($contactEmail, $webSiteTitle); $mail->Subject = $subject . " - " . $webSiteTitle; $mail->msgHTML($message); $mail->addAddress($contactEmail); $resp = $mail->send(); if (!$resp) { _error_log("sendEmailToSiteOwner Error Info: {$mail->ErrorInfo}"); } else { _error_log("sendEmailToSiteOwner Success Info: $subject " . json_encode($to)); } return $resp; } catch (phpmailerException $e) { _error_log($e->errorMessage()); //Pretty error messages from PHPMailer } catch (Exception $e) { _error_log($e->getMessage()); //Boring error messages from anything else! } } function parseVideos($videoString = null, $autoplay = 0, $loop = 0, $mute = 0, $showinfo = 0, $controls = 1, $time = 0, $objectFit = "") { global $global; //_error_log("parseVideos: $videoString"); if (strpos($videoString, 'youtube.com/embed') !== false) { return $videoString . (parse_url($videoString, PHP_URL_QUERY) ? '&' : '?') . 'modestbranding=1&showinfo=' . $showinfo . "&autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&t=$time&objectFit=$objectFit"; } if (strpos($videoString, 'iframe') !== false) { // retrieve the video url $anchorRegex = '/src="(.*)?"/isU'; $results = array(); if (preg_match($anchorRegex, $video, $results)) { $link = trim($results[1]); } } else { // we already have a url $link = $videoString; } if (stripos($link, 'embed') !== false) { return $link . (parse_url($link, PHP_URL_QUERY) ? '&' : '?') . 'modestbranding=1&showinfo=' . $showinfo . "&autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&t=$time&objectFit=$objectFit"; } elseif (strpos($link, 'youtube.com') !== false) { preg_match( '/[\\?\\&]v=([^\\?\\&]+)/', $link, $matches ); //the ID of the YouTube URL: x6qe_kVaBpg if (empty($matches[1])) { return $link; } $id = $matches[1]; return '//www.youtube.com/embed/' . $id . '?modestbranding=1&showinfo=' . $showinfo . "&autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&te=$time&objectFit=$objectFit"; } elseif (strpos($link, 'youtu.be') !== false) { //https://youtu.be/9XXOBSsPoMU preg_match( '/youtu.be\/([a-zA-Z0-9_]+)($|\/)/', $link, $matches ); //the ID of the YouTube URL: x6qe_kVaBpg $id = $matches[1]; return '//www.youtube.com/embed/' . $id . '?modestbranding=1&showinfo=' . $showinfo . "&autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&te=$time&objectFit=$objectFit"; } elseif (strpos($link, 'player.vimeo.com') !== false) { // works on: // http://player.vimeo.com/video/37985580?title=0&byline=0&portrait=0 $videoIdRegex = '/player.vimeo.com\/video\/([0-9]+)\??/i'; preg_match($videoIdRegex, $link, $matches); $id = $matches[1]; return '//player.vimeo.com/video/' . $id; } elseif (strpos($link, 'vimeo.com/channels') !== false) { //extract the ID preg_match( '/\/\/(www\.)?vimeo.com\/channels\/[a-z0-9-]+\/(\d+)($|\/)/i', $link, $matches ); //the ID of the Vimeo URL: 71673549 $id = $matches[2]; return '//player.vimeo.com/video/' . $id; } elseif (strpos($link, 'vimeo.com') !== false) { //extract the ID preg_match( '/\/\/(www\.)?vimeo.com\/(\d+)($|\/)/', $link, $matches ); //the ID of the Vimeo URL: 71673549 $id = $matches[2]; return '//player.vimeo.com/video/' . $id; } elseif (strpos($link, 'dailymotion.com') !== false) { //extract the ID preg_match( '/\/\/(www\.)?dailymotion.com\/video\/([a-zA-Z0-9_]+)($|\/)/', $link, $matches ); //the ID of the Vimeo URL: 71673549 $id = $matches[2]; return '//www.dailymotion.com/embed/video/' . $id; } elseif (strpos($link, 'metacafe.com') !== false) { //extract the ID preg_match( '/\/\/(www\.)?metacafe.com\/watch\/([a-zA-Z0-9_\/-]+)$/', $link, $matches ); $id = $matches[2]; return '//www.metacafe.com/embed/' . $id; } elseif (strpos($link, 'vid.me') !== false) { //extract the ID preg_match( '/\/\/(www\.)?vid.me\/([a-zA-Z0-9_-]+)$/', $link, $matches ); $id = $matches[2]; return '//vid.me/e/' . $id; } elseif (strpos($link, 'rutube.ru') !== false) { //extract the ID preg_match('/\/\/(www\.)?rutube.ru\/video\/([a-zA-Z0-9_-]+)\/.*/', $link, $matches); $id = $matches[2]; return '//rutube.ru/play/embed/' . $id; } elseif (strpos($link, 'ok.ru') !== false) { //extract the ID preg_match('/\/\/(www\.)?ok.ru\/video\/([a-zA-Z0-9_-]+)$/', $link, $matches); $id = $matches[2]; return '//ok.ru/videoembed/' . $id; } elseif (strpos($link, 'streamable.com') !== false) { //extract the ID preg_match('/\/\/(www\.)?streamable.com\/([a-zA-Z0-9_-]+)$/', $link, $matches); $id = $matches[2]; return '//streamable.com/s/' . $id; } elseif (strpos($link, 'twitch.tv/videos') !== false) { //extract the ID preg_match('/\/\/(www\.)?twitch.tv\/videos\/([a-zA-Z0-9_-]+)$/', $link, $matches); if (!empty($matches[2])) { $id = $matches[2]; return '//player.twitch.tv/?video=' . $id . '&parent=' . parse_url($global['webSiteRootURL'], PHP_URL_HOST); } //extract the ID preg_match('/\/\/(www\.)?twitch.tv\/[a-zA-Z0-9_-]+\/v\/([a-zA-Z0-9_-]+)$/', $link, $matches); $id = $matches[2]; return '//player.twitch.tv/?video=' . $id . '&parent=' . parse_url($global['webSiteRootURL'], PHP_URL_HOST); } elseif (strpos($link, 'twitch.tv') !== false) { //extract the ID preg_match('/\/\/(www\.)?twitch.tv\/([a-zA-Z0-9_-]+)$/', $link, $matches); $id = $matches[2]; return '//player.twitch.tv/?channel=' . $id . '&parent=' . parse_url($global['webSiteRootURL'], PHP_URL_HOST); } elseif (strpos($link, 'bitchute.com/video') !== false) { //extract the ID preg_match('/\/\/(www\.)?bitchute.com\/video\/([^\/]+)/', $link, $matches); $id = $matches[2]; return 'https://www.bitchute.com/embed/' . $id . '/?parent=' . parse_url($global['webSiteRootURL'], PHP_URL_HOST); } elseif (strpos($link, '/evideo/') !== false) { //extract the ID preg_match('/(http.+)\/evideo\/([a-zA-Z0-9_-]+)($|\/)/i', $link, $matches); //the AVideo site $site = $matches[1]; $id = $matches[2]; return $site . '/evideoEmbed/' . $id . "?autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&t=$time"; } elseif (strpos($link, '/video/') !== false) { //extract the ID preg_match('/(http.+)\/video\/([a-zA-Z0-9_-]+)($|\/)/i', $link, $matches); //the AVideo site if (!empty($matches[1])) { $site = $matches[1]; $id = $matches[2]; return $site . '/videoEmbeded/' . $id . "?autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&t=$time"; } else { return $link; } } $url = $videoString; $url_parsed = parse_url($url); if (empty($url_parsed['query'])) { return ""; } $new_qs_parsed = array(); // Grab our first query string parse_str($url_parsed['query'], $new_qs_parsed); // Here's the other query string $other_query_string = 'modestbranding=1&showinfo=' . $showinfo . "&autoplay={$autoplay}&controls=$controls&loop=$loop&mute=$mute&t=$time"; $other_qs_parsed = array(); parse_str($other_query_string, $other_qs_parsed); // Stitch the two query strings together $final_query_string_array = array_merge($new_qs_parsed, $other_qs_parsed); $final_query_string = http_build_query($final_query_string_array); // Now, our final URL: if (empty($url_parsed['scheme'])) { $scheme = ''; } else { $scheme = "{$url_parsed['scheme']}:"; } $new_url = $scheme . '//' . $url_parsed['host'] . $url_parsed['path'] . '?' . $final_query_string; return $new_url; // return data } $canUseCDN = array(); function canUseCDN($videos_id) { if (empty($videos_id)) { return false; } global $global, $canUseCDN; if (!isset($canUseCDN[$videos_id])) { require_once $global['systemRootPath'] . 'plugin/VR360/Objects/VideosVR360.php'; $pvr360 = AVideoPlugin::isEnabledByName('VR360'); // if the VR360 is enabled you can not use the CDN, it fail to load the GL $isVR360Enabled = VideosVR360::isVR360Enabled($videos_id); if ($pvr360 && $isVR360Enabled) { $ret = false; } else { $ret = true; } //_error_log(json_encode(array('canUseCDN'=>$ret, '$pvr360'=>$pvr360, '$isVR360Enabled'=>$isVR360Enabled, '$videos_id'=>$videos_id))); $canUseCDN[$videos_id] = $ret; } return $canUseCDN[$videos_id]; } function clearVideosURL($fileName = "") { global $global; $path = getCacheDir() . "getVideosURL/"; if (empty($path)) { rrmdir($path); } else { $cacheFilename = "{$path}{$fileName}.cache"; @unlink($cacheFilename); } } function maxLifetime() { global $maxLifetime; if (!isset($maxLifetime)) { $aws_s3 = AVideoPlugin::getObjectDataIfEnabled('AWS_S3'); $bb_b2 = AVideoPlugin::getObjectDataIfEnabled('Blackblaze_B2'); $secure = AVideoPlugin::getObjectDataIfEnabled('SecureVideosDirectory'); $maxLifetime = 0; if (!empty($aws_s3) && empty($aws_s3->makeMyFilesPublicRead) && !empty($aws_s3->presignedRequestSecondsTimeout) && (empty($maxLifetime) || $aws_s3->presignedRequestSecondsTimeout < $maxLifetime)) { $maxLifetime = $aws_s3->presignedRequestSecondsTimeout; //_error_log("maxLifetime: AWS_S3 = {$maxLifetime}"); } if (!empty($bb_b2) && empty($bb_b2->usePublicBucket) && !empty($bb_b2->presignedRequestSecondsTimeout) && (empty($maxLifetime) || $bb_b2->presignedRequestSecondsTimeout < $maxLifetime)) { $maxLifetime = $bb_b2->presignedRequestSecondsTimeout; //_error_log("maxLifetime: B2 = {$maxLifetime}"); } if (!empty($secure) && !empty($secure->tokenTimeOut) && (empty($maxLifetime) || $secure->tokenTimeOut < $maxLifetime)) { $maxLifetime = $secure->tokenTimeOut; //_error_log("maxLifetime: Secure = {$maxLifetime}"); } } return $maxLifetime; } $cacheExpirationTime = false; function cacheExpirationTime() { if (isBot()) { return 604800; // 1 week } global $cacheExpirationTime; if (empty($cacheExpirationTime)) { $obj = AVideoPlugin::getObjectDataIfEnabled('Cache'); $cacheExpirationTime = @$obj->cacheTimeInSeconds; } return intval($cacheExpirationTime); } /** * tell if a file should recreate a cache, based on its time and the plugins toke expirations * @param type $filename * @return boolean */ function recreateCache($filename) { return (!file_exists($filename) || time() - filemtime($filename) > minimumExpirationTime()); } function _getImagesURL($fileName, $type) { global $global; $files = array(); $source = Video::getSourceFile($fileName, ".jpg"); $file1 = $source['path']; if (file_exists($file1)) { $files["jpg"] = array( 'filename' => "{$fileName}.jpg", 'path' => $file1, 'url' => $source['url'], 'type' => 'image', ); } else { unset($file1); $files["jpg"] = array( 'filename' => "{$type}.png", 'path' => getCDN() . "view/img/{$type}.png", 'url' => getCDN() . "view/img/{$type}.png", 'type' => 'image', ); } $source = Video::getSourceFile($fileName, "_portrait.jpg"); $file2 = $source['path']; if (file_exists($file2)) { $files["pjpg"] = array( 'filename' => "{$fileName}_portrait.jpg", 'path' => $file2, 'url' => $source['url'], 'type' => 'image', ); } elseif ($type != 'image') { if (!empty($file1)) { $files["pjpg"] = $files["jpg"]; } else { $files["pjpg"] = array( 'filename' => "{$type}_portrait.png", 'path' => getCDN() . "view/img/{$type}_portrait.png", 'url' => getCDN() . "view/img/{$type}_portrait.png", 'type' => 'image', ); } } return $files; } function getVideosURLPDF($fileName) { global $global; if (empty($fileName)) { return array(); } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $start = $time; $source = Video::getSourceFile($fileName, ".pdf"); $file = $source['path']; $files["pdf"] = array( 'filename' => "{$fileName}.pdf", 'path' => $file, 'url' => $source['url'], 'type' => 'pdf', ); $files = array_merge($files, _getImagesURL($fileName, 'pdf')); $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); //_error_log("getVideosURLPDF generated in {$total_time} seconds. fileName: $fileName "); return $files; } function getVideosURLIMAGE($fileName) { global $global; if (empty($fileName)) { return array(); } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $start = $time; $types = array('png', 'gif', 'webp', 'jpg'); foreach ($types as $value) { $source = Video::getSourceFile($fileName, ".{$value}"); $file = $source['path']; $files["image"] = array( 'filename' => "{$fileName}.{$value}", 'path' => $file, 'url' => $source['url'], 'type' => 'image', ); if (file_exists($file)) { break; } } $files = array_merge($files, _getImagesURL($fileName, 'image')); $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); //_error_log("getVideosURLPDF generated in {$total_time} seconds. fileName: $fileName "); return $files; } function getVideosURLZIP($fileName) { global $global; if (empty($fileName)) { return array(); } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $start = $time; $types = array('zip'); foreach ($types as $value) { $source = Video::getSourceFile($fileName, ".{$value}"); $file = $source['path']; $files["zip"] = array( 'filename' => "{$fileName}.zip", 'path' => $file, 'url' => $source['url'], 'type' => 'zip', ); if (file_exists($file)) { break; } } $files = array_merge($files, _getImagesURL($fileName, 'zip')); $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); //_error_log("getVideosURLPDF generated in {$total_time} seconds. fileName: $fileName "); return $files; } function getVideosURLArticle($fileName) { global $global; if (empty($fileName)) { return array(); } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $start = $time; //$files = array_merge($files, _getImagesURL($fileName, 'article')); $files = _getImagesURL($fileName, 'article'); $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); //_error_log("getVideosURLPDF generated in {$total_time} seconds. fileName: $fileName "); return $files; } function getVideosURLAudio($fileName, $fileNameisThePath = false) { global $global; if (empty($fileName)) { return array(); } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $start = $time; if ($fileNameisThePath) { $filename = basename($fileName); $files["mp3"] = array( 'filename' => $filename, 'path' => Video::getPathToFile($filename), 'url' => Video::getURLToFile($filename), 'type' => 'audio', ); } else { $source = Video::getSourceFile($fileName, ".mp3"); $file = $source['path']; $files["mp3"] = array( 'filename' => "{$fileName}.mp3", 'path' => $file, 'url' => $source['url'], 'type' => 'audio', ); } $files = array_merge($files, _getImagesURL($fileName, 'audio_wave')); $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $start), 4); //_error_log("getVideosURLAudio generated in {$total_time} seconds. fileName: $fileName "); return $files; } function getVideosURL($fileName, $cache = true) { return getVideosURL_V2($fileName); // disable this function soon } function getVideosURLMP4Only($fileName) { $allFiles = getVideosURL_V2($fileName); if (is_array($allFiles)) { foreach ($allFiles as $key => $value) { if ($value['format'] !== 'mp4') { unset($allFiles[$key]); } } return $allFiles; } _error_log("getVideosURLMP4Only does not return an ARRAY from getVideosURL_V2($fileName) " . json_encode($allFiles)); return array(); } function getVideosURLWEBMOnly($fileName) { $allFiles = getVideosURL_V2($fileName); // disable this function soon if (is_array($allFiles)) { foreach ($allFiles as $key => $value) { if ($value['format'] !== 'webm') { unset($allFiles[$key]); } } return $allFiles; } _error_log("getVideosURLMP4Only does not return an ARRAY from getVideosURL_V2($fileName) " . json_encode($allFiles)); return array(); } function getVideosURLMP4WEBMOnly($fileName) { return array_merge(getVideosURLMP4Only($fileName), getVideosURLWEBMOnly($fileName)); } function getVideosURLOnly($fileName) { $allFiles = getVideosURL_V2($fileName); // disable this function soon foreach ($allFiles as $key => $value) { if ($value['type'] !== 'video') { unset($allFiles[$key]); } } return $allFiles; } function getAudioURLOnly($fileName) { $allFiles = getVideosURL_V2($fileName); // disable this function soon foreach ($allFiles as $key => $value) { if ($value['type'] !== 'audio') { unset($allFiles[$key]); } } return $allFiles; } function getAudioOrVideoURLOnly($fileName) { $allFiles = getVideosURL_V2($fileName); // disable this function soon foreach ($allFiles as $key => $value) { if ($value['type'] !== 'video' && $value['type'] !== 'audio') { unset($allFiles[$key]); } } return $allFiles; } function getVideosDir() { return Video::getStoragePath(); } $getVideosURL_V2Array = array(); function getVideosURL_V2($fileName, $recreateCache = false) { global $global, $getVideosURL_V2Array; if (empty($fileName)) { return array(); } //$recreateCache = true; $cleanfilename = Video::getCleanFilenameFromFile($fileName); if (!empty($getVideosURL_V2Array[$cleanfilename])) { return $getVideosURL_V2Array[$cleanfilename]; } $paths = Video::getPaths($cleanfilename); $pdf = $paths['path'] . "{$cleanfilename}.pdf"; $mp3 = $paths['path'] . "{$cleanfilename}.mp3"; if (file_exists($pdf)) { return getVideosURLPDF($fileName); } elseif (file_exists($mp3)) { return getVideosURLAudio($mp3, true); } $cacheName = "getVideosURL_V2$fileName"; if (empty($recreateCache)) { $lifetime = maxLifetime(); $TimeLog1 = "getVideosURL_V2($fileName) empty recreateCache"; TimeLogStart($TimeLog1); $files = object_to_array(ObjectYPT::getCache($cacheName, $lifetime, true)); if (is_array($files)) { //_error_log("getVideosURL_V2: do NOT recreate lifetime = {$lifetime}"); $preg_match_url = addcslashes(getCDN(), "/") . "videos"; foreach ($files as $value) { // check if is a dummy file and the URL still wrong $pathFilesize = filesize($value['path']); if ( $value['type'] === 'video' && // is a video preg_match("/^{$preg_match_url}/", $value['url']) && // the URL is the same as the main domain $pathFilesize < 20) { // file size is small _error_log("getVideosURL_V2:: dummy file found, fix cache " . json_encode(array("/^{$preg_match_url}/", $value['url'], preg_match("/^{$preg_match_url}video/", $value['url']), $pathFilesize, $value))); unset($files); $video = Video::getVideoFromFileName($fileName, true, true); Video::clearCache($video['id']); break; } else { //_error_log("getVideosURL_V2:: NOT dummy file ". json_encode(array("/^{$preg_match_url}video/", $value['url'], preg_match("/^{$preg_match_url}video/", $value['url']),filesize($value['path']),$value))); } } //_error_log("getVideosURL_V2:: cachestill good ". json_encode($files)); } else { //_error_log("getVideosURL_V2:: cache not found ". json_encode($files)); } TimeLogEnd($TimeLog1, __LINE__); } else { _error_log("getVideosURL_V2($fileName) Recreate cache requested " . json_encode(debug_backtrace())); } if (empty($files)) { $files = array(); $plugin = AVideoPlugin::loadPlugin("VideoHLS"); if (!empty($plugin)) { $timeName = "getVideosURL_V2::VideoHLS::getSourceFile($fileName)"; TimeLogStart($timeName); $files = VideoHLS::getSourceFile($fileName, true); TimeLogEnd($timeName, __LINE__); } $video = array('webm', 'mp4'); $audio = array('mp3', 'ogg'); $image = array('jpg', 'gif', 'webp'); $formats = array_merge($video, $audio, $image); //$globQuery = getVideosDir()."{$cleanfilename}*.{" . implode(",", $formats) . "}"; //$filesInDir = glob($globQuery, GLOB_BRACE); $timeName = "getVideosURL_V2::globVideosDir($cleanfilename)"; TimeLogStart($timeName); $filesInDir = globVideosDir($cleanfilename, true); TimeLogEnd($timeName, __LINE__); $timeName = "getVideosURL_V2::foreach"; TimeLogStart($timeName); foreach ($filesInDir as $file) { $parts = pathinfo($file); if ($parts['filename'] == 'index') { $parts['filename'] = str_replace(Video::getPathToFile($parts['dirname']), '', $parts['dirname']); } //$timeName2 = "getVideosURL_V2::Video::getSourceFile({$parts['filename']}, .{$parts['extension']})"; //TimeLogStart($timeName2); $source = Video::getSourceFile($parts['filename'], ".{$parts['extension']}"); //TimeLogEnd($timeName2, __LINE__); if (empty($source)) { continue; } if (filesize($file) < 1000 && !preg_match("/Dummy File/i", file_get_contents($file))) { continue; } if (preg_match("/{$cleanfilename}(_.+)[.]{$parts['extension']}$/", $file, $matches)) { $resolution = $matches[1]; } else { preg_match('/_([^_]{0,4}).' . $parts['extension'] . '$/', $file, $matches); $resolution = @$matches[1]; } $type = 'video'; if (in_array($parts['extension'], $video)) { $type = 'video'; } elseif (in_array($parts['extension'], $audio)) { $type = 'audio'; } elseif (in_array($parts['extension'], $image) || preg_match('/^(gif|jpg|webp|png|jpeg)/i', $parts['extension'])) { $type = 'image'; if (!preg_match('/(thumb|roku)/', $resolution)) { $resolution = ''; } } $files["{$parts['extension']}{$resolution}"] = array( 'filename' => "{$parts['filename']}.{$parts['extension']}", 'path' => $file, 'url' => $source['url'], 'type' => $type, 'format' => strtolower($parts['extension']), ); } TimeLogEnd($timeName, __LINE__); ObjectYPT::setCache($cacheName, $files); } if (is_array($files)) { // sort by resolution uasort($files, "sortVideosURL"); } //var_dump($files);exit; $getVideosURL_V2Array[$cleanfilename] = $files; return $getVideosURL_V2Array[$cleanfilename]; } //Returns < 0 if str1 is less than str2; > 0 if str1 is greater than str2, and 0 if they are equal. function sortVideosURL($a, $b) { if ($a['type'] == 'video') { $aRes = getResolutionFromFilename($a['filename']); $bRes = getResolutionFromFilename($b['filename']); return $aRes - $bRes; } return 0; } function getResolutionFromFilename($filename) { global $getResolutionFromFilenameArray; if (!isset($getResolutionFromFilenameArray)) { $getResolutionFromFilenameArray = array(); } if (!empty($getResolutionFromFilenameArray[$filename])) { return $getResolutionFromFilenameArray[$filename]; } $res = Video::getResolutionFromFilename($filename); if (empty($res)) { if (preg_match('/[_\/]hd[.\/]/i', $filename)) { $res = 720; } else if (preg_match('/[_\/]sd[.\/]/i', $filename)) { $res = 480; } else if (preg_match('/[_\/]low[.\/]/i', $filename)) { $res = 240; } else { $res = 0; } } $getResolutionFromFilenameArray[$filename] = $res; return $res; } function getSources($fileName, $returnArray = false, $try = 0) { if ($returnArray) { $videoSources = $audioTracks = $subtitleTracks = array(); } else { $videoSources = $audioTracks = $subtitleTracks = ""; } $video = Video::getVideoFromFileNameLight($fileName); if ($video['type'] !== 'audio' && function_exists('getVRSSources')) { $videoSources = getVRSSources($fileName, $returnArray); } else { //$files = getVideosURL($fileName); $files = getVideosURL_V2($fileName, !empty($try)); $sources = ""; $sourcesArray = array(); foreach ($files as $key => $value) { $path_parts = pathinfo($value['path']); if ($path_parts['extension'] == "webm" || $path_parts['extension'] == "mp4" || $path_parts['extension'] == "m3u8" || $path_parts['extension'] == "mp3" || $path_parts['extension'] == "ogg") { $obj = new stdClass(); $obj->type = mime_content_type_per_filename($value['path']); $sources .= "type}\">"; $obj->src = $value['url']; $sourcesArray[] = $obj; } } $videoSources = $returnArray ? $sourcesArray : $sources; } if (function_exists('getVTTTracks')) { $subtitleTracks = getVTTTracks($fileName, $returnArray); } if ($returnArray) { $return = array_merge($videoSources, $audioTracks, $subtitleTracks); } else { $return = $videoSources . $audioTracks . $subtitleTracks; } $obj = new stdClass(); $obj->result = $return; if (empty($videoSources) && empty($audioTracks) && !empty($video['id']) && $video['type'] == 'video') { if (empty($try)) { //sleep(1); $sources = getSources($fileName, $returnArray, $try + 1); if (!empty($sources)) { Video::updateFilesize($video['id']); } Video::clearCache($video['id']); return $sources; } else { _error_log("getSources($fileName) File not found " . json_encode($video)); $obj = new stdClass(); $obj->type = "video/mp4"; $obj->src = "Video not found"; $obj->label = "Video not found"; $obj->res = 0; $sourcesArray["mp4"] = $obj; $sources["mp4"] = "type}\" label=\"{$obj->label}\" res=\"{$obj->res}\">"; $return = $returnArray ? $sourcesArray : implode(PHP_EOL, $sources); } } return $return; } /** * * @param type $file_src * @return typeget image size with cache */ function getimgsize($file_src) { global $_getimagesize; if (empty($_getimagesize)) { $_getimagesize = array(); } $name = "getimgsize_" . md5($file_src); if (!empty($_getimagesize[$name])) { $size = $_getimagesize[$name]; } else { $cached = ObjectYPT::getCache($name, 86400); //one day if (!empty($cached)) { $c = (Array) $cached; $size = array(); foreach ($c as $key => $value) { if (preg_match("/^[0-9]+$/", $key)) { $key = intval($key); } $size[$key] = $value; } $_getimagesize[$name] = $size; return $size; } $size = @getimagesize($file_src); if (empty($size)) { $size = array(1024, 768); } ObjectYPT::setCache($name, $size); $_getimagesize[$name] = $size; } return $size; } function im_resize($file_src, $file_dest, $wd, $hd, $q = 80) { if (empty($file_dest)) { return false; } if (!file_exists($file_src)) { _error_log("im_resize: Source not found: {$file_src}"); return false; } $size = getimgsize($file_src); if ($size === false) { _error_log("im_resize: Could not get image size: {$file_src}"); return false; } if (empty($size['mime']) || $size['mime'] == 'image/pjpeg') { $size['mime'] = 'image/jpeg'; } $format = strtolower(substr($size['mime'], strpos($size['mime'], '/') + 1)); if (empty($format)) { $format = 'jpeg'; } $destformat = strtolower(substr($file_dest, -4)); if (empty($destformat)) { _error_log("destformat not found {$file_dest}"); $destformat = ".jpg"; } $icfunc = "imagecreatefrom" . $format; if (!function_exists($icfunc)) { _error_log("im_resize: Function does not exists: {$icfunc}"); return false; } $imgSize = getimagesize($file_src); if (empty($imgSize)) { _error_log("im_resize: getimagesize($file_src) return false " . json_encode($imgSize)); return false; } try { $src = $icfunc($file_src); } catch (Exception $exc) { _error_log("im_resize: " . $exc->getMessage()); _error_log("im_resize: Try {$icfunc} from string"); $src = imagecreatefromstring(file_get_contents($file_src)); if (!$src) { _error_log("im_resize: fail {$icfunc} from string"); return false; } } $ws = imagesx($src); $hs = imagesy($src); if ($ws <= $hs) { $hd = ceil(($wd * $hs) / $ws); } else { $wd = ceil(($hd * $ws) / $hs); } if ($ws <= $wd) { $wd = $ws; $hd = $hs; } $wc = ($wd * $hs) / $hd; if ($wc <= $ws) { $hc = ($wc * $hd) / $wd; } else { $hc = ($ws * $hd) / $wd; $wc = ($wd * $hc) / $hd; } $dest = imagecreatetruecolor($wd, $hd); switch ($format) { case "png": imagealphablending($dest, false); imagesavealpha($dest, true); $transparent = imagecolorallocatealpha($dest, 255, 255, 255, 127); imagefilledrectangle($dest, 0, 0, $wd, $hd, $transparent); break; case "gif": // integer representation of the color black (rgb: 0,0,0) $background = imagecolorallocate($src, 0, 0, 0); // removing the black from the placeholder imagecolortransparent($src, $background); break; } imagecopyresampled($dest, $src, 0, 0, ($ws - $wc) / 2, ($hs - $hc) / 2, $wd, $hd, $wc, $hc); $saved = false; if ($destformat == '.png') { $saved = imagepng($dest, $file_dest); } if ($destformat == '.jpg') { $saved = imagejpeg($dest, $file_dest, $q); } if (!$saved) { _error_log('saving failed'); } imagedestroy($dest); imagedestroy($src); @chmod($file_dest, 0666); return true; } function im_resizeV2($file_src, $file_dest, $wd, $hd, $q = 80) { _error_log("im_resizeV2: $file_src, $file_dest, $wd, $hd, $q"); $newImage = im_resize($file_src, $file_dest, $wd, $hd, 100); if (!$newImage) { return false; } $src = imagecreatefromjpeg($file_dest); $ws = imagesx($src); $hs = imagesy($src); if ($ws < $wd) { $dst_x = ($wd - $ws) / 2; } else { $dst_x = 0; } if ($hs < $hd) { $dst_y = ($hd - $hs) / 2; } else { $dst_y = 0; } $mapImage = imagecreatetruecolor($wd, $hd); $bgColor = imagecolorallocate($mapImage, 0, 0, 0); imagefill($mapImage, 0, 0, $bgColor); $tileImg = imagecreatefromjpeg($file_dest); imagecopy($mapImage, $tileImg, $dst_x, $dst_y, 0, 0, $ws, $hs); $saved = imagejpeg($mapImage, $file_dest, $q); return $saved; } function im_resizePNG($file_src, $file_dest, $wd, $hd) { $srcImage = imagecreatefrompng($file_src); $ws = imagesx($srcImage); $hs = imagesy($srcImage); $targetImage = imagecreatetruecolor($wd, $hd); imagealphablending($targetImage, false); imagesavealpha($targetImage, true); imagecopyresampled($targetImage, $srcImage, 0, 0, 0, 0, $wd, $hd, $ws, $hs); $saved = imagepng($targetImage, $file_dest); return $saved; } function im_resizeV3($file_src, $file_dest, $wd, $hd) { _error_log("im_resizeV3: $file_src, $file_dest, $wd, $hd"); // This tries to preserve the aspect ratio of the thumb while letterboxing it in // The same way that the encoder now does. eval('$ffmpeg ="ffmpeg -i {$file_src} -filter_complex \"scale=(iw*sar)*min({$wd}/(iw*sar)\,{$hd}/ih):ih*min({$wd}/(iw*sar)\,{$hd}/ih), pad={$wd}:{$hd}:({$wd}-iw*min({$wd}/iw\,{$hd}/ih))/2:({$hd}-ih*min({$wd}/iw\,{$hd}/ih))/2\" -sws_flags lanczos -qscale:v 2 {$file_dest}";'); exec($ffmpeg . " < /dev/null 2>&1", $output, $return_val); } function im_resize_gif($file_src, $file_dest, $max_width, $max_height) { if (class_exists('Imagick')) { $imagick = new Imagick($file_src); $format = $imagick->getImageFormat(); if ($format == 'GIF') { $imagick = $imagick->coalesceImages(); do { $imagick->resizeImage($max_width, $max_height, Imagick::FILTER_BOX, 1); } while ($imagick->nextImage()); $imagick = $imagick->deconstructImages(); $imagick->writeImages($file_dest, true); } $imagick->clear(); $imagick->destroy(); } else { copy($file_src, $file_dest); } } function im_resize_max_size($file_src, $file_dest, $max_width, $max_height) { $fn = $file_src; $extension = strtolower(pathinfo($file_dest, PATHINFO_EXTENSION)); if ($extension == 'gif') { im_resize_gif($file_src, $file_dest, $max_width, $max_height); @unlink($file_src); return true; } $tmpFile = getTmpFile() . ".{$extension}"; if (empty($fn)) { _error_log("im_resize_max_size: file name is empty, Destination: {$file_dest}", AVideoLog::$ERROR); return false; } if (function_exists("exif_read_data")) { error_log($fn); convertImage($fn, $tmpFile, 100); $exif = exif_read_data($tmpFile); if ($exif && isset($exif['Orientation'])) { $orientation = $exif['Orientation']; if ($orientation != 1) { $img = imagecreatefromjpeg($tmpFile); $deg = 0; switch ($orientation) { case 3: $deg = 180; break; case 6: $deg = 270; break; case 8: $deg = 90; break; } if ($deg) { $img = imagerotate($img, $deg, 0); } imagejpeg($img, $fn, 100); } } } else { _error_log("Make sure you install the php_mbstring and php_exif to be able to rotate images"); } $size = getimagesize($fn); $ratio = $size[0] / $size[1]; // width/height if ($size[0] <= $max_width && $size[1] <= $max_height) { $width = $size[0]; $height = $size[1]; } elseif ($ratio > 1) { $width = $max_width; $height = $max_height / $ratio; } else { $width = $max_width * $ratio; $height = $max_height; } $src = imagecreatefromstring(file_get_contents($fn)); $dst = imagecreatetruecolor($width, $height); imagecopyresampled($dst, $src, 0, 0, 0, 0, $width, $height, $size[0], $size[1]); imagedestroy($src); imagejpeg($dst, $file_dest); // adjust format as needed imagedestroy($dst); @unlink($file_src); @unlink($tmpFile); } function convertImage($originalImage, $outputImage, $quality) { $imagetype = 0; if (function_exists('exif_imagetype')) { $imagetype = exif_imagetype($originalImage); } $ext = strtolower(pathinfo($originalImage, PATHINFO_EXTENSION)); $extOutput = strtolower(pathinfo($outputImage, PATHINFO_EXTENSION)); if ($ext == $extOutput) { return copy($originalImage, $outputImage); } try { if ($imagetype == IMAGETYPE_JPEG || preg_match('/jpg|jpeg/i', $ext)) { $imageTmp = @imagecreatefromjpeg($originalImage); } elseif ($imagetype == IMAGETYPE_PNG || preg_match('/png/i', $ext)) { $imageTmp = imagecreatefrompng($originalImage); } elseif ($imagetype == IMAGETYPE_GIF || preg_match('/gif/i', $ext)) { $imageTmp = imagecreatefromgif($originalImage); } elseif ($imagetype == IMAGETYPE_BMP || preg_match('/bmp/i', $ext)) { $imageTmp = imagecreatefrombmp($originalImage); } elseif ($imagetype == IMAGETYPE_WEBP || preg_match('/webp/i', $ext)) { $imageTmp = imagecreatefromwebp($originalImage); } else { _error_log("convertImage: File Extension not found ($originalImage, $outputImage, $quality) " . exif_imagetype($originalImage)); return 0; } } catch (Exception $exc) { _error_log("convertImage: " . $exc->getMessage()); return 0; } if (!is_resource($imageTmp)) { _error_log("convertImage: could not create a resource $originalImage, $outputImage, $quality"); return 0; } // quality is a value from 0 (worst) to 100 (best) $response = 0; if ($extOutput === 'jpg') { if (function_exists('imagejpeg')) { $response = imagejpeg($imageTmp, $outputImage, $quality); } else { _error_log("convertImage ERROR: function imagejpeg does not exists"); } } else if ($extOutput === 'png') { if (function_exists('imagepng')) { $response = imagepng($imageTmp, $outputImage, $quality / 10); } else { _error_log("convertImage ERROR: function imagepng does not exists"); } } else if ($extOutput === 'webp') { if (function_exists('imagewebp')) { $response = imagewebp($imageTmp, $outputImage, $quality); } else { _error_log("convertImage ERROR: function imagewebp does not exists"); } } else if ($extOutput === 'gif') { if (function_exists('imagegif')) { $response = imagegif($imageTmp, $outputImage); } else { _error_log("convertImage ERROR: function imagegif does not exists"); } } imagedestroy($imageTmp); return $response; } function decideMoveUploadedToVideos($tmp_name, $filename, $type = "video") { if ($filename == '.zip') { return false; } global $global; $obj = new stdClass(); $aws_s3 = AVideoPlugin::loadPluginIfEnabled('AWS_S3'); $bb_b2 = AVideoPlugin::loadPluginIfEnabled('Blackblaze_B2'); $ftp = AVideoPlugin::loadPluginIfEnabled('FTP_Storage'); $paths = Video::getPaths($filename, true); $destinationFile = "{$paths['path']}{$filename}"; //$destinationFile = getVideosDir() . "{$filename}"; _error_log("decideMoveUploadedToVideos: {$filename}"); $path_info = pathinfo($filename); if ($type !== "zip" && $path_info['extension'] === 'zip') { _error_log("decideMoveUploadedToVideos: ZIp file {$filename}"); $paths = Video::getPaths($path_info['filename']); $dir = $paths['path']; unzipDirectory($tmp_name, $dir); // unzip it cleanDirectory($dir); if (!empty($aws_s3)) { //$aws_s3->move_uploaded_file($tmp_name, $filename); } elseif (!empty($bb_b2)) { $bb_b2->move_uploaded_directory($dir); } elseif (!empty($ftp)) { //$ftp->move_uploaded_file($tmp_name, $filename); } } else { _error_log("decideMoveUploadedToVideos: NOT ZIp file {$filename}"); if (!empty($aws_s3)) { _error_log("decideMoveUploadedToVideos: S3 {$filename}"); $aws_s3->move_uploaded_file($tmp_name, $filename); } elseif (!empty($bb_b2)) { _error_log("decideMoveUploadedToVideos: B2 {$filename}"); $bb_b2->move_uploaded_file($tmp_name, $filename); } elseif (!empty($ftp)) { _error_log("decideMoveUploadedToVideos: FTP {$filename}"); $ftp->move_uploaded_file($tmp_name, $filename); } else { _error_log("decideMoveUploadedToVideos: Local {$filename}"); if (!move_uploaded_file($tmp_name, $destinationFile)) { if (!rename($tmp_name, $destinationFile)) { if (!copy($tmp_name, $destinationFile)) { $obj->msg = "Error on decideMoveUploadedToVideos({$tmp_name}, $destinationFile)"; die(json_encode($obj)); } } } chmod($destinationFile, 0644); } } sleep(1); $fsize = @filesize($destinationFile); _error_log("decideMoveUploadedToVideos: destinationFile {$destinationFile} filesize=" . ($fsize) . " (" . humanFileSize($fsize) . ")"); Video::clearCacheFromFilename($filename); } function unzipDirectory($filename, $destination) { global $global; // Wait a couple of seconds to make sure the file has completed transfer sleep(2); ini_set('memory_limit', '-1'); ini_set('max_execution_time', 7200); // 2 hours $cmd = "unzip {$filename} -d {$destination}" . " 2>&1"; _error_log("unzipDirectory: {$cmd}"); exec($cmd, $output, $return_val); if ($return_val !== 0 && function_exists("zip_open")) { // try to unzip using PHP _error_log("unzipDirectory: TRY to use PHP {$filename}"); $zip = zip_open($filename); if ($zip) { while ($zip_entry = zip_read($zip)) { $path = "{$destination}/" . zip_entry_name($zip_entry); //_error_log("unzipDirectory: fopen $path"); if (substr(zip_entry_name($zip_entry), -1) == '/') { make_path($path); } else { make_path($path); $fp = fopen($path, "w"); if (zip_entry_open($zip, $zip_entry, "r")) { $buf = zip_entry_read($zip_entry, zip_entry_filesize($zip_entry)); fwrite($fp, "$buf"); zip_entry_close($zip_entry); fclose($fp); } } } zip_close($zip); } else { _error_log("unzipDirectory: ERROR php zip does not work"); } } else { _error_log("unzipDirectory: Success {$destination}"); } @unlink($filename); } function make_path($path) { if (substr($path, -1) !== DIRECTORY_SEPARATOR) { $path = pathinfo($path, PATHINFO_DIRNAME); } if (!is_dir($path)) { mkdir($path, 0755, true); } } /** * for security clean all non secure files from directory * @param type $dir * @param type $allowedExtensions * @return type */ function cleanDirectory($dir, $allowedExtensions = array('key', 'm3u8', 'ts', 'vtt', 'jpg', 'gif', 'mp3', 'webm', 'webp')) { $ffs = scandir($dir); unset($ffs[array_search('.', $ffs, true)]); unset($ffs[array_search('..', $ffs, true)]); // prevent empty ordered elements if (count($ffs) < 1) { return; } foreach ($ffs as $ff) { $current = $dir . '/' . $ff; if (is_dir($current)) { cleanDirectory($current, $allowedExtensions); } $path_parts = pathinfo($current); if (!empty($path_parts['extension']) && !in_array($path_parts['extension'], $allowedExtensions)) { unlink($current); } } } function decideFile_put_contentsToVideos($tmp_name, $filename) { global $global; $aws_s3 = AVideoPlugin::loadPluginIfEnabled('AWS_S3'); $bb_b2 = AVideoPlugin::loadPluginIfEnabled('Blackblaze_B2'); $ftp = AVideoPlugin::loadPluginIfEnabled('FTP_Storage'); if (!empty($bb_b2)) { $bb_b2->move_uploaded_file($tmp_name, $filename); } elseif (!empty($aws_s3)) { $aws_s3->move_uploaded_file($tmp_name, $filename); } elseif (!empty($ftp)) { $ftp->move_uploaded_file($tmp_name, $filename); } else { $path = Video::getPathToFile($filename); if (!move_uploaded_file($tmp_name, $path)) { $obj->msg = "Error on move_uploaded_file({$tmp_name}, {$filename})"; die(json_encode($obj)); } } } function isAnyStorageEnabled() { if ($yptStorage = AVideoPlugin::loadPluginIfEnabled("YPTStorage")) { return true; } else if ($aws_s3 = AVideoPlugin::loadPluginIfEnabled("AWS_S3")) { return true; } else if ($bb_b2 = AVideoPlugin::loadPluginIfEnabled("Blackblaze_B2")) { return true; } else if ($ftp = AVideoPlugin::loadPluginIfEnabled("FTP_Storage")) { return true; } return false; } if (!function_exists('mime_content_type')) { function mime_content_type($filename) { return mime_content_type_per_filename($filename); } } function fontAwesomeClassName($filename) { $mime_type = mime_content_type_per_filename($filename); // List of official MIME Types: http://www.iana.org/assignments/media-types/media-types.xhtml $icon_classes = array( // Media 'image' => 'fas fa-file-image', 'audio' => 'fas fa-file-audio', 'video' => 'fas fa-file-video', // Documents 'application/pdf' => 'fas fa-file-pdf', 'application/msword' => 'fas fa-file-word', 'application/vnd.ms-word' => 'fas fa-file-word', 'application/vnd.oasis.opendocument.text' => 'fas fa-file-word', 'application/vnd.openxmlformats-officedocument.wordprocessingml' => 'fas fa-file-word', 'application/vnd.ms-excel' => 'fas fa-file-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml' => 'fas fa-file-excel', 'application/vnd.oasis.opendocument.spreadsheet' => 'fas fa-file-excel', 'application/vnd.ms-powerpoint' => 'fas fa-file-powerpoint', 'application/vnd.openxmlformats-officedocument.presentationml' => 'fas fa-file-powerpoint', 'application/vnd.oasis.opendocument.presentation' => 'fas fa-file-powerpoint', 'text/plain' => 'far fa-file-alt', 'text/html' => 'fas fa-code', 'application/json' => 'fas fa-code', // Archives 'application/gzip' => 'far fa-file-archive', 'application/zip' => 'far fa-file-archive', ); foreach ($icon_classes as $text => $icon) { if (strpos($mime_type, $text) === 0) { return $icon; } } return 'fas fa-file'; } function mime_content_type_per_filename($filename) { $mime_types = array( 'txt' => 'text/plain', 'htm' => 'text/html', 'html' => 'text/html', 'php' => 'text/html', 'css' => 'text/css', 'js' => 'application/javascript', 'json' => 'application/json', 'xml' => 'application/xml', 'swf' => 'application/x-shockwave-flash', 'flv' => 'video/x-flv', // images 'png' => 'image/png', 'jpe' => 'image/jpeg', 'jpeg' => 'image/jpeg', 'jpg' => 'image/jpeg', 'gif' => 'image/gif', 'bmp' => 'image/bmp', 'ico' => 'image/vnd.microsoft.icon', 'tiff' => 'image/tiff', 'tif' => 'image/tiff', 'svg' => 'image/svg+xml', 'svgz' => 'image/svg+xml', // archives 'zip' => 'application/zip', 'rar' => 'application/x-rar-compressed', 'exe' => 'application/x-msdownload', 'msi' => 'application/x-msdownload', 'cab' => 'application/vnd.ms-cab-compressed', // audio/video 'mp3' => 'audio/mpeg', 'qt' => 'video/quicktime', 'mov' => 'video/quicktime', 'mp4' => 'video/mp4', 'avi' => 'video/avi', 'mkv' => 'video/mkv', 'wav' => 'audio/wav', 'm4v' => 'video/mpeg', 'webm' => 'video/webm', 'wmv' => 'video/wmv', 'mpg' => 'video/mpeg', 'mpeg' => 'video/mpeg', 'f4v' => 'video/x-flv', 'm4v' => 'video/m4v', 'm4a' => 'video/quicktime', 'm2p' => 'video/quicktime', 'rm' => 'video/quicktime', 'vob' => 'video/quicktime', 'mkv' => 'video/quicktime', '3gp' => 'video/quicktime', 'm3u8' => 'application/x-mpegURL', // adobe 'pdf' => 'application/pdf', 'psd' => 'image/vnd.adobe.photoshop', 'ai' => 'application/postscript', 'eps' => 'application/postscript', 'ps' => 'application/postscript', // ms office 'doc' => 'application/msword', 'rtf' => 'application/rtf', 'xls' => 'application/vnd.ms-excel', 'ppt' => 'application/vnd.ms-powerpoint', // open office 'odt' => 'application/vnd.oasis.opendocument.text', 'ods' => 'application/vnd.oasis.opendocument.spreadsheet' ); if (filter_var($filename, FILTER_VALIDATE_URL) === false) { $ext = pathinfo($filename, PATHINFO_EXTENSION); } else { $ext = pathinfo(parse_url($filename, PHP_URL_PATH), PATHINFO_EXTENSION); } if ($ext === 'mp4' || $ext === 'webm') { $securePlugin = AVideoPlugin::loadPluginIfEnabled('SecureVideosDirectory'); if (!empty($securePlugin)) { if (method_exists($securePlugin, "useEncoderWatrermarkFromFileName") && $securePlugin->useEncoderWatrermarkFromFileName($filename)) { return "application/x-mpegURL"; } } } if (array_key_exists($ext, $mime_types)) { return $mime_types[$ext]; } elseif (function_exists('finfo_open')) { $finfo = finfo_open(FILEINFO_MIME); $mimetype = finfo_file($finfo, $filename); finfo_close($finfo); return $mimetype; } else { return 'application/octet-stream'; } } function combineFiles($filesArray, $extension = "js") { global $global, $advancedCustom; if ($extension == 'js' && isBot()) { return getCDN() . 'view/js/empty.js'; } $cacheDir = $global['systemRootPath'] . 'videos/cache/' . $extension . "/"; if (!is_dir($cacheDir)) { mkdir($cacheDir, 0777, true); } $str = ""; $fileName = ""; foreach ($filesArray as $value) { $fileName .= $value . filectime($global['systemRootPath'] . $value) . filemtime($global['systemRootPath'] . $value); } if ($advancedCustom != false) { $minifyEnabled = $advancedCustom->EnableMinifyJS; } else { $minifyEnabled = false; } // temporary disable minify $minifyEnabled = false; $md5FileName = md5($fileName) . ".{$extension}"; if (!file_exists($cacheDir . $md5FileName)) { foreach ($filesArray as $value) { if (file_exists($global['systemRootPath'] . $value)) { $str .= "\n/*{$value} created local with systemRootPath */\n" . local_get_contents($global['systemRootPath'] . $value); } elseif (file_exists($value)) { $str .= "\n/*{$value} created local with full-path given */\n" . local_get_contents($value); } else { $allowed = ""; if (ini_get('allow_url_fopen')) { $allowed .= "allow_url_fopen is on and "; } if (function_exists('curl_init')) { $allowed .= "curl is on"; } else { $allowed .= "curl is off"; } $content = url_get_contents($value); if (empty($content)) { $allowed .= " - web-fallback 1 (add webSiteRootURL)"; $content = url_get_contents($global['webSiteRootURL'] . $value); } $str .= "\n/*{$value} created via web with own url ({$allowed}) */\n" . $content; } } //if ((($extension == "js" || $extension == "css") && ($minifyEnabled))) { if ($extension == "css" && ($minifyEnabled)) { require_once $global['systemRootPath'] . 'objects/jshrink.php'; $str = \JShrink\Minifier::minify($str, array('flaggedComments' => false)); } file_put_contents($cacheDir . $md5FileName, $str); } return getCDN() . 'videos/cache/' . $extension . "/" . $md5FileName . "?cache=" . filectime($cacheDir . $md5FileName) . filemtime($cacheDir . $md5FileName); } function local_get_contents($path) { if (function_exists('fopen')) { $myfile = fopen($path, "r") or die("Unable to open file! [{$path}]"); $text = fread($myfile, filesize($path)); fclose($myfile); return $text; } } function getSelfUserAgent() { global $global, $AVideoStreamer_UA; $agent = $AVideoStreamer_UA . " "; $agent .= parse_url($global['webSiteRootURL'], PHP_URL_HOST); return $agent; } function url_get_contents($url, $ctx = "", $timeout = 0, $debug = false) { global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort; if ($debug) { _error_log("url_get_contents: Start $url, $ctx, $timeout " . getSelfURI() . " " . getRealIpAddr() . " " . json_encode(debug_backtrace())); } $agent = getSelfUserAgent(); if (empty($ctx)) { $opts = array( 'http' => array('header' => "User-Agent: {$agent}\r\n"), "ssl" => array( "verify_peer" => false, "verify_peer_name" => false, "allow_self_signed" => true, ), ); if (!empty($timeout)) { ini_set('default_socket_timeout', $timeout); $opts['http'] = array('timeout' => $timeout); } $context = stream_context_create($opts); } else { $context = $ctx; } if (ini_get('allow_url_fopen')) { if ($debug) { _error_log("url_get_contents: allow_url_fopen {$url}"); } try { $tmp = @file_get_contents($url, false, $context); if ($tmp != false) { $response = remove_utf8_bom($tmp); if ($debug) { //_error_log("url_get_contents: SUCCESS file_get_contents($url) {$response}"); _error_log("url_get_contents: SUCCESS file_get_contents($url)"); } return $response; } if ($debug) { _error_log("url_get_contents: ERROR file_get_contents($url) "); } } catch (ErrorException $e) { if ($debug) { _error_log("url_get_contents: allow_url_fopen ERROR " . $e->getMessage() . " {$url}"); } return "url_get_contents: " . $e->getMessage(); } } elseif (function_exists('curl_init')) { if ($debug) { _error_log("url_get_contents: CURL {$url} "); } $ch = curl_init(); curl_setopt($ch, CURLOPT_USERAGENT, $agent); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); if (!empty($timeout)) { curl_setopt($ch, CURLOPT_TIMEOUT, $timeout); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout + 10); } $output = curl_exec($ch); curl_close($ch); if ($debug) { _error_log("url_get_contents: CURL SUCCESS {$url}"); } return remove_utf8_bom($output); } if ($debug) { _error_log("url_get_contents: Nothing yet {$url}"); } // try wget $filename = getTmpDir("YPTurl_get_contents") . md5($url); if ($debug) { _error_log("url_get_contents: try wget $filename {$url}"); } if (wget($url, $filename, $debug)) { if ($debug) { _error_log("url_get_contents: wget success {$url} "); } $result = file_get_contents($filename); unlink($filename); if (!empty($result)) { return remove_utf8_bom($result); } } elseif ($debug) { _error_log("url_get_contents: try wget fail {$url}"); } return false; } function getUpdatesFilesArray() { global $config, $global; if (!class_exists('User') || !User::isAdmin()) { return array(); } $files1 = scandir($global['systemRootPath'] . "updatedb"); $updateFiles = array(); foreach ($files1 as $value) { preg_match("/updateDb.v([0-9.]*).sql/", $value, $match); if (!empty($match)) { if ($config->currentVersionLowerThen($match[1])) { $updateFiles[] = array('filename' => $match[0], 'version' => $match[1]); } } } return $updateFiles; } function thereIsAnyUpdate() { if (!User::isAdmin()) { return false; } $name = 'thereIsAnyUpdate'; if (!isset($_SESSION['sessionCache'][$name])) { $files = getUpdatesFilesArray(); if (!empty($files)) { _session_start(); $_SESSION['sessionCache'][$name] = $files; } } return @$_SESSION['sessionCache'][$name]; } function thereIsAnyRemoteUpdate() { if (!User::isAdmin()) { return false; } global $config; $cacheName = '_thereIsAnyRemoteUpdate'; $cache = ObjectYPT::getCache($cacheName, 86400); // 24 hours if (!empty($cache)) { return $cache; } //$version = _json_decode(url_get_contents("https://tutorials.avideo.com/version")); $version = _json_decode(url_get_contents("https://tutorialsavideo.b-cdn.net/version", "", 4)); if (empty($version)) { return false; } $name = 'thereIsAnyRemoteUpdate'; if (!isset($_SESSION['sessionCache'][$name])) { if (!empty($version)) { _session_start(); if (version_compare($config->getVersion(), $version->version) === -1) { $_SESSION['sessionCache'][$name] = $version; } else { $_SESSION['sessionCache'][$name] = false; } } } ObjectYPT::setCache($cacheName, $_SESSION['sessionCache'][$name]); return $_SESSION['sessionCache'][$name]; } function UTF8encode($data) { global $advancedCustom, $global; if (!empty($advancedCustom->utf8Encode)) { return utf8_encode($data); } if (!empty($advancedCustom->utf8Decode)) { return utf8_decode($data); } return $data; } //detect search engine bots function isBot() { global $_isBot; if (empty($_SERVER['HTTP_USER_AGENT'])) { return true; } if (isAVideoEncoder()) { return false; } if (isset($_isBot)) { return $_isBot; } $_isBot = false; // User lowercase string for comparison. $user_agent = strtolower($_SERVER['HTTP_USER_AGENT']); // A list of some common words used only for bots and crawlers. $bot_identifiers = array( 'bot', 'slurp', 'crawler', 'spider', 'curl', 'facebook', 'fetch', 'loader', 'lighthouse', 'pingdom', 'gtmetrix', 'ptst', 'dmbrowser', 'dareboost' ); // See if one of the identifiers is in the UA string. foreach ($bot_identifiers as $identifier) { if (stripos($user_agent, $identifier) !== false) { $_isBot = true; break; } } return $_isBot; } /** * A function that could get me the last N lines of a log file. * @param type $filepath * @param type $lines * @param type $adaptive * @return boolean */ function tail($filepath, $lines = 1, $adaptive = true, $returnArray = false) { if (!function_exists('mb_strlen')) { $msg = "AVideoLog::ERROR you need to install the mb_strlen function to make it work, please the command 'sudo apt install php-mbstring'"; if ($returnArray) { return array(array($msg)); } else { return $msg; } } // Open file $f = @fopen($filepath, "rb"); if ($f === false) { return false; } // Sets buffer size, according to the number of lines to retrieve. // This gives a performance boost when reading a few lines from the file. if (!$adaptive) { $buffer = 4096; } else { $buffer = ($lines < 2 ? 64 : ($lines < 10 ? 512 : 4096)); } // Jump to last character fseek($f, -1, SEEK_END); // Read it and adjust line number if necessary // (Otherwise the result would be wrong if file doesn't end with a blank line) if (fread($f, 1) != "\n") { $lines -= 1; } // Start reading $output = ''; $chunk = ''; // While we would like more while (ftell($f) > 0 && $lines >= 0) { // Figure out how far back we should jump $seek = min(ftell($f), $buffer); // Do the jump (backwards, relative to where we are) fseek($f, -$seek, SEEK_CUR); // Read a chunk and prepend it to our output $output = ($chunk = fread($f, $seek)) . $output; // Jump back to where we started reading fseek($f, -mb_strlen($chunk, '8bit'), SEEK_CUR); // Decrease our line counter $lines -= substr_count($chunk, "\n"); } // While we have too many lines // (Because of buffer size we might have read too many) while ($lines++ < 0) { // Find first newline and remove all text before that $output = substr($output, strpos($output, "\n") + 1); } // Close file and return fclose($f); $output = trim($output); if ($returnArray) { $array = explode("\n", $output); $newArray = array(); foreach ($array as $value) { $newArray[] = array($value); } return $newArray; } else { return $output; } } function encryptPassword($password, $noSalt = false) { global $advancedCustom, $global, $advancedCustomUser; if (!empty($advancedCustomUser->encryptPasswordsWithSalt) && !empty($global['salt']) && empty($noSalt)) { $password .= $global['salt']; } return md5(hash("whirlpool", sha1($password))); } function encryptPasswordVerify($password, $hash, $encodedPass = false) { global $advancedCustom, $global; if (!$encodedPass || $encodedPass === 'false') { //_error_log("encryptPasswordVerify: encrypt"); $passwordSalted = encryptPassword($password); // in case you enable the salt later $passwordUnSalted = encryptPassword($password, true); } else { //_error_log("encryptPasswordVerify: do not encrypt"); $passwordSalted = $password; // in case you enable the salt later $passwordUnSalted = $password; } //_error_log("passwordSalted = $passwordSalted, hash=$hash, passwordUnSalted=$passwordUnSalted"); return $passwordSalted === $hash || $passwordUnSalted === $hash || $password === $hash; } function isMobile($userAgent = null, $httpHeaders = null) { if (empty($userAgent) && empty($_SERVER["HTTP_USER_AGENT"])) { return false; } global $global; require_once $global['systemRootPath'] . 'objects/Mobile_Detect.php'; $detect = new Mobile_Detect; return $detect->isMobile($userAgent, $httpHeaders); } function isChannelPage() { return strpos($_SERVER["SCRIPT_NAME"], 'view/channel.php') !== false; } function isAVideoMobileApp($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return false; } global $AVideoMobileAPP_UA; if (preg_match("/{$AVideoMobileAPP_UA}(.*)/", $_SERVER["HTTP_USER_AGENT"], $match)) { $url = trim($match[1]); if (!empty($url)) { return $url; } return true; } return false; } function isAVideoEncoder($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return false; } global $AVideoEncoder_UA; if (preg_match("/{$AVideoEncoder_UA}(.*)/", $_SERVER["HTTP_USER_AGENT"], $match)) { $url = trim($match[1]); if (!empty($url)) { return $url; } return true; } return false; } function isCDN() { if (empty($_SERVER['HTTP_CDN_HOST'])) { return false; } return isFromCDN($_SERVER['HTTP_CDN_HOST']); } function isFromCDN($url) { if (preg_match('/cdn.ypt.me/i', $url)) { return true; } return false; } function isAVideo($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return false; } global $AVideoEncoder_UA; if (preg_match("/AVideo(.*)/", $_SERVER["HTTP_USER_AGENT"], $match)) { $url = trim($match[1]); if (!empty($url)) { return $url; } return true; } return false; } function isAVideoEncoderOnSameDomain() { $url = isAVideoEncoder(); if (empty($url)) { return false; } $url = "http://{$url}"; return isSameDomainAsMyAVideo($url); } function isSameDomainAsMyAVideo($url) { global $global; if (empty($url)) { return false; } return isSameDomain($url, $global['webSiteRootURL']) || isSameDomain($url, getCDN()); } function requestComesFromSameDomainAsMyAVideo() { global $global; $url = ""; if (!empty($_SERVER['HTTP_REFERER'])) { $url = $_SERVER['HTTP_REFERER']; } elseif (!empty($_SERVER['HTTP_ORIGIN'])) { $url = $_SERVER['HTTP_ORIGIN']; } //_error_log("requestComesFromSameDomainAsMyAVideo: ({$url}) == ({$global['webSiteRootURL']})"); return isSameDomain($url, $global['webSiteRootURL']) || isSameDomain($url, getCDN()) || isFromCDN($url); } function requestComesFromSafePlace() { return (requestComesFromSameDomainAsMyAVideo() || isAVideo()); } function addGlobalTokenIfSameDomain($url) { if (!filter_var($url, FILTER_VALIDATE_URL) || (empty($_GET['livelink']) || !preg_match("/^http.*/i", $_GET['livelink']))) { return $url; } if (!isSameDomainAsMyAVideo($url)) { return $url; } return addQueryStringParameter($url, 'globalToken', getToken(60)); } /** * Remove a query string parameter from an URL. * * @param string $url * @param string $varname * * @return string */ function removeQueryStringParameter($url, $varname) { $parsedUrl = parse_url($url); $query = array(); if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); unset($query[$varname]); } $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; $query = !empty($query) ? '?' . http_build_query($query) : ''; if (empty($parsedUrl['scheme'])) { $scheme = ''; } else { $scheme = "{$parsedUrl['scheme']}:"; } return $scheme . '//' . $parsedUrl['host'] . $path . $query; } /** * Add a query string parameter from an URL. * * @param string $url * @param string $varname * * @return string */ function addQueryStringParameter($url, $varname, $value) { $parsedUrl = parse_url($url); if (empty($parsedUrl['host'])) { return ""; } $query = array(); if (isset($parsedUrl['query'])) { parse_str($parsedUrl['query'], $query); } $query[$varname] = $value; $path = isset($parsedUrl['path']) ? $parsedUrl['path'] : ''; $query = !empty($query) ? '?' . http_build_query($query) : ''; $port = ""; if (!empty($parsedUrl['port']) && $parsedUrl['port'] != '80') { $port = ":{$parsedUrl['port']}"; } if (empty($parsedUrl['scheme'])) { $scheme = ''; } else { $scheme = "{$parsedUrl['scheme']}:"; } return $scheme . '//' . $parsedUrl['host'] . $port . $path . $query; } function isSameDomain($url1, $url2) { if (empty($url1) || empty($url2)) { return false; } return (get_domain($url1) === get_domain($url2)); } function isAVideoStreamer($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return false; } global $AVideoStreamer_UA; if (preg_match("/{$AVideoStreamer_UA}(.*)/", $_SERVER["HTTP_USER_AGENT"], $match)) { $url = trim($match[1]); if (!empty($url)) { return $url; } return true; } return false; } function isAVideoStorage($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return false; } global $AVideoStorage_UA; if (preg_match("/{$AVideoStorage_UA}(.*)/", $_SERVER["HTTP_USER_AGENT"], $match)) { $url = trim($match[1]); if (!empty($url)) { return $url; } return true; } return false; } function get_domain($url, $ifEmptyReturnSameString = false) { $pieces = parse_url($url); $domain = isset($pieces['host']) ? $pieces['host'] : ''; if (empty($domain)) { return $ifEmptyReturnSameString ? $url : false; } if (preg_match('/(?P[a-z0-9][a-z0-9\-]{1,63}\.[a-z\.]{2,6})$/i', $domain, $regs)) { return $regs['domain']; } else { $isIp = (bool) ip2long($pieces['host']); if ($isIp) { return $pieces['host']; } } return false; } function siteMap() { _error_log("siteMap: start"); ini_set('memory_limit', '-1'); ini_set('max_execution_time', 0); global $global, $advancedCustom; $date = date('Y-m-d\TH:i:s') . "+00:00"; $xml = ' ' . $global['webSiteRootURL'] . ' ' . $date . ' always 1.00 ' . $global['webSiteRootURL'] . 'help ' . $date . ' monthly 0.50 ' . $global['webSiteRootURL'] . 'about ' . $date . ' monthly 0.50 ' . $global['webSiteRootURL'] . 'contact ' . $date . ' monthly 0.50 ' . $global['webSiteRootURL'] . 'channels ' . $date . ' daily 0.80 '; $_REQUEST['rowCount'] = $advancedCustom->siteMapRowsLimit; _error_log("siteMap: rowCount {$_REQUEST['rowCount']} "); $_POST['sort']['modified'] = "DESC"; $users = User::getAllUsersThatHasVideos(true); _error_log("siteMap: getAllUsers " . count($users)); foreach ($users as $value) { $xml .= ' ' . User::getChannelLink($value['id']) . ' ' . $date . ' daily 0.90 '; } $xml .= ' '; $_REQUEST['rowCount'] = $advancedCustom->siteMapRowsLimit; $_POST['sort']['modified'] = "DESC"; $rows = Category::getAllCategories(); _error_log("siteMap: getAllCategories " . count($rows)); foreach ($rows as $value) { $xml .= ' ' . $global['webSiteRootURL'] . 'cat/' . $value['clean_name'] . ' ' . $date . ' weekly 0.80 '; } $xml .= ''; $_REQUEST['rowCount'] = $advancedCustom->siteMapRowsLimit * 10; $_POST['sort']['created'] = "DESC"; $rows = Video::getAllVideos(!empty($advancedCustom->showPrivateVideosOnSitemap) ? "viewableNotUnlisted" : "publicOnly"); _error_log("siteMap: getAllVideos " . count($rows)); foreach ($rows as $video) { $videos_id = $video['id']; //_error_log("siteMap: getAllVideos videos_id {$videos_id} start"); $source = Video::getSourceFile($video['filename']); if (($video['type'] !== "audio") && ($video['type'] !== "linkAudio") && !empty($source['url'])) { $img = $source['url']; $data = getimgsize($source['path']); $imgw = $data[0]; $imgh = $data[1]; } elseif ($video['type'] == "audio") { $img = getCDN() . "view/img/audio_wave.jpg"; } $type = 'video'; if ($video['type'] === 'pdf') { $type = 'pdf'; } if ($video['type'] === 'article') { $type = 'article'; } $images = Video::getImageFromFilename($video['filename'], $type); if (!empty($images->posterPortrait) && basename($images->posterPortrait) !== 'notfound_portrait.jpg' && basename($images->posterPortrait) !== 'pdf_portrait.png' && basename($images->posterPortrait) !== 'article_portrait.png') { $img = $images->posterPortrait; $data = getimgsize($images->posterPortraitPath); $imgw = $data[0]; $imgh = $data[1]; } else { $img = $images->poster; } $description = str_replace(array('"', "\n", "\r"), array('', ' ', ' '), empty(trim($video['description'])) ? $video['title'] : $video['description']); $duration = parseDurationToSeconds($video['duration']); if ($duration > 28800) { // this is because this issue https://github.com/WWBN/AVideo/issues/3338 remove in the future if is not necessary anymore $duration = 28800; } $xml .= ' ' . Video::getLink($video['id'], $video['clean_title']) . ' ' . $img . ' ' . $duration . ' ' . $video['views_count'] . ' ' . date("Y-m-d\TH:i:s", strtotime($video['created'])) . '+00:00 yes ' . (Video::isPublic($video['id']) ? "no" : "yes") . ' ' . User::getNameIdentificationById($video['users_id']) . ' no '; } $xml .= ' '; _error_log("siteMap: done "); $newXML1 = preg_replace('/[^\x{0009}\x{000a}\x{000d}\x{0020}-\x{D7FF}\x{E000}-\x{FFFD}]+/u', '', $xml); if (empty($newXML1)) { _error_log("siteMap: pregreplace1 fail "); $newXML1 = $xml; } if (!empty($advancedCustom->siteMapUTF8Fix)) { $newXML2 = preg_replace('/&(?!#?[a-z0-9]+;)/', '&', $newXML1); if (empty($newXML2)) { _error_log("siteMap: pregreplace2 fail "); $newXML2 = $newXML1; } $newXML3 = preg_replace('/[\x00-\x1F\x7F-\xFF]/', '', $newXML2); if (empty($newXML3)) { _error_log("siteMap: pregreplace3 fail "); $newXML3 = $newXML2; } $newXML4 = preg_replace('/[\x00-\x1F\x7F]/', '', $newXML3); if (empty($newXML4)) { _error_log("siteMap: pregreplace4 fail "); $newXML4 = $newXML3; } $newXML5 = preg_replace('/[\x00-\x1F\x7F\xA0]/u', '', $newXML4); if (empty($newXML5)) { _error_log("siteMap: pregreplace5 fail "); $newXML5 = $newXML4; } } else { $newXML5 = $newXML1; } return $newXML5; } function object_to_array($obj) { //only process if it's an object or array being passed to the function if (is_object($obj) || is_array($obj)) { $ret = (array) $obj; foreach ($ret as &$item) { //recursively process EACH element regardless of type $item = object_to_array($item); } return $ret; } //otherwise (i.e. for scalar values) return without modification else { return $obj; } } function allowOrigin() { global $global; if (!headers_sent()) { header_remove('Access-Control-Allow-Origin'); } if (empty($_SERVER['HTTP_ORIGIN'])) { $server = parse_url($global['webSiteRootURL']); header('Access-Control-Allow-Origin: ' . $server["scheme"] . '://imasdk.googleapis.com'); } else { header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); } header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Methods: GET,HEAD,OPTIONS,POST,PUT"); header("Access-Control-Allow-Headers: Access-Control-Allow-Headers, Origin,Accept, X-Requested-With, Content-Type, Access-Control-Request-Method, Access-Control-Request-Headers"); } function rrmdir($dir) { if (empty($dir)) { _error_log('rrmdir: the dir was empty'); return false; } global $global; $dir = fixPath($dir, true); $pattern = '/' . addcslashes($dir, DIRECTORY_SEPARATOR) . 'videos[\/\\\]?$/i'; if ($dir == getVideosDir() || $dir == "{$global['systemRootPath']}videos" . DIRECTORY_SEPARATOR || preg_match($pattern, $dir)) { _error_log('rrmdir: A script ties to delete the videos Directory [' . $dir . '] ' . json_encode(array($dir == getVideosDir(), $dir == "{$global['systemRootPath']}videos" . DIRECTORY_SEPARATOR, preg_match($pattern, $dir)))); return false; } if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir . "/" . $object)) { rrmdir($dir . "/" . $object); } else { @unlink($dir . "/" . $object); } } } if (preg_match('/(\/|^)videos(\/cache)?\/?$/i', $dir)) { // do not delete videos or cache folder return false; } @rmdir($dir); if (is_dir($dir)) { _error_log('rrmdir: The Directory was not deleted, trying again ' . $dir); exec('rm -R ' . $dir); } } else { //_error_log('rrmdir: The Directory does not exists '.$dir); } } /** * You can now configure it on the configuration.php * @return boolean */ function ddosProtection() { global $global; $maxCon = empty($global['ddosMaxConnections']) ? 40 : $global['ddosMaxConnections']; $secondTimeout = empty($global['ddosSecondTimeout']) ? 5 : $global['ddosSecondTimeout']; $whitelistedFiles = array( 'playlists.json.php', 'playlistsFromUserVideos.json.php', 'image404.php' ); if (in_array(basename($_SERVER["SCRIPT_FILENAME"]), $whitelistedFiles)) { return true; } $time = time(); if (!isset($_SESSION['bruteForceBlock']) || empty($_SESSION['bruteForceBlock'])) { $_SESSION['bruteForceBlock'] = array(); $_SESSION['bruteForceBlock'][] = $time; return true; } $_SESSION['bruteForceBlock'][] = $time; //remove requests that are older than secondTimeout foreach ($_SESSION['bruteForceBlock'] as $key => $request_time) { if ($request_time < $time - $secondTimeout) { unset($_SESSION['bruteForceBlock'][$key]); } } //progressive timeout-> more requests, longer timeout $active_connections = count($_SESSION['bruteForceBlock']); $timeoutReal = ($active_connections / $maxCon) < 1 ? 0 : ($active_connections / $maxCon) * $secondTimeout; if ($timeoutReal) { _error_log("ddosProtection:: progressive timeout timeoutReal = ($timeoutReal) active_connections = ($active_connections) maxCon = ($maxCon) ", AVideoLog::$SECURITY); } sleep($timeoutReal); //with strict mode, penalize "attacker" with sleep() above, log and then die if ($global['strictDDOSprotection'] && $timeoutReal > 0) { $str = "bruteForceBlock: maxCon: $maxCon => secondTimeout: $secondTimeout | IP: " . getRealIpAddr() . " | count:" . count($_SESSION['bruteForceBlock']); _error_log($str); die($str); } return true; } function getAdsLeaderBoardBigVideo() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->leaderBoardBigVideoMobile->value); } else { return ADs::giveGoogleATimeout($ad->leaderBoardBigVideo->value); } } } function getAdsLeaderBoardTop() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->leaderBoardTopMobile->value); } else { return ADs::giveGoogleATimeout($ad->leaderBoardTop->value); } } } function getAdsChannelLeaderBoardTop() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->channelLeaderBoardTopMobile->value); } else { return ADs::giveGoogleATimeout($ad->channelLeaderBoardTop->value); } } } function getAdsLeaderBoardTop2() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->leaderBoardTopMobile2->value); } else { return ADs::giveGoogleATimeout($ad->leaderBoardTop2->value); } } } function getAdsLeaderBoardMiddle() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->leaderBoardMiddleMobile->value); } else { return ADs::giveGoogleATimeout($ad->leaderBoardMiddle->value); } } } function getAdsLeaderBoardFooter() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->leaderBoardFooterMobile->value); } else { return ADs::giveGoogleATimeout($ad->leaderBoardFooter->value); } } } function getAdsSideRectangle() { $ad = AVideoPlugin::getObjectDataIfEnabled('ADs'); if (!empty($ad)) { if (isMobile()) { return ADs::giveGoogleATimeout($ad->sideRectangle->value); } else { return ADs::giveGoogleATimeout($ad->sideRectangle->value); } } } function isToHidePrivateVideos() { $obj = AVideoPlugin::getObjectDataIfEnabled("Gallery"); if (!empty($obj)) { return $obj->hidePrivateVideos; } $obj = AVideoPlugin::getObjectDataIfEnabled("YouPHPFlix2"); if (!empty($obj)) { return $obj->hidePrivateVideos; } $obj = AVideoPlugin::getObjectDataIfEnabled("YouTube"); if (!empty($obj)) { return $obj->hidePrivateVideos; } return false; } function convertImageToOG($source, $destination) { if (!file_exists($destination)) { $w = 200; $h = 200; $sizes = getimagesize($source); if ($sizes[0] < $w || $sizes[1] < $h) { $tmpDir = getTmpDir(); $fileConverted = $tmpDir . "_jpg_" . uniqid() . ".jpg"; convertImage($source, $fileConverted, 100); im_resizeV2($fileConverted, $destination, $w, $h, 100); unlink($fileConverted); } } return $destination; } function convertImageToRoku($source, $destination) { if (empty($source)) { _error_log("convertImageToRoku: source image is empty"); return false; } $w = 1280; $h = 720; if (file_exists($destination)) { $sizes = getimagesize($destination); if ($sizes[0] < $w || $sizes[1] < $h) { _error_log("convertImageToRoku: file is smaller " . json_encode($sizes)); unlink($destination); } } if (!file_exists($destination)) { try { $tmpDir = getTmpDir(); $fileConverted = $tmpDir . "_jpg_" . uniqid() . ".jpg"; convertImage($source, $fileConverted, 100); im_resizeV2($fileConverted, $destination, $w, $h, 100); @unlink($fileConverted); } catch (Exception $exc) { _error_log("convertImageToRoku: " . $exc->getMessage()); return false; } } return $destination; } function ogSite() { global $global, $config; include $global['systemRootPath'] . 'objects/functionogSite.php'; } function getOpenGraph($videos_id) { global $global, $config, $advancedCustom; include $global['systemRootPath'] . 'objects/functiongetOpenGraph.php'; } function getLdJson($videos_id) { $cache = ObjectYPT::getCache("getLdJson{$videos_id}", 0); if (empty($cache)) { echo $cache; } global $global, $config; echo ""; if (empty($videos_id)) { echo ""; if (!empty($_GET['videoName'])) { echo ""; $video = Video::getVideoFromCleanTitle($_GET['videoName']); } } else { echo ""; $video = Video::getVideoLight($videos_id); } if (empty($video)) { echo ""; return false; } $videos_id = $video['id']; $source = Video::getSourceFile($video['filename']); if (($video['type'] !== "audio") && ($video['type'] !== "linkAudio") && !empty($source['url'])) { $img = $source['url']; $data = getimgsize($source['path']); $imgw = $data[0]; $imgh = $data[1]; } elseif ($video['type'] == "audio") { $img = getCDN() . "view/img/audio_wave.jpg"; } $type = 'video'; if ($video['type'] === 'pdf') { $type = 'pdf'; } if ($video['type'] === 'article') { $type = 'article'; } $images = Video::getImageFromFilename($video['filename'], $type); if (!empty($images->posterPortrait) && basename($images->posterPortrait) !== 'notfound_portrait.jpg' && basename($images->posterPortrait) !== 'pdf_portrait.png' && basename($images->posterPortrait) !== 'article_portrait.png') { $img = $images->posterPortrait; $data = getimgsize($images->posterPortraitPath); $imgw = $data[0]; $imgh = $data[1]; } else { $img = $images->poster; } $description = html2plainText(empty(trim($video['description'])) ? $video['title'] : $video['description']); $duration = Video::getItemPropDuration($video['duration']); if ($duration == "PT0H0M0S") { $duration = "PT0H0M1S"; } $output = ' '; ObjectYPT::setCache("getLdJson{$videos_id}", $output); echo $output; } function getItemprop($videos_id) { $cache = ObjectYPT::getCache("getItemprop{$videos_id}", 0); if (empty($cache)) { echo $cache; } global $global, $config; echo ""; if (empty($videos_id)) { echo ""; if (!empty($_GET['videoName'])) { echo ""; $video = Video::getVideoFromCleanTitle($_GET['videoName']); } } else { echo ""; $video = Video::getVideoLight($videos_id); } if (empty($video)) { echo ""; return false; } $videos_id = $video['id']; $source = Video::getSourceFile($video['filename']); if (($video['type'] !== "audio") && ($video['type'] !== "linkAudio") && !empty($source['url'])) { $img = $source['url']; $data = getimgsize($source['path']); $imgw = $data[0]; $imgh = $data[1]; } elseif ($video['type'] == "audio") { $img = getCDN() . "view/img/audio_wave.jpg"; } $type = 'video'; if ($video['type'] === 'pdf') { $type = 'pdf'; } if ($video['type'] === 'image') { $type = 'image'; } if ($video['type'] === 'zip') { $type = 'zip'; } if ($video['type'] === 'article') { $type = 'article'; } $images = Video::getImageFromFilename($video['filename'], $type); if (!empty($images->posterPortrait) && basename($images->posterPortrait) !== 'notfound_portrait.jpg' && basename($images->posterPortrait) !== 'pdf_portrait.png' && basename($images->posterPortrait) !== 'article_portrait.png') { $img = $images->posterPortrait; $data = getimgsize($images->posterPortraitPath); $imgw = $data[0]; $imgh = $data[1]; } else { $img = $images->poster; } $description = html2plainText(empty(trim($video['description'])) ? $video['title'] : $video['description']); $duration = Video::getItemPropDuration($video['duration']); if ($duration == "PT0H0M0S") { $duration = "PT0H0M1S"; } $output = ' '; ObjectYPT::setCache("getItemprop{$videos_id}", $output); echo $output; } function getOS($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } $os_platform = "Unknown OS Platform"; $os_array = array( '/windows nt 10/i' => 'Windows 10', '/windows nt 6.3/i' => 'Windows 8.1', '/windows nt 6.2/i' => 'Windows 8', '/windows nt 6.1/i' => 'Windows 7', '/windows nt 6.0/i' => 'Windows Vista', '/windows nt 5.2/i' => 'Windows Server 2003/XP x64', '/windows nt 5.1/i' => 'Windows XP', '/windows xp/i' => 'Windows XP', '/windows nt 5.0/i' => 'Windows 2000', '/windows me/i' => 'Windows ME', '/win98/i' => 'Windows 98', '/win95/i' => 'Windows 95', '/win16/i' => 'Windows 3.11', '/macintosh|mac os x/i' => 'Mac OS X', '/mac_powerpc/i' => 'Mac OS 9', '/linux/i' => 'Linux', '/ubuntu/i' => 'Ubuntu', '/iphone/i' => 'iPhone', '/ipod/i' => 'iPod', '/ipad/i' => 'iPad', '/android/i' => 'Android', '/blackberry/i' => 'BlackBerry', '/webos/i' => 'Mobile' ); foreach ($os_array as $regex => $value) { if (preg_match($regex, $user_agent)) { $os_platform = $value; } } return $os_platform; } function get_browser_name($user_agent = "") { if (empty($user_agent)) { $user_agent = @$_SERVER['HTTP_USER_AGENT']; } if (empty($user_agent)) { return 'Unknow'; } // Make case insensitive. $t = strtolower($user_agent); // If the string *starts* with the string, strpos returns 0 (i.e., FALSE). Do a ghetto hack and start with a space. // "[strpos()] may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE." // http://php.net/manual/en/function.strpos.php $t = " " . $t; // Humans / Regular Users if (isAVideoStreamer($t)) { return 'AVideo Mobile App'; } elseif ($url = isAVideoEncoder($t)) { return 'AVideo Encoder ' . $url; } elseif ($url = isAVideoStreamer($t)) { return 'AVideo Streamer ' . $url; } elseif (strpos($t, 'crkey')) { return 'Chromecast'; } elseif (strpos($t, 'opera') || strpos($t, 'opr/')) { return 'Opera'; } elseif (strpos($t, 'edge')) { return 'Edge'; } elseif (strpos($t, 'chrome')) { return 'Chrome'; } elseif (strpos($t, 'safari')) { return 'Safari'; } elseif (strpos($t, 'firefox')) { return 'Firefox'; } elseif (strpos($t, 'msie') || strpos($t, 'trident/7')) { return 'Internet Explorer'; } elseif (strpos($t, 'applecoremedia')) { return 'Native Apple Player'; } // Search Engines elseif (strpos($t, 'google')) { return '[Bot] Googlebot'; } elseif (strpos($t, 'bing')) { return '[Bot] Bingbot'; } elseif (strpos($t, 'slurp')) { return '[Bot] Yahoo! Slurp'; } elseif (strpos($t, 'duckduckgo')) { return '[Bot] DuckDuckBot'; } elseif (strpos($t, 'baidu')) { return '[Bot] Baidu'; } elseif (strpos($t, 'yandex')) { return '[Bot] Yandex'; } elseif (strpos($t, 'sogou')) { return '[Bot] Sogou'; } elseif (strpos($t, 'exabot')) { return '[Bot] Exabot'; } elseif (strpos($t, 'msn')) { return '[Bot] MSN'; } // Common Tools and Bots elseif (strpos($t, 'mj12bot')) { return '[Bot] Majestic'; } elseif (strpos($t, 'ahrefs')) { return '[Bot] Ahrefs'; } elseif (strpos($t, 'semrush')) { return '[Bot] SEMRush'; } elseif (strpos($t, 'rogerbot') || strpos($t, 'dotbot')) { return '[Bot] Moz or OpenSiteExplorer'; } elseif (strpos($t, 'frog') || strpos($t, 'screaming')) { return '[Bot] Screaming Frog'; } // Miscellaneous elseif (strpos($t, 'facebook')) { return '[Bot] Facebook'; } elseif (strpos($t, 'pinterest')) { return '[Bot] Pinterest'; } // Check for strings commonly used in bot user agents elseif (strpos($t, 'crawler') || strpos($t, 'api') || strpos($t, 'spider') || strpos($t, 'http') || strpos($t, 'bot') || strpos($t, 'archive') || strpos($t, 'info') || strpos($t, 'data')) { return '[Bot] Other'; } //_error_log("Unknow user agent ($t) IP=" . getRealIpAddr() . " URI=" . getRequestURI()); return 'Other (Unknown)'; } /** * Due some error on old chrome browsers (version < 70) on decrypt HLS keys with the videojs versions greater then 7.9.7 * we need to detect the chrome browser and load an older version * */ function isOldChromeVersion() { $global; if (empty($_SERVER['HTTP_USER_AGENT'])) { return false; } if (!empty($global['forceOldChrome'])) { return true; } if (preg_match('/Chrome\/([0-9.]+)/i', $_SERVER['HTTP_USER_AGENT'], $matches)) { return version_compare($matches[1], '80', '<='); } return false; } function TimeLogStart($name) { global $global; if (!empty($global['noDebug'])) { return false; } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; if (empty($global['start']) || !is_array($global['start'])) { $global['start'] = array(); } $global['start'][$name] = $time; } function TimeLogEnd($name, $line, $TimeLogLimit = 0.7) { global $global; if (!empty($global['noDebug']) || empty($global['start'][$name])) { return false; } if (!empty($global['TimeLogLimit'])) { $TimeLogLimit = $global['TimeLogLimit']; } $time = microtime(); $time = explode(' ', $time); $time = $time[1] + $time[0]; $finish = $time; $total_time = round(($finish - $global['start'][$name]), 4); if (empty($global['noDebugSlowProcess']) && $total_time > $TimeLogLimit) { _error_log("Warning: Slow process detected [{$name}] On Line {$line} takes {$total_time} seconds to complete, Limit ({$TimeLogLimit}). {$_SERVER["SCRIPT_FILENAME"]}"); } TimeLogStart($name); } class AVideoLog { public static $DEBUG = 0; public static $WARNING = 1; public static $ERROR = 2; public static $SECURITY = 3; public static $SOCKET = 4; } function _error_log_debug($message, $show_args = false) { $array = debug_backtrace(); $message .= PHP_EOL; foreach ($array as $value) { $message .= "function: {$value['function']} Line: {{$value['line']}} File: {{$value['file']}}" . PHP_EOL; if ($show_args) { $message .= print_r($value['args'], true) . PHP_EOL; } } _error_log(PHP_EOL . '***' . PHP_EOL . $message . '***'); } function _error_log($message, $type = 0, $doNotRepeat = false) { if (empty($doNotRepeat)) { // do not log it too many times when you are using HLS format, other wise it will fill the log file with the same error $doNotRepeat = preg_match("/hls.php$/", $_SERVER['SCRIPT_NAME']); } if ($doNotRepeat) { return false; } global $global; if (!empty($global['noDebug']) && $type == 0) { return false; } if (!is_string($message)) { $message = json_encode($message); } $prefix = "AVideoLog::"; switch ($type) { case AVideoLog::$DEBUG: $prefix .= "DEBUG: "; break; case AVideoLog::$WARNING: $prefix .= "WARNING: "; break; case AVideoLog::$ERROR: $prefix .= "ERROR: "; break; case AVideoLog::$SECURITY: $prefix .= "SECURITY: "; break; case AVideoLog::$SOCKET: $prefix .= "SOCKET: "; break; } error_log($prefix . $message . " SCRIPT_NAME: {$_SERVER['SCRIPT_NAME']}"); } function postVariables($url, $array, $httpcodeOnly = true, $timeout = 10) { if (!$url || !is_string($url) || !preg_match('/^http(s)?:\/\/[a-z0-9-]+(.[a-z0-9-]+)*(:[0-9]+)?(\/.*)?$/i', $url)) { return false; } $array = object_to_array($array); $ch = curl_init($url); if ($httpcodeOnly) { @curl_setopt($ch, CURLOPT_HEADER, true); // we want headers @curl_setopt($ch, CURLOPT_NOBODY, true); // we don't need body } else { curl_setopt($curl, CURLOPT_USERAGENT, getSelfUserAgent()); } curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout); //The number of seconds to wait while trying to connect. Use 0 to wait indefinitely. curl_setopt($ch, CURLOPT_TIMEOUT, $timeout + 1); //The maximum number of seconds to allow cURL functions to execute. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $array); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // execute! $response = curl_exec($ch); if ($httpcodeOnly) { $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); // close the connection, release resources used curl_close($ch); if ($httpcode == 200) { return true; } return $httpcode; } else { curl_close($ch); return $response; } } function _session_start(array $options = array()) { try { if (session_status() == PHP_SESSION_NONE) { return @session_start($options); } } catch (Exception $exc) { _error_log("_session_start: " . $exc->getTraceAsString()); return false; } } function _mysql_connect() { global $global, $mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, $mysqlPort, $mysql_connect_was_closed; try { if (!_mysql_is_open()) { $mysql_connect_was_closed = 0; $global['mysqli'] = new mysqli($mysqlHost, $mysqlUser, $mysqlPass, $mysqlDatabase, @$mysqlPort); if (!empty($global['mysqli_charset'])) { $global['mysqli']->set_charset($global['mysqli_charset']); } } } catch (Exception $exc) { _error_log($exc->getTraceAsString()); return false; } } function _mysql_close() { global $global, $mysql_connect_was_closed; if (_mysql_is_open()) { $mysql_connect_was_closed = 1; @$global['mysqli']->close(); $global['mysqli'] = false; } } function _mysql_is_open() { global $global, $mysql_connect_was_closed; try { //if (is_object($global['mysqli']) && (empty($mysql_connect_was_closed) || !empty(@$global['mysqli']->ping()))) { if (is_object($global['mysqli']) && empty($mysql_connect_was_closed)) { return true; } } catch (Exception $exc) { return false; } return false; } function remove_utf8_bom($text) { if (strlen($text) > 1000000) { return $text; } $bom = pack('H*', 'EFBBBF'); $text = preg_replace("/^$bom/", '', $text); return $text; } function getCacheDir() { $p = AVideoPlugin::loadPlugin("Cache"); return $p->getCacheDir(); } function clearCache($firstPageOnly = false) { global $global; $dir = getVideosDir() . "cache" . DIRECTORY_SEPARATOR; if ($firstPageOnly || !empty($_GET['FirstPage'])) { $dir .= "firstPage" . DIRECTORY_SEPARATOR; } //_error_log('clearCache 1: '.$dir); rrmdir($dir); $dir = getCacheDir(); if ($firstPageOnly || !empty($_GET['FirstPage'])) { $dir .= "firstPage" . DIRECTORY_SEPARATOR; } //_error_log('clearCache 2: '.$dir); rrmdir($dir); $dir = getTmpDir() . 'YPTObjectCache' . DIRECTORY_SEPARATOR; if ($firstPageOnly || !empty($_GET['FirstPage'])) { $dir .= "firstPage" . DIRECTORY_SEPARATOR; } //_error_log('clearCache 3: '.$dir); rrmdir($dir); ObjectYPT::deleteCache("getEncoderURL"); } function getUsageFromFilename($filename, $dir = "") { global $global; if (!empty($global['getUsageFromFilename'])) { // manually add this variable in your configuration.php file to not scan your video usage return 0; } if (empty($dir)) { $paths = Video::getPaths($filename); $dir = $paths['path']; } $pos = strrpos($dir, '/'); $dir .= (($pos === false) ? "/" : ""); $totalSize = 0; _error_log("getUsageFromFilename: start {$dir}{$filename}"); //$files = glob("{$dir}{$filename}*"); $files = globVideosDir($filename); session_write_close(); $filesProcessed = array(); if (empty($files)) { _error_log("getUsageFromFilename: we did not find any file for {$dir}{$filename}, we will create a fake one " . json_encode(debug_backtrace())); make_path($dir); file_put_contents("{$dir}{$filename}.notfound", time()); $totalSize = 10; } else { foreach ($files as $f) { if (strpos($f, '.size.lock') !== false) { continue; } if (is_dir($f)) { _error_log("getUsageFromFilename: {$f} is Dir"); $dirSize = getDirSize($f); $totalSize += $dirSize; if ($dirSize < 10000 && AVideoPlugin::isEnabledByName('YPTStorage')) { // probably the HLS file is hosted on the YPTStorage $info = YPTStorage::getFileInfo($filename); if (!empty($info->size)) { $totalSize += $info->size; } } } elseif (is_file($f)) { $filesize = filesize($f); if ($filesize < 20) { // that means it is a dummy file $lockFile = $f . ".size.lock"; if (!file_exists($lockFile) || (time() - 600) > filemtime($lockFile)) { file_put_contents($lockFile, time()); _error_log("getUsageFromFilename: {$f} is Dummy file ({$filesize})"); $aws_s3 = AVideoPlugin::loadPluginIfEnabled('AWS_S3'); //$bb_b2 = AVideoPlugin::loadPluginIfEnabled('Blackblaze_B2'); if (!empty($aws_s3)) { _error_log("getUsageFromFilename: Get from S3"); $filesize += $aws_s3->getFilesize($filename); } elseif (!empty($bb_b2)) { // TODO } else { $urls = Video::getVideosPaths($filename, true); _error_log("getUsageFromFilename: Paths " . json_encode($urls)); if (!empty($urls["m3u8"]['url'])) { $filesize += getUsageFromURL($urls["m3u8"]['url']); } if (!empty($urls['mp4'])) { foreach ($urls['mp4'] as $mp4) { if (in_array($mp4, $filesProcessed)) { continue; } $filesProcessed[] = $mp4; $filesize += getUsageFromURL($mp4); } } if (!empty($urls['webm'])) { foreach ($urls['webm'] as $mp4) { if (in_array($mp4, $filesProcessed)) { continue; } $filesProcessed[] = $mp4; $filesize += getUsageFromURL($mp4); } } if (!empty($urls["pdf"]['url'])) { $filesize += getUsageFromURL($urls["pdf"]['url']); } if (!empty($urls["image"]['url'])) { $filesize += getUsageFromURL($urls["image"]['url']); } if (!empty($urls["zip"]['url'])) { $filesize += getUsageFromURL($urls["zip"]['url']); } if (!empty($urls["mp3"]['url'])) { $filesize += getUsageFromURL($urls["mp3"]['url']); } } unlink($lockFile); } } else { _error_log("getUsageFromFilename: {$f} is File ({$filesize})"); } $totalSize += $filesize; } } } return $totalSize; } /** * Returns the size of a file without downloading it, or -1 if the file * size could not be determined. * * @param $url - The location of the remote file to download. Cannot * be null or empty. * * @return The size of the file referenced by $url, or false if the size * could not be determined. */ function getUsageFromURL($url) { global $global; if (!empty($global['doNotGetUsageFromURL'])) { // manually add this variable in your configuration.php file to not scan your video usage return 0; } _error_log("getUsageFromURL: start ({$url})"); // Assume failure. $result = false; $curl = curl_init($url); _error_log("getUsageFromURL: curl_init "); try { // Issue a HEAD request and follow any redirects. curl_setopt($curl, CURLOPT_NOBODY, true); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); //curl_setopt($curl, CURLOPT_USERAGENT, get_user_agent_string()); $data = curl_exec($curl); } catch (Exception $exc) { echo $exc->getTraceAsString(); _error_log("getUsageFromURL: ERROR " . $exc->getMessage()); _error_log("getUsageFromURL: ERROR " . curl_errno($curl)); _error_log("getUsageFromURL: ERROR " . curl_error($curl)); } if ($data) { _error_log("getUsageFromURL: response header " . $data); $content_length = "unknown"; $status = "unknown"; if (preg_match("/^HTTP\/1\.[01] (\d\d\d)/", $data, $matches)) { $status = (int) $matches[1]; } if (preg_match("/Content-Length: (\d+)/", $data, $matches)) { $content_length = (int) $matches[1]; } // http://en.wikipedia.org/wiki/List_of_HTTP_status_codes if ($status == 200 || ($status > 300 && $status <= 308)) { $result = $content_length; } } else { _error_log("getUsageFromURL: ERROR no response data " . curl_error($curl)); } curl_close($curl); return (int) $result; } function getDirSize($dir) { _error_log("getDirSize: start {$dir}"); if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { return foldersize($dir); } 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; } 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]); } _error_log("getDirSize: ERROR on pregmatch {$output[0]}"); return 0; } } } function foldersize($path) { $total_size = 0; $files = scandir($path); $cleanPath = rtrim($path, '/') . '/'; foreach ($files as $t) { if ($t <> "." && $t <> "..") { $currentFile = $cleanPath . $t; if (is_dir($currentFile)) { $size = foldersize($currentFile); $total_size += $size; } else { $size = filesize($currentFile); $total_size += $size; } } } return $total_size; } function getDiskUsage() { global $global; $dir = getVideosDir() . ""; $obj = new stdClass(); $obj->disk_free_space = disk_free_space($dir); $obj->disk_total_space = disk_total_space($dir); $obj->videos_dir = getDirSize($dir); $obj->disk_used = $obj->disk_total_space - $obj->disk_free_space; $obj->disk_used_by_other = $obj->disk_used - $obj->videos_dir; $obj->disk_free_space_human = humanFileSize($obj->disk_free_space); $obj->disk_total_space_human = humanFileSize($obj->disk_total_space); $obj->videos_dir_human = humanFileSize($obj->videos_dir); $obj->disk_used_human = humanFileSize($obj->disk_used); $obj->disk_used_by_other_human = humanFileSize($obj->disk_used_by_other); // percentage of disk used $obj->disk_used_percentage = sprintf('%.2f', ($obj->disk_used / $obj->disk_total_space) * 100); $obj->videos_dir_used_percentage = sprintf('%.2f', ($obj->videos_dir / $obj->disk_total_space) * 100); $obj->disk_free_space_percentage = sprintf('%.2f', ($obj->disk_free_space / $obj->disk_total_space) * 100); return $obj; } function unsetSearch() { unset($_GET['searchPhrase'], $_POST['searchPhrase'], $_GET['search'], $_GET['q']); } function encrypt_decrypt($string, $action) { global $global; $output = false; $encrypt_method = "AES-256-CBC"; $secret_key = 'This is my secret key'; $secret_iv = $global['systemRootPath']; while (strlen($secret_iv) < 16) { $secret_iv .= $global['systemRootPath']; } if (empty($secret_iv)) { $secret_iv = '1234567890abcdef'; } // hash $key = hash('sha256', $global['salt']); // iv - encrypt method AES-256-CBC expects 16 bytes - else you will get a warning $iv = substr(hash('sha256', $secret_iv), 0, 16); if ($action == 'encrypt') { $output = openssl_encrypt($string, $encrypt_method, $key, 0, $iv); $output = base64_encode($output); } elseif ($action == 'decrypt') { $output = openssl_decrypt(base64_decode($string), $encrypt_method, $key, 0, $iv); } return $output; } function compressString($string) { if (function_exists("gzdeflate")) { $string = gzdeflate($string, 9); } return $string; } function decompressString($string) { if (function_exists("gzinflate")) { $string = gzinflate($string); } return $string; } function encryptString($string) { if (is_object($string)) { $string = json_encode($string); } return encrypt_decrypt($string, 'encrypt'); } function decryptString($string) { return encrypt_decrypt($string, 'decrypt'); } function getToken($timeout = 0, $salt = "") { global $global; $obj = new stdClass(); $obj->salt = $global['salt'] . $salt; if (!empty($timeout)) { $obj->time = time(); $obj->timeout = $obj->time + $timeout; } else { $obj->time = strtotime("Today 00:00:00"); $obj->timeout = strtotime("Today 23:59:59"); $obj->timeout += cacheExpirationTime(); } $strObj = json_encode($obj); //_error_log("Token created: {$strObj}"); return encryptString($strObj); } function isTokenValid($token, $salt = "") { return verifyToken($token, $salt); } function verifyToken($token, $salt = "") { global $global; $obj = _json_decode(decryptString($token)); if (empty($obj)) { _error_log("verifyToken invalid token"); return false; } if ($obj->salt !== $global['salt'] . $salt) { _error_log("verifyToken salt fail"); return false; } $time = time(); if (!($time >= $obj->time && $time <= $obj->timeout)) { _error_log("verifyToken token timout time = $time; obj->time = $obj->time; obj->timeout = $obj->timeout"); return false; } return true; } class YPTvideoObject { public $id; public $title; public $description; public $thumbnails; public $channelTitle; public $videoLink; public function __construct($id, $title, $description, $thumbnails, $channelTitle, $videoLink) { $this->id = $id; $this->title = $title; $this->description = $description; $this->thumbnails = $thumbnails; $this->channelTitle = $channelTitle; $this->videoLink = $videoLink; } } function isToShowDuration($type) { $notShowTo = array('pdf', 'article', 'serie', 'zip', 'image', 'live', 'livelinks'); if (in_array($type, $notShowTo)) { return false; } else { return true; } } function _dieAndLogObject($obj, $prefix = "") { $objString = json_encode($obj); _error_log($prefix . $objString); die($objString); } function isAVideoPlayer() { if (isVideo() || isSerie()) { return true; } return false; } function isFirstPage() { global $isFirstPage, $global; return !empty($isFirstPage) || getSelfURI() === "{$global['webSiteRootURL']}view/"; } function isVideo() { global $isModeYouTube, $global; if (!empty($global['doNotLoadPlayer'])) { return false; } return !empty($isModeYouTube) || isPlayList() || isEmbed() || isLive(); } function isVideoTypeEmbed() { global $isVideoTypeEmbed; if (isVideo() && !empty($isVideoTypeEmbed) && $videos_id = getVideos_id()) { return $videos_id; } return false; } function isAudio() { global $isAudio; return !empty($isAudio); } function isSerie() { return isPlayList(); } function isPlayList() { global $isPlayList, $isSerie; return !empty($isSerie) || !empty($isPlayList); } function isChannel() { global $isChannel; if (!empty($isChannel) && !isVideo()) { $user_id = 0; if (empty($_GET['channelName'])) { if (User::isLogged()) { $user_id = User::getId(); } else { return false; } } else { $_GET['channelName'] = xss_esc($_GET['channelName']); $user = User::getChannelOwner($_GET['channelName']); if (!empty($user)) { $user_id = $user['id']; } else { $user_id = $_GET['channelName']; } } return $user_id; } return false; } function isEmbed() { global $isEmbed, $global; if (!empty($global['doNotLoadPlayer'])) { return false; } return !empty($isEmbed); } function isWebRTC() { global $isWebRTC, $global; if (!empty($global['doNotLoadPlayer'])) { return false; } return !empty($isWebRTC); } function isLive() { global $isLive, $global; if (!empty($global['doNotLoadPlayer'])) { return false; } if (!empty($isLive)) { $live = getLiveKey(); if (empty($live)) { $live = array('key' => false, 'live_servers_id' => false, 'live_index' => false); } $live['liveLink'] = isLiveLink(); return $live; } else { return false; } } function isLiveLink() { global $isLiveLink; if (!empty($isLiveLink)) { return $isLiveLink; } else { return false; } } function getLiveKey() { global $getLiveKey; if (empty($getLiveKey)) { return false; } return $getLiveKey; } function setLiveKey($key, $live_servers_id, $live_index = '') { global $getLiveKey; $parameters = Live::getLiveParametersFromKey($key); $key = $parameters['key']; $cleanKey = $parameters['cleanKey']; if (empty($live_index)) { $live_index = $parameters['live_index']; } $key = Live::getLiveKeyFromRequest($key, $live_index, $parameters['playlists_id_live']); $getLiveKey = array('key' => $key, 'live_servers_id' => intval($live_servers_id), 'live_index' => $live_index, 'cleanKey' => $cleanKey); return $getLiveKey; } function isVideoPlayerHasProgressBar() { if (isWebRTC()) { return false; } if (isLive()) { $obj = AVideoPlugin::getObjectData('Live'); if (empty($obj->disableDVR)) { return true; } } elseif (isAVideoPlayer()) { return true; } return false; } function isHLS() { global $video, $global; if (isLive()) { return true; } elseif (!empty($video) && $video['type'] == 'video' && file_exists(Video::getPathToFile("{$video['filename']}/index.m3u8"))) { return true; } return false; } function getRedirectUri() { if (!empty($_GET['redirectUri'])) { return $_GET['redirectUri']; } if (!empty($_SERVER["HTTP_REFERER"])) { return $_SERVER["HTTP_REFERER"]; } return getRequestURI(); } function getRedirectToVideo($videos_id) { $redirectUri = getRedirectUri(); $isEmbed = 0; if (stripos($redirectUri, "embed") !== false) { $isEmbed = 1; } $video = Video::getVideoLight($videos_id); if (empty($video)) { return false; } return Video::getLink($videos_id, $video['clean_title'], $isEmbed); } function getRequestURI() { if (empty($_SERVER['REQUEST_URI'])) { return ""; } return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"; } function getSelfURI() { if (empty($_SERVER['PHP_SELF']) || empty($_SERVER['HTTP_HOST'])) { return ""; } $queryStringWithoutError = preg_replace("/error=[^&]*/", "", @$_SERVER['QUERY_STRING']); $phpselfWithoutIndex = preg_replace("/index.php/", "", @$_SERVER['PHP_SELF']); $url = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] === 'on' ? "https" : "http") . "://$_SERVER[HTTP_HOST]$phpselfWithoutIndex?$queryStringWithoutError"; $url = rtrim($url, '?'); return $url; } function isSameVideoAsSelfURI($url) { return URLsAreSameVideo($url, getSelfURI()); } function URLsAreSameVideo($url1, $url2) { $videos_id1 = getVideoIDFromURL($url1); $videos_id2 = getVideoIDFromURL($url2); if (empty($videos_id1) || empty($videos_id2)) { return false; } return $videos_id1 === $videos_id2; } function getVideos_id() { global $_getVideos_id; $videos_id = false; if (isset($_getVideos_id) && is_int($_getVideos_id)) { return $_getVideos_id; } if (isVideo()) { $videos_id = getVideoIDFromURL(getSelfURI()); if (empty($videos_id) && !empty($_REQUEST['videoName'])) { $video = Video::getVideoFromCleanTitle($_REQUEST['videoName']); if (!empty($video)) { $videos_id = $video['id']; } } setVideos_id($videos_id); } if (empty($videos_id) && !empty($_REQUEST['playlists_id'])) { AVideoPlugin::loadPlugin('PlayLists'); $video = PlayLists::isPlayListASerie($_REQUEST['playlists_id']); if (!empty($video)) { $videos_id = $video['id']; } } if (empty($videos_id) && !empty($_REQUEST['v'])) { $videos_id = $_REQUEST['v']; } $videos_id = videosHashToID($videos_id); return $videos_id; } function setVideos_id($videos_id) { global $_getVideos_id; $_getVideos_id = $videos_id; } function getPlaylists_id() { global $_isPlayList; if (!isset($_isPlayList)) { $_isPlayList = false; if (isPlayList()) { $_isPlayList = intval(@$_GET['playlists_id']); if (empty($_isPlayList)) { $videos_id = getVideos_id(); if (empty($videos_id)) { $_isPlayList = false; } else { $v = Video::getVideoLight($videos_id); if (empty($v) || empty($v['serie_playlists_id'])) { $_isPlayList = false; } else { $_isPlayList = $v['serie_playlists_id']; } } } } } return $_isPlayList; } function isVideoOrAudioNotEmbed() { if (!isVideo()) { return false; } $videos_id = getVideos_id(); if (empty($videos_id)) { return false; } $v = Video::getVideoLight($videos_id); if (empty($v)) { return false; } $types = array('audio', 'video'); if (in_array($v['type'], $types)) { return true; } return false; } function getVideoIDFromURL($url) { if (preg_match("/v=([0-9]+)/", $url, $matches)) { return intval($matches[1]); } if (preg_match('/\/(video|videoEmbed|v|vEmbed|article|articleEmbed)\/([0-9]+)/', $url, $matches)) { return intval($matches[1]); } if (AVideoPlugin::isEnabledByName('PlayLists')) { if (preg_match('/player.php\?playlists_id=([0-9]+)/', $url, $matches)) { $serie_playlists_id = intval($matches[1]); $video = PlayLists::isPlayListASerie($serie_playlists_id); if ($video) { return $video['id']; } } } if (preg_match("/v=(\.[0-9a-zA-Z_-]+)/", $url, $matches)) { return hashToID($matches[1]); } if (preg_match('/\/(video|videoEmbed|v|vEmbed|article|articleEmbed)\/(\.[0-9a-zA-Z_-]+)/', $url, $matches)) { return hashToID($matches[2]); } return false; } function getBackURL() { global $global; $backURL = getRedirectUri(); if (empty($backURL)) { $backURL = getRequestURI(); } if (isSameVideoAsSelfURI($backURL)) { $backURL = getHomeURL(); } return $backURL; } function getHomeURL() { global $global, $advancedCustomUser, $advancedCustom; if (isValidURL($advancedCustomUser->afterLoginGoToURL)) { return $advancedCustomUser->afterLoginGoToURL; } elseif (isValidURL($advancedCustom->logoMenuBarURL) && isSameDomainAsMyAVideo($advancedCustom->logoMenuBarURL)) { return $advancedCustom->logoMenuBarURL; } return $global['webSiteRootURL']; } function isValidURL($url) { //var_dump(empty($url), !is_string($url), preg_match("/^http.*/", $url), filter_var($url, FILTER_VALIDATE_URL)); if (empty($url) || !is_string($url)) { return false; } if (preg_match("/^http.*/", $url) && filter_var($url, FILTER_VALIDATE_URL)) { return true; } return false; } function hasLastSlash($word) { return substr($word, -1) === '/'; } function addLastSlash($word) { return $word . (hasLastSlash($word) ? "" : "/"); } function URLHasLastSlash() { return hasLastSlash($_SERVER["REQUEST_URI"]); } function ucname($str) { $str = ucwords(strtolower($str)); foreach (array('\'', '-') as $delim) { if (strpos($str, $delim) !== false) { $str = implode($delim, array_map('ucfirst', explode($delim, $str))); } } return $str; } function sanitize_input($input) { return htmlentities(strip_tags($input)); } function sanitize_array_item(&$item, $key) { $item = sanitize_input($item); } function getSEOComplement($parameters = array()) { global $config; $allowedTypes = isset($parameters["allowedTypes"]) ? $parameters["allowedTypes"] : null; $addAutoPrefix = isset($parameters["addAutoPrefix"]) ? $parameters["addAutoPrefix"] : true; $addCategory = isset($parameters["addCategory"]) ? $parameters["addCategory"] : true; $parts = array(); if (!empty($_GET['error'])) { array_push($parts, __("Error")); } if ($addCategory && !empty($_GET['catName'])) { array_push($parts, $_GET['catName']); } if (!empty($_GET['channelName'])) { array_push($parts, $_GET['channelName']); } if (!empty($_GET['type'])) { $type = $_GET['type']; if (empty($allowedTypes) || in_array(strtolower($type), $allowedTypes)) { array_push($parts, __(ucname($type))); } } if (!empty($_GET['showOnly'])) { array_push($parts, $_GET['showOnly']); } if (!empty($_GET['page'])) { $page = intval($_GET['page']); if ($page > 1) { array_push($parts, sprintf(__("Page %d"), $page)); } } // Cleaning all entries in the $parts array array_walk($parts, 'sanitize_array_item'); $txt = implode($config->getPageTitleSeparator(), $parts); $txt = (!empty($txt) && $addAutoPrefix ? $config->getPageTitleSeparator() : "") . $txt; return $txt; } function getCurrentPage() { if (!empty($_REQUEST['current'])) { return intval($_REQUEST['current']); } elseif (!empty($_POST['current'])) { return intval($_POST['current']); } elseif (!empty($_GET['current'])) { return intval($_GET['current']); } elseif (isset($_GET['start']) && isset($_GET['length'])) { // for the bootgrid $start = intval($_GET['start']); $length = intval($_GET['length']); if (!empty($start) && !empty($length)) { return floor($start / $length) + 1; } } return 1; } function getRowCount($default = 1000) { global $global; if (!empty($_REQUEST['rowCount'])) { $defaultN = intval($_REQUEST['rowCount']); } elseif (!empty($_POST['rowCount'])) { $defaultN = intval($_POST['rowCount']); } elseif (!empty($_GET['rowCount'])) { $defaultN = intval($_GET['rowCount']); } elseif (!empty($_REQUEST['length'])) { $defaultN = intval($_REQUEST['length']); } elseif (!empty($_POST['length'])) { $defaultN = intval($_POST['length']); } elseif (!empty($_GET['length'])) { $defaultN = intval($_GET['length']); } elseif (!empty($global['rowCount'])) { $defaultN = intval($global['rowCount']); } return (!empty($defaultN) && $defaultN > 0) ? $defaultN : $default; } function getSearchVar() { if (!empty($_REQUEST['search'])) { return $_REQUEST['search']; } elseif (!empty($_REQUEST['q'])) { return $_REQUEST['q']; } if (!empty($_REQUEST['searchPhrase'])) { return $_REQUEST['searchPhrase']; } elseif (!empty($_REQUEST['search']['value'])) { return $_REQUEST['search']['value']; } return ""; } $cleanSearchHistory = ""; function cleanSearchVar() { global $cleanSearchHistory; $search = getSearchVar(); if (!empty($search)) { $cleanSearchHistory = $search; } $searchIdex = array('q', 'searchPhrase', 'search'); foreach ($searchIdex as $value) { unset($_REQUEST[$value], $_POST[$value], $_GET[$value]); } } function reloadSearchVar() { global $cleanSearchHistory; $_REQUEST['search'] = $cleanSearchHistory; if (empty($_GET['search'])) { $_GET['search'] = $cleanSearchHistory; } if (empty($_POST['search'])) { $_POST['search'] = $cleanSearchHistory; } } function wget($url, $filename, $debug = false) { if (empty($url) || $url == "php://input" || !preg_match("/^http/", $url)) { return false; } if (wgetIsLocked($url)) { if ($debug) { _error_log("wget: ERROR the url is already downloading $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; } $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. * * @param $infile The full URL to the remote file * @param $outfile The path where to save the file */ function copyfile_chunked($infile, $outfile) { $chunksize = 10 * (1024 * 1024); // 10 Megs /** * parse_url breaks a part a URL into it's parts, i.e. host, path, * query string, etc. */ $parts = parse_url($infile); $i_handle = fsockopen($parts['host'], 80, $errstr, $errcode, 5); $o_handle = fopen($outfile, 'wb'); if ($i_handle == false || $o_handle == false) { return false; } if (!empty($parts['query'])) { $parts['path'] .= '?' . $parts['query']; } /** * Send the request to the server for the file */ $request = "GET {$parts['path']} HTTP/1.1\r\n"; $request .= "Host: {$parts['host']}\r\n"; $request .= "User-Agent: Mozilla/5.0\r\n"; $request .= "Keep-Alive: 115\r\n"; $request .= "Connection: keep-alive\r\n\r\n"; fwrite($i_handle, $request); /** * Now read the headers from the remote server. We'll need * to get the content length. */ $headers = array(); while (!feof($i_handle)) { $line = fgets($i_handle); if ($line == "\r\n") break; $headers[] = $line; } /** * Look for the Content-Length header, and get the size * of the remote file. */ $length = 0; foreach ($headers as $header) { if (stripos($header, 'Content-Length:') === 0) { $length = (int) str_replace('Content-Length: ', '', $header); break; } } /** * Start reading in the remote file, and writing it to the * local file one chunk at a time. */ $cnt = 0; while (!feof($i_handle)) { $buf = ''; $buf = fread($i_handle, $chunksize); $bytes = fwrite($o_handle, $buf); if ($bytes == false) { return false; } $cnt += $bytes; /** * We're done reading when we've reached the conent length */ if ($cnt >= $length) break; } fclose($i_handle); fclose($o_handle); return $cnt; } function wgetLockFile($url) { return getTmpDir("YPTWget") . md5($url) . ".lock"; } function wgetLock($url) { $file = wgetLockFile($url); return file_put_contents($file, time() . PHP_EOL, FILE_APPEND | LOCK_EX); } function wgetRemoveLock($url) { $filename = wgetLockFile($url); if (!file_exists($filename)) { return false; } return unlink($filename); } function getLockFile($name) { return getTmpDir("YPTLockFile") . md5($name) . ".lock"; } function setLock($name) { $file = getLockFile($name); return file_put_contents($file, time()); } function isLock($name, $timeout = 60) { $file = getLockFile($name); if (file_exists($file)) { $time = intval(file_get_contents($file)); if ($time + $timeout < time()) { return false; } } } function removeLock($name) { $filename = getLockFile($name); if (!file_exists($filename)) { return false; } return unlink($filename); } function wgetIsLocked($url) { $filename = wgetLockFile($url); if (!file_exists($filename)) { return false; } $time = intval(file_get_contents($filename)); if (time() - $time > 36000) { // more then 10 hours unlink($filename); return false; } return true; } // due the some OS gives a fake is_writable response function isWritable($dir) { $dir = rtrim($dir, '/') . '/'; $file = $dir . uniqid(); $result = false; $time = time(); if (@file_put_contents($file, $time)) { if ($fileTime = @file_get_contents($file)) { if ($fileTime == $time) { $result = true; } } } @unlink($file); return $result; } function _isWritable($dir) { if (!isWritable($dir)) { return false; } $tmpFile = "{$dir}" . uniqid(); $bytes = @file_put_contents($tmpFile, time()); @unlink($tmpFile); return !empty($bytes); } function getTmpDir($subdir = "") { global $global; if (empty($_SESSION['getTmpDir'])) { $_SESSION['getTmpDir'] = array(); } if (empty($_SESSION['getTmpDir'][$subdir . "_"])) { if (empty($global['tmpDir'])) { $tmpDir = sys_get_temp_dir(); if (empty($tmpDir) || !_isWritable($tmpDir)) { $tmpDir = getVideosDir() . "cache" . DIRECTORY_SEPARATOR; } $tmpDir = rtrim($tmpDir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $tmpDir = "{$tmpDir}{$subdir}"; } else { $tmpDir = $global['tmpDir']; } $tmpDir = addLastSlash($tmpDir); if (!is_dir($tmpDir)) { mkdir($tmpDir, 0755, true); } _session_start(); $_SESSION['getTmpDir'][$subdir . "_"] = $tmpDir; } else { $tmpDir = $_SESSION['getTmpDir'][$subdir . "_"]; } return $tmpDir; } function getTmpFile() { return getTmpDir("tmpFiles") . uniqid(); } function getMySQLDate() { global $global; $sql = "SELECT now() as time FROM configurations LIMIT 1"; // I had to add this because the about from customize plugin was not loading on the about page http://127.0.0.1/AVideo/about $res = sqlDAL::readSql($sql); $data = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { $row = $data['time']; } else { $row = false; } return $row; } function _file_put_contents($filename, $data, $flags = 0, $context = null) { make_path($filename); return file_put_contents($filename, $data, $flags, $context); } function html2plainText($html) { $text = strip_tags($html); $text = str_replace(array('\\', "\n", "\r", '"'), array('', ' ', ' ', ''), trim($text)); return $text; } function getInputPassword($id, $attributes = 'class="form-control"', $paceholder = '') { if (empty($paceholder)) { $paceholder = __("Password"); } ?>
>
>
" . PHP_EOL; } else { return __LINE__; } $object = object_to_array($object); $json = json_encode($object); if (json_last_error()) { echo "Error 1 Found after array conversion: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } $json = json_encode($object, JSON_UNESCAPED_UNICODE); if (json_last_error()) { echo "Error 1 Found with JSON_UNESCAPED_UNICODE: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } $objectEncoded = $object; array_walk_recursive($objectEncoded, function (&$item) { if (is_string($item)) { $item = utf8_encode($item); } }); $json = json_encode($objectEncoded); if (json_last_error()) { echo "Error 2 Found after array conversion: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } $json = json_encode($objectEncoded, JSON_UNESCAPED_UNICODE); if (json_last_error()) { echo "Error 2 Found with JSON_UNESCAPED_UNICODE: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } $objectDecoded = $object; array_walk_recursive($objectDecoded, function (&$item) { if (is_string($item)) { $item = utf8_decode($item); } }); $json = json_encode($objectDecoded); if (json_last_error()) { echo "Error 2 Found after array conversion: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } $json = json_encode($objectDecoded, JSON_UNESCAPED_UNICODE); if (json_last_error()) { echo "Error 2 Found with JSON_UNESCAPED_UNICODE: " . json_last_error_msg() . "
" . PHP_EOL; } else { return __LINE__; } return false; } function _json_encode($object) { if (empty($object)) { return false; } if (is_string($object)) { return $object; } $json = json_encode($object); if (json_last_error()) { _error_log("_json_encode: Error 1 Found: " . json_last_error_msg()); $object = object_to_array($object); $json = json_encode($object); if (json_last_error()) { _error_log("_json_encode: Error 2 Found: " . json_last_error_msg()); $json = json_encode($object, JSON_UNESCAPED_UNICODE); if (json_last_error()) { _error_log("_json_encode: Error 3 Found: " . json_last_error_msg()); $objectEncoded = $object; array_walk_recursive($objectEncoded, function (&$item) { if (is_string($item)) { $item = utf8_encode($item); } }); $json = json_encode($objectEncoded); if (json_last_error()) { _error_log("_json_encode: Error 4 Found: " . json_last_error_msg()); $json = json_encode($objectEncoded, JSON_UNESCAPED_UNICODE); if (json_last_error()) { _error_log("_json_encode: Error 5 Found: " . json_last_error_msg()); $objectDecoded = $object; array_walk_recursive($objectDecoded, function (&$item) { if (is_string($item)) { $item = utf8_decode($item); } }); $json = json_encode($objectDecoded); if (json_last_error()) { _error_log("_json_encode: Error 6 Found: " . json_last_error_msg()); $json = json_encode($objectDecoded, JSON_UNESCAPED_UNICODE); if (json_last_error()) { _error_log("_json_encode: Error 7 Found: " . json_last_error_msg()); } } } } } } } return $json; } function _json_decode($object) { if (empty($object)) { return false; } if (!is_string($object)) { return $object; } $json = json_decode($object); if ($json === NULL) { $object = str_replace(array("\r", "\n"), array('\r', '\n'), $object); return json_decode($object); } else { return $json; } } // this will make sure the strring will fits in the database field function _substr($string, $start, $length = null) { // make sure the name is not chunked in case of multibyte string if (function_exists("mb_strcut")) { return mb_strcut($string, $start, $length, "UTF-8"); } else { return substr($string, $start, $length); } } function getPagination($total, $page = 0, $link = "", $maxVisible = 10, $infinityScrollGetFromSelector = "", $infinityScrollAppendIntoSelector = "") { global $global, $advancedCustom; if ($total < 2) { return ''; } if (empty($page)) { $page = getCurrentPage(); } $isInfiniteScroll = !empty($infinityScrollGetFromSelector) && !empty($infinityScrollAppendIntoSelector); $uid = md5($link); if ($total < $maxVisible) { $maxVisible = $total; } if (empty($link)) { $link = getSelfURI(); if (preg_match("/(current=[0-9]+)/i", $link, $match)) { $link = str_replace($match[1], "current={page}", $link); } else { //$link = addQueryStringParameter($link, 'current', '{page}'); $link .= (parse_url($link, PHP_URL_QUERY) ? '&' : '?') . 'current={page}'; } } $class = ""; if (!empty($infinityScrollGetFromSelector) && !empty($infinityScrollAppendIntoSelector)) { $class = "infiniteScrollPagination{$uid} hidden"; } if ($isInfiniteScroll && $page > 1) { if (preg_match("/\{page\}/", $link, $match)) { $pageForwardLink = str_replace("{page}", $page + 1, $link); } else { $pageForwardLink = addQueryStringParameter($link, 'current', $page + 1); } return ""; } $pag = ' '; if ($isInfiniteScroll) { $content = file_get_contents($global['systemRootPath'] . 'objects/functiongetPagination.php'); $pag .= str_replace( array('$uid', '$webSiteRootURL', '$infinityScrollGetFromSelector', '$infinityScrollAppendIntoSelector'), array($uid, $global['webSiteRootURL'], $infinityScrollGetFromSelector, $infinityScrollAppendIntoSelector), $content ); } return $pag; } function getShareMenu($title, $permaLink, $URLFriendly, $embedURL, $img, $class = "row bgWhite list-group-item menusDiv") { global $global, $advancedCustom; include $global['systemRootPath'] . 'objects/functiongetShareMenu.php'; } function getSharePopupButton($videos_id, $url = "", $title = "") { global $global, $advancedCustom; if ($advancedCustom->disableShareOnly || $advancedCustom->disableShareAndPlaylist) { return false; } $video['id'] = $videos_id; include $global['systemRootPath'] . 'view/include/socialModal.php'; } function forbiddenPage($message, $logMessage = false) { global $global; $_REQUEST['403ErrorMsg'] = $message; if ($logMessage) { _error_log($message); } include $global['systemRootPath'] . 'view/forbiddenPage.php'; exit; } define('E_FATAL', E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR); if (!isCommandLineInterface() && !isAVideoEncoder()) { register_shutdown_function('avidoeShutdown'); } function avidoeShutdown() { global $global; $error = error_get_last(); if ($error && ($error['type'] & E_FATAL)) { _error_log($error, AVideoLog::$ERROR); header($_SERVER['SERVER_PROTOCOL'] . ' 500 Internal Server Error', true, 500); if (!User::isAdmin()) { if (!preg_match('/json\.php$/i', $_SERVER['PHP_SELF'])) { echo '' . PHP_EOL; include $global['systemRootPath'] . 'view/maintanance.html'; } else { $o = new stdClass(); $o->error = true; $o->msg = __('Under Maintanance'); echo json_encode($o); } } else { var_dump($error); } exit; } } function videoNotFound($message, $logMessage = false) { global $global; $_REQUEST['404ErrorMsg'] = $message; if ($logMessage) { _error_log($message); } include $global['systemRootPath'] . 'view/videoNotFound.php'; exit; } function isForbidden() { global $global; if (!empty($global['isForbidden'])) { return true; } return false; } function diskUsageBars() { global $global; ob_start(); include $global['systemRootPath'] . 'objects/functiondiskUsageBars.php'; $contents = ob_get_contents(); ob_end_clean(); return $contents; } function getDomain() { global $global, $_getDomain; if (isset($_getDomain)) { return $_getDomain; } if (empty($_SERVER['HTTP_HOST'])) { $parse = parse_url($global['webSiteRootURL']); $domain = $parse['host']; } else { $domain = $_SERVER['HTTP_HOST']; } $domain = str_replace("www.", "", $domain); $domain = preg_match("/^\..+/", $domain) ? ltrim($domain, '.') : $domain; $_getDomain = $domain; return $domain; } /** * It's separated by time, version, clock_seq_hi, clock_seq_lo, node, as indicated in the followoing rfc. * * From the IETF RFC4122: * 8-4-4-4-12 * @return string */ function getDeviceID($useRandomString = true) { $ip = md5(getRealIpAddr()); if (empty($_SERVER['HTTP_USER_AGENT'])) { $device = "unknowDevice-{$ip}"; $device .= '-' . intval(User::getId()); return $device; } if (empty($useRandomString)) { $device = 'ypt-' . get_browser_name() . '-' . getOS() . '-' . $ip . '-' . md5($_SERVER['HTTP_USER_AGENT']); $device = str_replace( array('[', ']', ' '), array('', '', '_'), $device); $device .= '-' . intval(User::getId()); return $device; } $cookieName = "yptDeviceID"; if (empty($_COOKIE[$cookieName])) { if (empty($_GET[$cookieName])) { $id = uniqidV4(); $_GET[$cookieName] = $id; } if (empty($_SESSION[$cookieName])) { _session_start(); $_SESSION[$cookieName] = $_GET[$cookieName]; } else { $_GET[$cookieName] = $_SESSION[$cookieName]; } if (!_setcookie($cookieName, $_GET[$cookieName], strtotime("+ 1 year"))) { return "getDeviceIDError"; } $_COOKIE[$cookieName] = $_GET[$cookieName]; return $_GET[$cookieName]; } return $_COOKIE[$cookieName]; } function deviceIdToObject($deviceID) { $parts = explode('-', $deviceID); $obj = new stdClass(); $obj->browser = ''; $obj->os = ''; $obj->ip = ''; $obj->user_agent = ''; $obj->users_id = 0; foreach ($parts as $key => $value) { $parts[$key] = str_replace('_', ' ', $value); } switch ($parts[0]) { case 'ypt': $obj->browser = $parts[1]; $obj->os = $parts[2]; $obj->ip = $parts[3]; $obj->user_agent = $parts[4]; $obj->users_id = $parts[5]; break; case 'unknowDevice': $obj->browser = $parts[0]; $obj->os = 'unknow OS'; $obj->ip = $parts[1]; $obj->user_agent = 'unknow UA'; $obj->users_id = $parts[2]; break; default: break; } return $obj; } function uniqidV4() { $randomString = openssl_random_pseudo_bytes(16); $time_low = bin2hex(substr($randomString, 0, 4)); $time_mid = bin2hex(substr($randomString, 4, 2)); $time_hi_and_version = bin2hex(substr($randomString, 6, 2)); $clock_seq_hi_and_reserved = bin2hex(substr($randomString, 8, 2)); $node = bin2hex(substr($randomString, 10, 6)); /** * Set the four most significant bits (bits 12 through 15) of the * time_hi_and_version field to the 4-bit version number from * Section 4.1.3. * @see http://tools.ietf.org/html/rfc4122#section-4.1.3 */ $time_hi_and_version = hexdec($time_hi_and_version); $time_hi_and_version = $time_hi_and_version >> 4; $time_hi_and_version = $time_hi_and_version | 0x4000; /** * Set the two most significant bits (bits 6 and 7) of the * clock_seq_hi_and_reserved to zero and one, respectively. */ $clock_seq_hi_and_reserved = hexdec($clock_seq_hi_and_reserved); $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved >> 2; $clock_seq_hi_and_reserved = $clock_seq_hi_and_reserved | 0x8000; return sprintf('%08s-%04s-%04x-%04x-%012s', $time_low, $time_mid, $time_hi_and_version, $clock_seq_hi_and_reserved, $node); } // guid function _setcookie($cookieName, $value, $expires = 0) { if (empty($expires)) { if (empty($config) || !is_object($config)) { $config = new Configuration(); } $expires = time() + $config->getSession_timeout(); } if (version_compare(phpversion(), '7.3', '>=')) { $cookie_options = array( 'expires' => $expires, 'path' => '/', 'domain' => getDomain(), 'secure' => true, 'httponly' => false, 'samesite' => 'None'); return setcookie($cookieName, $value, $cookie_options); } else { return setcookie($cookieName, $value, (int) $expires, "/", getDomain()); } } function _unsetcookie($cookieName) { $domain = getDomain(); $expires = strtotime("-10 years"); $value = ""; _setcookie($cookieName, $value, $expires); setcookie($cookieName, $value, (int) $expires, "/") && setcookie($cookieName, $value, (int) $expires); setcookie($cookieName, $value, (int) $expires, "/", str_replace("www", "", $domain)); setcookie($cookieName, $value, (int) $expires, "/", "www." . $domain); setcookie($cookieName, $value, (int) $expires, "/", "." . $domain); setcookie($cookieName, $value, (int) $expires, "/", $domain); setcookie($cookieName, $value, (int) $expires, "/"); setcookie($cookieName, $value, (int) $expires); unset($_COOKIE[$cookieName]); } /** * This function is not 100% but try to tell if the site is in an iFrame * @global type $global * @return boolean */ function isIframeInDifferentDomain() { global $global; if (!isIframe()) { return false; } return isSameDomainAsMyAVideo($_SERVER['HTTP_REFERER']); } function isIframe() { global $global; if (isset($_SERVER['HTTP_SEC_FETCH_DEST']) && $_SERVER['HTTP_SEC_FETCH_DEST'] === 'iframe') { return true; } if (empty($_SERVER['HTTP_REFERER']) || $_SERVER['HTTP_REFERER'] == $global['webSiteRootURL'] || str_replace('view/', '', getSelfURI()) == $global['webSiteRootURL']) { return false; } return true; } function getCredentialsURL() { global $global; return "webSiteRootURL=" . urlencode($global['webSiteRootURL']) . "&user=" . urlencode(User::getUserName()) . "&pass=" . urlencode(User::getUserPass()) . "&encodedPass=1"; } function gotToLoginAndComeBackHere($msg) { global $global; if (User::isLogged()) { forbiddenPage($msg); exit; } if (!empty($_GET['comebackhere'])) { return false; } header("Location: {$global['webSiteRootURL']}user?redirectUri=" . urlencode(getSelfURI()) . "&msg=" . urlencode($msg) . "&comebackhere=1"); exit; } function setAlertMessage($msg, $type = "msg") { _session_start(); $_SESSION['YPTalertMessage'][] = array($msg, $type); } function setToastMessage($msg) { setAlertMessage($msg, "toast"); } function showAlertMessage() { if (!empty($_SESSION['YPTalertMessage'])) { foreach ($_SESSION['YPTalertMessage'] as $value) { if (!empty($value[0])) { if (empty($_GET[$value[1]])) { $_GET[$value[1]] = array(); } $_GET[$value[1]][] = $value[0]; } } _session_start(); unset($_SESSION['YPTalertMessage']); } $joinString = array('error', 'msg', 'success'); foreach ($joinString as $value) { if (!empty($_GET[$value]) && is_array($_GET[$value])) { $_GET[$value] = array_unique($_GET[$value]); $newStr = array(); foreach ($_GET[$value] as $value2) { if (!empty($value2)) { $newStr[] = $value2; } } $_GET[$value] = implode("
", $newStr); } } $check = array('error', 'msg', 'success', 'toast'); foreach ($check as $value) { if (!empty($_GET[$value])) { if (is_array($_GET[$value])) { $newStr = array(); foreach ($_GET[$value] as $key => $value2) { $value2 = str_replace('"', "''", $value2); if (!empty($value2)) { $newStr[] = $value2; } } $_GET[$value] = $newStr; } else { $_GET[$value] = str_replace('"', "''", $_GET[$value]); } } } echo "/** showAlertMessage **/", PHP_EOL; if (!empty($_GET['error'])) { echo 'avideoAlertError("' . $_GET['error'] . '");'; echo 'window.history.pushState({}, document.title, "' . getSelfURI() . '");'; } if (!empty($_GET['msg'])) { echo 'avideoAlertInfo("' . $_GET['msg'] . '");'; echo 'window.history.pushState({}, document.title, "' . getSelfURI() . '");'; } if (!empty($_GET['success'])) { echo 'avideoAlertSuccess("' . $_GET['success'] . '");'; echo 'window.history.pushState({}, document.title, "' . getSelfURI() . '");'; } if (!empty($_GET['toast'])) { if (!is_array($_GET['toast'])) { $_GET['toast'] = array($_GET['toast']); } else { $_GET['toast'] = array_unique($_GET['toast']); } foreach ($_GET['toast'] as $key => $value) { $hideAfter = strlen(strip_tags($value)) * 150; if ($hideAfter < 3000) { $hideAfter = 3000; } if ($hideAfter > 15000) { $hideAfter = 15000; } echo '$.toast({ text: "' . $value . '", hideAfter: ' . $hideAfter . ' // in milli seconds });console.log("Toast Hide after ' . $hideAfter . '");'; } echo 'window.history.pushState({}, document.title, "' . getSelfURI() . '");'; } echo PHP_EOL, "/** showAlertMessage END **/"; } function getResolutionLabel($res) { if ($res == 720) { return "" . getResolutionText($res) . ""; } elseif ($res == 1080) { return "" . getResolutionText($res) . ""; } elseif ($res == 1440) { return "" . getResolutionText($res) . ""; } elseif ($res == 2160) { return "" . getResolutionText($res) . ""; } elseif ($res == 4320) { return "" . getResolutionText($res) . ""; } else { return ''; } } function getResolutionText($res) { if ($res == 720) { return "HD"; } elseif ($res == 1080) { return "FHD"; } elseif ($res == 1440) { return "FHD+"; } elseif ($res == 2160) { return "4K"; } elseif ($res == 4320) { return "8K"; } else { return ''; } } // just realize the readdir is a lot faster then glob function _glob($dir, $pattern) { global $_glob; if (empty($dir)) { return array(); } if (empty($_glob)) { $_glob = array(); } $name = md5($dir . $pattern); if (isset($_glob[$name])) { return $_glob[$name]; } $dir = rtrim($dir, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; $array = array(); if (is_dir($dir) && $handle = opendir($dir)) { $count = 0; while (false !== ($file_name = readdir($handle))) { if ($file_name == '.' || $file_name == '..') { continue; } //_error_log("_glob: {$dir}{$file_name} [$pattern]"); //var_dump($pattern, $file_name, preg_match($pattern, $file_name)); if (preg_match($pattern, $file_name)) { $array[] = "{$dir}{$file_name}"; } } closedir($handle); } $_glob[$name] = $array; return $array; } function globVideosDir($filename, $filesOnly = false) { global $global; if (empty($filename)) { return array(); } $cleanfilename = Video::getCleanFilenameFromFile($filename); $paths = Video::getPaths($filename); ; $dir = $paths['path']; if (is_dir($dir . $filename)) { $dir = $dir . $filename; $cleanfilename = ''; } $pattern = "/{$cleanfilename}.*"; if (!empty($filesOnly)) { $formats = getValidFormats(); $pattern .= ".(" . implode("|", $formats) . ")"; } $pattern .= "/"; //var_dump($dir, $pattern); return _glob($dir, $pattern); } function getValidFormats() { $video = array('webm', 'mp4', 'm3u8'); $audio = array('mp3', 'ogg'); $image = array('jpg', 'gif', 'webp'); return array_merge($video, $audio, $image); } function isValidFormats($format) { $format = str_replace(".", "", $format); return in_array($format, getValidFormats()); } function getTimerFromDates($startTime, $endTime = 0) { if (!is_int($startTime)) { $startTime = strtotime($startTime); } if (!is_int($endTime)) { $endTime = strtotime($endTime); } if (empty($endTime)) { $endTime = time(); } $timer = abs($endTime - $startTime); $uid = uniqid(); return ""; } function getServerClock() { $id = uniqid(); $today = getdate(); $html = '00:00:00'; $html .= ""; return $html; } /** * Xsendfile and FFMPEG are required for this feature * @global type $global * @param type $filepath * @return boolean */ function downloadHLS($filepath) { global $global; if (!CustomizeUser::canDownloadVideos()) { _error_log("downloadHLS: CustomizeUser::canDownloadVideos said NO"); return false; } if (!file_exists($filepath)) { _error_log("downloadHLS: file NOT found: {$filepath}"); return false; } $output = m3u8ToMP4($filepath); if (empty($output)) { die("downloadHLS was not possible"); } $outputpath = $output['path']; $outputfilename = $output['filename']; if (!empty($_REQUEST['title'])) { $quoted = sprintf('"%s"', addcslashes(basename($_REQUEST['title']), '"\\')); } elseif (!empty($_REQUEST['file'])) { $quoted = sprintf('"%s"', addcslashes(basename($_REQUEST['file']), '"\\')) . ".mp4"; } else { $quoted = $outputfilename; } header('Content-Description: File Transfer'); header('Content-Disposition: attachment; filename=' . $quoted); header('Content-Transfer-Encoding: binary'); header('Connection: Keep-Alive'); header('Expires: 0'); header('Cache-Control: must-revalidate, post-check=0, pre-check=0'); header('Pragma: public'); header("X-Sendfile: {$outputpath}"); exit; } function playHLSasMP4($filepath) { global $global; if (!CustomizeUser::canDownloadVideos()) { _error_log("playHLSasMP4: CustomizeUser::canDownloadVideos said NO"); return false; } if (!file_exists($filepath)) { _error_log("playHLSasMP4: file NOT found: {$filepath}"); return false; } $output = m3u8ToMP4($filepath); if (empty($output)) { die("playHLSasMP4 was not possible"); } $outputpath = $output['path']; header('Cache-Control: no-store, no-cache, must-revalidate, max-age=0'); header('Cache-Control: post-check=0, pre-check=0', false); header('Pragma: no-cache'); header('Content-type: video/mp4'); header('Content-Length: ' . filesize($outputpath)); header("X-Sendfile: {$outputpath}"); exit; } function m3u8ToMP4($input) { $videosDir = getVideosDir(); $outputfilename = str_replace($videosDir, "", $input); $parts = explode("/", $outputfilename); $resolution = Video::getResolutionFromFilename($input); $outputfilename = $parts[0] . "_{$resolution}_.mp4"; $outputpath = "{$videosDir}cache/downloads/{$outputfilename}"; make_path($outputpath); if (empty($outputfilename)) { _error_log("downloadHLS: empty outputfilename {$outputfilename}"); return false; } //var_dump(!preg_match('/^http/i', $input), filesize($input), preg_match('/.m3u8$/i', $input)); if (!preg_match('/^http/i', $input) && (filesize($input) <= 10 || preg_match('/.m3u8$/i', $input))) { // dummy file $filepath = escapeshellcmd(pathToRemoteURL($input, true)); } else { $filepath = escapeshellcmd($input); } $outputpath = escapeshellcmd($outputpath); if (!file_exists($outputpath)) { $command = get_ffmpeg() . " -allowed_extensions ALL -y -i {$filepath} -c:v copy -c:a copy -bsf:a aac_adtstoasc -strict -2 {$outputpath}"; _error_log("downloadHLS: Exec Command ({$command})"); //var_dump($outputfilename, $command, $_GET, $filepath, $quoted);exit; exec($command . " 2>&1", $output, $return); if (!empty($return)) { _error_log("downloadHLS: ERROR 1 " . implode(PHP_EOL, $output)); $command = get_ffmpeg() . " -y -i {$filepath} -c:v copy -c:a copy -bsf:a aac_adtstoasc -strict -2 {$outputpath}"; //var_dump($outputfilename, $command, $_GET, $filepath, $quoted);exit; exec($command . " 2>&1", $output, $return); if (!empty($return)) { _error_log("downloadHLS: ERROR 2 " . implode(PHP_EOL, $output)); return false; } } } return array('path' => $outputpath, 'filename' => $outputfilename); } function getSocialModal($videos_id, $url = "", $title = "") { global $global; $video['id'] = $videos_id; $sharingUid = uniqid(); ob_start(); ?> $contents, 'id' => $sharingUid); } function getCroppie( $buttonTitle, $callBackJSFunction, $resultWidth, $resultHeight, $viewportWidth = 0, $boundary = 25, $viewportHeight = 0 ) { global $global; if (empty($viewportWidth)) { $viewportWidth = $resultWidth; } $zoom = 0; if (empty($viewportHeight)) { $zoom = ($viewportWidth / $resultWidth); $viewportHeight = $zoom * $resultHeight; } $boundaryWidth = $viewportWidth + $boundary; $boundaryHeight = $viewportHeight + $boundary; $uid = uniqid(); ob_start(); include $global['systemRootPath'] . 'objects/functionCroppie.php'; $contents = ob_get_contents(); ob_end_clean(); $callBackJSFunction = addcslashes($callBackJSFunction, "'"); return array( "html" => $contents, "id" => "croppie{$uid}", "uploadCropObject" => "uploadCrop{$uid}", "getCroppieFunction" => "getCroppie(uploadCrop{$uid}, '{$callBackJSFunction}', {$resultWidth}, {$resultHeight});", "createCroppie" => "createCroppie{$uid}", "restartCroppie" => "restartCroppie{$uid}" ); } function saveCroppieImage($destination, $postIndex = "imgBase64") { if (empty($_POST[$postIndex])) { return false; } $fileData = base64DataToImage($_POST[$postIndex]); return file_put_contents($destination, $fileData); } function get_ffmpeg($ignoreGPU = false) { global $global; //return 'ffmpeg -user_agent "'.getSelfUserAgent("FFMPEG").'" '; //return 'ffmpeg -headers "User-Agent: '.getSelfUserAgent("FFMPEG").'" '; $ffmpeg = 'ffmpeg '; if (empty($ignoreGPU) && !empty($global['ffmpegGPU'])) { $ffmpeg .= ' --enable-nvenc '; } if (!empty($global['ffmpeg'])) { $ffmpeg = "{$global['ffmpeg']}{$ffmpeg}"; } return $ffmpeg; } function isHTMLPage($url) { if (preg_match('/https?:\/\/(www\.)?(youtu.be|youtube.com|vimeo.com|bitchute.com)\//i', $url)) { return true; } else if ($type = getHeaderContentTypeFromURL($url)) { if (preg_match('/text\/html/i', $type)) { return true; } } return false; } function getHeaderContentTypeFromURL($url) { if (isValidURL($url) && $type = get_headers($url, 1)["Content-Type"]) { return $type; } return false; } function canFullScreen() { global $doNotFullScreen; if (!empty($doNotFullScreen) || isSerie() || !isVideo()) { return false; } return true; } function getTinyMCE($id) { global $global; ob_start(); include $global['systemRootPath'] . 'objects/functionsGetTinyMCE.php'; $contents = ob_get_contents(); ob_end_clean(); return $contents; } function pathToRemoteURL($filename, $forceHTTP = false) { global $pathToRemoteURL, $global; if (!isset($pathToRemoteURL)) { $pathToRemoteURL = array(); } if (isset($pathToRemoteURL[$filename])) { return $pathToRemoteURL[$filename]; } if (!file_exists($filename) || filesize($filename) < 1000) { $fileName = getFilenameFromPath($filename); if ($yptStorage = AVideoPlugin::loadPluginIfEnabled("YPTStorage")) { $source = $yptStorage->getAddress("{$fileName}"); $url = $source['url']; } else if (!preg_match('/index.m3u8$/', $filename)) { if ($aws_s3 = AVideoPlugin::loadPluginIfEnabled("AWS_S3")) { $source = $aws_s3->getAddress("{$fileName}"); $url = $source['url']; $url = replaceCDNIfNeed($url, 'CDN_S3'); } else if ($bb_b2 = AVideoPlugin::loadPluginIfEnabled("Blackblaze_B2")) { $source = $bb_b2->getAddress("{$fileName}"); $url = $source['url']; $url = replaceCDNIfNeed($url, 'CDN_B2'); } else if ($ftp = AVideoPlugin::loadPluginIfEnabled("FTP_Storage")) { $source = $ftp->getAddress("{$fileName}"); $url = $source['url']; $url = replaceCDNIfNeed($url, 'CDN_FTP'); } } } if (empty($url)) { if ($forceHTTP) { $paths = Video::getPaths($filename); //$url = str_replace(getVideosDir(), getCDN() . "videos/", $filename); $url = getCDN() . "{$paths['relative']}"; } else { $url = $filename; } } //$url = str_replace(array($global['systemRootPath'], '/videos/videos/'), array("", '/videos/'), $url); $pathToRemoteURL[$filename] = $url; return $url; } function getFilenameFromPath($path) { global $global; $fileName = Video::getCleanFilenameFromFile($path); return $fileName; } function showCloseButton() { global $global, $showCloseButtonIncluded; if (!empty($showCloseButtonIncluded)) { return ''; } if (isSerie()) { return ''; } if (!isLive() && $obj = AVideoPlugin::getDataObjectIfEnabled("Gallery")) { if (!empty($obj->playVideoOnFullscreen)) { $_REQUEST['showCloseButton'] = 1; } } if (isLive() && $obj = AVideoPlugin::getDataObjectIfEnabled("Live")) { if (!empty($obj->playLiveInFullScreen)) { $_REQUEST['showCloseButton'] = 1; } } if (!empty($_REQUEST['showCloseButton'])) { $showCloseButtonIncluded = 1; include $global['systemRootPath'] . 'view/include/youtubeModeOnFullscreenCloseButton.php'; } return ''; } function getThemes() { global $_getThemes, $global; if (isset($_getThemes)) { return $_getThemes; } $_getThemes = array(); foreach (glob("{$global['systemRootPath']}view/css/custom/*.css") as $filename) { $fileEx = basename($filename, ".css"); $_getThemes[] = $fileEx; } return $_getThemes; } function getCurrentTheme() { global $config; if (!empty($_REQUEST['customCSS'])) { _setcookie('customCSS', $_REQUEST['customCSS']); return $_REQUEST['customCSS']; } if (!empty($_COOKIE['customCSS'])) { return $_COOKIE['customCSS']; } return $config->getTheme(); } /* * $users_id="" or 0 means send messages to all users * $users_id="-1" means send to no one */ function sendSocketMessage($msg, $callbackJSFunction = "", $users_id = "-1", $send_to_uri_pattern = "") { if (AVideoPlugin::isEnabledByName('YPTSocket')) { if (!is_string($msg)) { $msg = json_encode($msg); } $obj = YPTSocket::send($msg, $callbackJSFunction, $users_id, $send_to_uri_pattern); if ($obj->error && !empty($obj->msg)) { _error_log("sendSocketMessage " . $obj->msg); } return $obj; } return false; } function sendSocketMessageToUsers_id($msg, $users_id, $callbackJSFunction = "") { if (!is_array($users_id)) { $users_id = array($users_id); } $resp = array(); foreach ($users_id as $value) { $resp[] = sendSocketMessage($msg, $callbackJSFunction, $value); } return $resp; } function sendSocketMessageToAll($msg, $callbackJSFunction = "", $send_to_uri_pattern = "") { return sendSocketMessage($msg, $callbackJSFunction, "", $send_to_uri_pattern); } function sendSocketMessageToNone($msg, $callbackJSFunction = "") { return sendSocketMessage($msg, $callbackJSFunction, -1); } function execAsync($command) { //$command = escapeshellarg($command); // If windows, else if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { //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: ' . json_encode($output) . ' ' . $retval); } else { $newCommand = $command . " > /dev/null 2>&1 & echo $!; "; _error_log($newCommand); $pid = exec($newCommand); } return $pid; } function killProcess($pid) { $pid = intval($pid); if (empty($pid)) { return false; } if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { exec("taskkill /F /PID $pid"); } else { exec("kill -9 $pid"); } return true; } 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; } } } } return false; } function isURL200($url, $forceRecheck = false) { global $_isURL200; $name = "isURL200" . DIRECTORY_SEPARATOR . md5($url); if (empty($forceRecheck)) { $result = ObjectYPT::getCache($name, 30); if (!empty($result)) { $object = _json_decode($result); return $object->result; } } $object = new stdClass(); $object->url = $url; $object->forceRecheck = $forceRecheck; //error_log("isURL200 checking URL {$url}"); $headers = @get_headers($url); if (!is_array($headers)) { $headers = array($headers); } $object->result = false; foreach ($headers as $value) { if ( strpos($value, '200') || strpos($value, '302') || strpos($value, '304') ) { $object->result = true; break; } else { //_error_log('isURL200: '.$value); } } ObjectYPT::setCache($name, json_encode($object)); return $object->result; } function isURL200Clear() { $tmpDir = ObjectYPT::getCacheDir(); $cacheDir = $tmpDir . "isURL200" . DIRECTORY_SEPARATOR; //_error_log("Live::isURL200Clear [{$cacheDir}]"); rrmdir($cacheDir); exec('rm -R ' . $cacheDir); } function getStatsNotifications($force_recreate = false) { $cacheName = "getStats" . DIRECTORY_SEPARATOR . "getStatsNotifications"; if ($force_recreate) { Live::deleteStatsCache(); } else { $json = ObjectYPT::getCache($cacheName, 0, true); } if (empty($json)) { //_error_log('getStatsNotifications: 1 ' . json_encode(debug_backtrace())); $json = Live::getStats(); $json = object_to_array($json); if (empty($json['applications']) && is_array($json)) { $json['applications'] = array(); foreach ($json as $key => $value) { if (empty($value['applications'])) { continue; } $json['applications'] = array_merge($json['applications'], $value['applications']); unset($json[$key]); } } $appArray = AVideoPlugin::getLiveApplicationArray(); if (!empty($appArray)) { if (empty($json)) { $json = array(); } $json['error'] = false; if (empty($json['msg'])) { $json['msg'] = "OFFLINE"; } $json['nclients'] = count($appArray); if (empty($json['applications'])) { $json['applications'] = array(); } $json['applications'] = array_merge($json['applications'], $appArray); } $count = 0; if (!isset($json['total'])) { $json['total'] = 0; } if (!empty($json['applications'])) { $json['total'] += count($json['applications']); } while (!empty($json[$count])) { $json['total'] += count($json[$count]['applications']); $count++; } if (empty($json['countLiveStream']) || $json['countLiveStream'] < $json['total']) { $json['countLiveStream'] = $json['total']; } if (!empty($json['applications'])) { foreach ($json['applications'] as $key => $value) { if (empty($value['users_id']) && !empty($value['user'])) { $u = User::getFromUsername($value['user']); $json['applications'][$key]['users_id'] = $u['id']; } } } $cache = ObjectYPT::setCache($cacheName, $json); _error_log('Live::createStatsCache ' . json_encode($cache)); } else { //_error_log('getStatsNotifications: 2 cached result'); $json = object_to_array($json); } return $json; } function getSocketConnectionLabel() { $html = ' ' . __('Disconnected') . ' ' . __('Connected') . ' '; return $html; } function getSocketVideoClassName($videos_id) { return 'total_on_videos_id_' . $videos_id; } function getSocketLiveClassName($key, $live_servers_id) { return 'total_on_live_' . $key . '_' . intval($live_servers_id); } function getSocketLiveLinksClassName($live_links_id) { return 'total_on_live_links_id_' . $live_links_id; } function getLiveUsersLabelVideo($videos_id, $totalViews = null, $viewsClass = "label label-default", $counterClass = "label label-primary") { if (AVideoPlugin::isEnabledByName('LiveUsers') && method_exists("LiveUsers", "getLabels")) { return LiveUsers::getLabels(getSocketVideoClassName($videos_id), $totalViews, $viewsClass, $counterClass, 'video'); } } function getLiveUsersLabelLive($key, $live_servers_id, $viewsClass = "label label-default", $counterClass = "label label-primary") { if (AVideoPlugin::isEnabledByName('LiveUsers') && method_exists("LiveUsers", "getLabels")) { $totalViews = 0; if (User::isLogged()) { $totalViews = LiveUsers::getTotalUsers($key, $live_servers_id); } return LiveUsers::getLabels(getSocketLiveClassName($key, $live_servers_id), $totalViews, $viewsClass, $counterClass, 'live'); } } function getLiveUsersLabelLiveLinks($liveLinks_id, $totalViews = null, $viewsClass = "label label-default", $counterClass = "label label-primary") { if (AVideoPlugin::isEnabledByName('LiveUsers') && method_exists("LiveUsers", "getWatchingNowLabel")) { return LiveUsers::getWatchingNowLabel(getSocketLiveLinksClassName($liveLinks_id), "label label-primary", '', $viewsClass, 'livelinks'); } } function getLiveUsersLabel($viewsClass = "label label-default", $counterClass = "label label-primary") { if (AVideoPlugin::isEnabledByName('LiveUsers')) { $live = isLive(); if (!empty($live)) { if (!empty($live['key'])) { return getLiveUsersLabelLive($live['key'], $live['live_servers_id'], $viewsClass, $counterClass); } else if (!empty($live['liveLinks_id'])) { return getLiveUsersLabelLiveLinks($live['liveLinks_id'], null, $viewsClass, $counterClass); } } else { $videos_id = getVideos_id(); if (!empty($videos_id)) { $v = new Video("", "", $videos_id); $totalViews = $v->getViews_count(); return getLiveUsersLabelVideo($videos_id, $totalViews, $viewsClass, $counterClass); } } } return ""; } function getLiveUsersLabelHTML($viewsClass = "label label-default", $counterClass = "label label-primary") { global $global; ob_start(); include $global['systemRootPath'] . 'plugin/Live/view/onlineLabel.php'; $htmlMediaTag = '
'; $htmlMediaTag .= ob_get_contents(); ob_end_clean(); $htmlMediaTag .= getLiveUsersLabel($viewsClass, $counterClass); $htmlMediaTag .= '
'; return $htmlMediaTag; } function getHTMLTitle($titleArray) { global $config, $global; if (!is_array($titleArray)) { $titleArray = array(); } $titleArray[] = $config->getWebSiteTitle(); $title = implode($config->getPageTitleSeparator(), $titleArray); $global['pageTitle'] = $title; return "{$title}"; } function getButtonSignInAndUp() { $signIn = getButtonSignIn(); $signUp = getButtonSignUp(); $html = $signIn . $signUp; if (!empty($signIn) && !empty($signIn)) { return '
' . $html . '
'; } else { return $html; } } function getButtonSignUp() { global $global; $obj = AVideoPlugin::getDataObject('CustomizeUser'); if (!empty($obj->disableNativeSignUp)) { return ''; } $url = $global['webSiteRootURL'] . 'signUp'; $url = addQueryStringParameter($url, 'redirectUri', getRedirectUri()); $html = ' ' . __("Sign Up") . ' '; return $html; } function getButtonSignIn() { global $global; $obj = AVideoPlugin::getDataObject('CustomizeUser'); if (!empty($obj->disableNativeSignIn)) { return ''; } $url = $global['webSiteRootURL'] . 'user'; $url = addQueryStringParameter($url, 'redirectUri', getRedirectUri()); $html = ' ' . __("Sign In") . ' '; return $html; } function getTitle() { global $global; if (empty($global['pageTitle'])) { $url = getSelfURI(); $global['pageTitle'] = str_replace($global['webSiteRootURL'], '', $url); if (preg_match('/\/plugin\/([^\/])/i', $url, $matches)) { $global['pageTitle'] = __('Plugin') . ' ' . __($matches[1]); } $title = $global['pageTitle']; } return $global['pageTitle']; } function outputAndContinueInBackground() { global $outputAndContinueInBackground; if (!empty($outputAndContinueInBackground)) { return false; } $outputAndContinueInBackground = 1; @session_write_close(); //_mysql_close(); // Instruct PHP to continue execution ignore_user_abort(true); if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } ob_start(); @header("Connection: close"); @header("Content-Length: " . ob_get_length()); @header("HTTP/1.1 200 OK"); ob_end_flush(); flush(); } function cleanUpRowFromDatabase($row) { if (is_array($row)) { foreach ($row as $key => $value) { if (preg_match('/pass/i', $key)) { unset($row[$key]); } } } return $row; } function getImageTransparent1pxURL() { global $global; return getCDN() . "view/img/transparent1px.png"; } function getDatabaseTime() { global $global, $_getDatabaseTime; if (isset($_getDatabaseTime)) { return $_getDatabaseTime; } $sql = "SELECT CURRENT_TIMESTAMP"; $res = sqlDAL::readSql($sql); $data = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { $row = $data; } else { $row = false; } $_getDatabaseTime = strtotime($row['CURRENT_TIMESTAMP']); return $_getDatabaseTime; } function get_js_availableLangs() { global $global; if (empty($global['js_availableLangs'])) { include_once $global['systemRootPath'] . 'objects/bcp47.php'; } return $global['js_availableLangs']; } function listAllWordsToTranslate() { global $global; $cacheName = 'listAllWordsToTranslate'; $cache = ObjectYPT::getCache($cacheName, 0); if (!empty($cache)) { return object_to_array($cache); } ini_set('max_execution_time', 300); function listAll($dir) { $vars = array(); if ($handle = opendir($dir)) { while (false !== ($entry = readdir($handle))) { if ($entry != "." && $entry != "..") { $filename = $dir . "/" . $entry; if (is_dir($filename)) { $vars = listAll($filename); } elseif (preg_match("/\.php$/", $entry)) { $data = file_get_contents($filename); $regex = '/__\(["\']{1}(.*)["\']{1}\)/U'; preg_match_all( $regex, $data, $matches ); foreach ($matches[0] as $key => $value) { $vars[$matches[1][$key]] = $matches[1][$key]; } } } } closedir($handle); } return $vars; } $vars = listAll($global['systemRootPath']); sort($vars); ObjectYPT::setCache($cacheName, $vars); return $vars; } function secondsInterval($time1, $time2) { if (!is_int($time1)) { $time1 = strtotime($time1); } if (!is_int($time2)) { $time2 = strtotime($time2); } return $time1 - $time2; } function secondsIntervalHuman($time, $useDatabaseTime = true) { $dif = secondsIntervalFromNow($time, $useDatabaseTime); if ($dif < 0) { return humanTimingAfterwards($time); } else { return humanTimingAgo($time); } } function secondsIntervalFromNow($time, $useDatabaseTime = true) { if ($useDatabaseTime) { return secondsInterval(getDatabaseTime(), $time); } else { return secondsInterval(time(), $time); } } function getScriptRunMicrotimeInSeconds() { global $global; $time_now = microtime(true); return ($time_now - $global['avideoStartMicrotime']); } function fixSystemPath() { global $global; $global['systemRootPath'] = fixPath($global['systemRootPath']); } function fixPath($path, $addLastSlash = false) { if (empty($path)) { return false; } if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { $path = str_replace('/', DIRECTORY_SEPARATOR, $path); $path = str_replace('\\\\\\', DIRECTORY_SEPARATOR, $path); } else { $path = str_replace('\\', DIRECTORY_SEPARATOR, $path); } if ($addLastSlash) { $path = rtrim($path, DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR; } return $path; } function idToHash($id) { global $global, $_idToHash; if (!isset($_idToHash)) { $_idToHash = array(); } if (!empty($_idToHash[$id])) { return $_idToHash[$id]; } if (!empty($global['useLongHash'])) { $base = 2; $cipher_algo = 'des'; } else { $base = 32; $cipher_algo = 'rc4'; } if (empty($global['salt'])) { $global['salt'] = '11234567890abcdef'; } $idConverted = base_convert($id, 10, $base); $hash = (@openssl_encrypt($idConverted, $cipher_algo, $global['salt'])); //$hash = preg_replace('/^([+]+)/', '', $hash); $hash = preg_replace('/(=+)$/', '', $hash); $hash = str_replace(array('/', '+', '='), array('_', '-', '.'), $hash); //return base64_encode($hash); $_idToHash[$id] = $hash; return $hash; } function hashToID($hash) { global $global; if (!empty($global['useLongHash'])) { $base = 2; $cipher_algo = 'des'; } else { $base = 32; $cipher_algo = 'rc4'; } //$hash = str_pad($hash, 4, "="); $hash = str_replace(array('_', '-', '.'), array('/', '+', '='), $hash); //$hash = base64_decode($hash); $decrypt = openssl_decrypt(($hash), $cipher_algo, $global['salt']); $decrypt = base_convert($decrypt, $base, 10); return intval($decrypt); } function videosHashToID($hash_of_videos_id) { if (is_int($hash_of_videos_id)) { return $hash_of_videos_id; } if (!is_string($hash_of_videos_id) && !is_numeric($hash_of_videos_id)) { return 0; } if (preg_match('/^\.([0-9a-z._-]+)/i', $hash_of_videos_id, $matches)) { $hash_of_videos_id = hashToID($matches[1]); } return $hash_of_videos_id; } /** * * @global type $advancedCustom * @global type $global * @global type $_getCDNURL * @param type $type enum(CDN, CDN_S3,CDN_B2,CDN_FTP,CDN_YPTStorage,CDN_Live,CDN_LiveServers) * @param type $id the ID of the URL in case the CDN is an array * @return \type */ function getCDN($type = 'CDN', $id = 0) { global $advancedCustom, $global, $_getCDNURL; $index = $type . $id; if (!isset($_getCDNURL)) { $_getCDNURL = array(); } if (empty($_getCDNURL[$index])) { if (!empty($type) && AVideoPlugin::isEnabledByName('CDN')) { $_getCDNURL[$index] = CDN::getURL($type, $id); } } if ($type == 'CDN') { if (!empty($global['ignoreCDN'])) { return $global['webSiteRootURL']; } else if (isValidURL($advancedCustom->videosCDN)) { $_getCDNURL[$index] = addLastSlash($advancedCustom->videosCDN); } else if (empty($_getCDNURL[$index])) { $_getCDNURL[$index] = $global['webSiteRootURL']; } } //var_dump($type, $id, $_getCDNURL[$index]); return empty($_getCDNURL[$index]) ? false : $_getCDNURL[$index]; } +function getURL($relativePath){ + global $global; + return getCDN().$relativePath.'?cache='.(@filemtime("{$global['systemRootPath']}{$relativePath}").(@filectime("{$global['systemRootPath']}{$relativePath}"))); +} + function getCDNOrURL($url, $type = 'CDN', $id = 0) { $cdn = getCDN($type, $id); if (!empty($cdn)) { return $cdn; } return addLastSlash($url); } function replaceCDNIfNeed($url, $type = 'CDN', $id = 0) { $cdn = getCDN($type, $id); if (empty($cdn)) { return $url; } return str_replace(parse_url($url, PHP_URL_HOST), parse_url($cdn, PHP_URL_HOST), $url); } function isIPPrivate($ip) { if ($ip == '192.168.1.4') { return false; } if (!filter_var($ip, FILTER_VALIDATE_IP)) { return false; } $result = filter_var( $ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE | FILTER_FLAG_NO_RES_RANGE); if (empty($result)) { return true; } return false; } function countDownPage($toTime, $message, $image, $bgImage) { global $global; include $global['systemRootPath'] . 'objects/functionCountDownPage.php'; exit; } function inputToRequest() { $content = file_get_contents("php://input"); if (!empty($content)) { $json = json_decode($content); if (empty($json)) { return false; } foreach ($json as $key => $value) { if (!isset($_REQUEST[$key])) { $_REQUEST[$key] = $value; } } } } function useVideoHashOrLogin() { if (!empty($_REQUEST['video_id_hash'])) { $videos_id = Video::getVideoIdFromHash($_REQUEST['video_id_hash']); if (!empty($videos_id)) { $users_id = Video::getOwner($videos_id); $user = new User($users_id); _error_log("useVideoHashOrLogin: $users_id, $videos_id"); return $user->login(true); } } return User::loginFromRequest(); } function strip_specific_tags($string, $tags_to_strip = array("script")) { foreach ($tags_to_strip as $tag) { $string = preg_replace('/<' . $tag . '[^>]*>(.*?)<\/' . $tag . '>/s', '', $string); } return $string; } function strip_render_blocking_resources($string) { $tags_to_strip = array('link', 'style'); $head = preg_match('/(.*)<\/head>/s', $string, $matches); $string = str_replace($matches[0], '{_head_}', $string); foreach ($tags_to_strip as $tag) { $string = preg_replace('/<' . $tag . '[^>]*>(.*?)<\/' . $tag . '>/s', '', $string); $string = preg_replace('/<' . $tag . '[^>]*\/>/s', '', $string); } $string = str_replace('{_head_}', $matches[0], $string); return $string; } function optimizeHTMLTags($html) { return $html; //$html = optimizeCSS($html); //$html = optimizeJS($html); return $html . '<--! optimized -->'; } function optimizeCSS($html) { global $global; $css = ''; $cacheDir = getVideosDir() . 'cache/'; $cacheName = md5(getSelfURI() . User::getId()) . '.css'; $filename = "{$cacheDir}{$cacheName}"; $urlname = "{$global['webSiteRootURL']}videos/cache/{$cacheName}"; $HTMLTag = ""; $fileExists = file_exists($filename); //$fileExists = false; // get link tags $pattern = '/((<(link)[^>]*(stylesheet|css)[^>]*\/>)|(<(style)[^>]*>([^<]+)<\/style>))/i'; preg_match_all($pattern, $html, $matches); foreach ($matches[3] as $key => $type) { if (strtolower($type) == 'link') { $linkTag = $matches[0][$key]; $pattern = '/href=.(http[^"\']+)/i'; preg_match($pattern, $linkTag, $href); if (empty($href)) { continue; } if (!$fileExists) { $content = url_get_contents($href[1]); if (empty($content)) { continue; } $css .= PHP_EOL . " /* link {$href[1]} */ " . $content; } $html = str_replace($linkTag, '', $html); } else { if (!$fileExists) { $css .= PHP_EOL . ' /* style */ ' . $matches[7][$key]; } $html = str_replace($matches[1][$key], '', $html); } } if (!$fileExists) { _file_put_contents($filename, $css); } return str_replace('', '' . PHP_EOL . $HTMLTag . PHP_EOL . '', $html); } function optimizeJS($html) { global $global; $js = ''; $cacheDir = getVideosDir() . 'cache/'; $cacheName = md5(getSelfURI() . User::getId()) . '.js'; $filename = "{$cacheDir}{$cacheName}"; $urlname = "{$global['webSiteRootURL']}videos/cache/{$cacheName}"; $HTMLTag = ""; $fileExists = file_exists($filename); $fileExists = false; // get link tags $pattern = '/((]+(src=[^ ]+)[^>]*>( *)<\/script>)|(]*>([^<]+)<\/script>))/si'; preg_match_all($pattern, $html, $matches); foreach ($matches[2] as $key => $type) { if (empty($type)) { if (preg_match('/application_ld_json/i', $matches[1][$key])) { continue; } $js .= PHP_EOL . " /* js */ " . $matches[6][$key]; $html = str_replace($matches[1][$key], '', $html); } else { $pattern = '/src=.(http[^"\']+)/i'; preg_match($pattern, $type, $href); if (empty($href)) { continue; } if (preg_match('/(jquery|video-js|videojs)/i', $href[1])) { continue; } if (!$fileExists) { $content = url_get_contents($href[1]); if (empty($content)) { continue; } $js .= PHP_EOL . " /* js link {$href[1]} */ " . $content; } $html = str_replace($type, '', $html); } } if (!$fileExists) { _file_put_contents($filename, $js); } return str_replace('', '' . PHP_EOL . $HTMLTag . PHP_EOL . '', $html); } function mysqlBeginTransaction() { global $global; _error_log('Begin transaction ' . getSelfURI()); $global['mysqli']->autocommit(false); } function mysqlRollback() { global $global; _error_log('Rollback transaction ' . getSelfURI(), AVideoLog::$ERROR); $global['mysqli']->rollback(); $global['mysqli']->autocommit(true); } function mysqlCommit() { global $global; _error_log('Commit transaction ' . getSelfURI()); $global['mysqli']->commit(); $global['mysqli']->autocommit(true); } function number_format_short($n, $precision = 1) { if ($n < 900) { // 0 - 900 $n_format = number_format($n, $precision); $suffix = ''; } else if ($n < 900000) { // 0.9k-850k $n_format = number_format($n / 1000, $precision); $suffix = 'K'; } else if ($n < 900000000) { // 0.9m-850m $n_format = number_format($n / 1000000, $precision); $suffix = 'M'; } else if ($n < 900000000000) { // 0.9b-850b $n_format = number_format($n / 1000000000, $precision); $suffix = 'B'; } else { // 0.9t+ $n_format = number_format($n / 1000000000000, $precision); $suffix = 'T'; } // Remove unecessary zeroes after decimal. "1.0" -> "1"; "1.00" -> "1" // Intentionally does not affect partials, eg "1.50" -> "1.50" if ($precision > 0) { $dotzero = '.' . str_repeat('0', $precision); $n_format = str_replace($dotzero, '', $n_format); } return $n_format . $suffix; } function seconds2human($ss) { $s = $ss % 60; $m = floor(($ss % 3600) / 60); $h = floor(($ss % 86400) / 3600); $d = floor(($ss % 2592000) / 86400); $M = floor($ss / 2592000); $times = array(); if(!empty($M)){ $times[] = "$M ".__('m'); } if(!empty($d)){ $times[] = "$d ".__('d'); } if(!empty($h)){ $times[] = "$h ".__('h'); } if(!empty($m)){ $times[] = "$m ".__('min'); } if(!empty($s)){ $times[] = "$s ".__('sec'); } return implode(', ', $times); } diff --git a/objects/video.php b/objects/video.php index d4848a110..9347a73b0 100644 --- a/objects/video.php +++ b/objects/video.php @@ -1,4535 +1,4535 @@ 'Active', 'k' => 'Active and Encoding', 'i' => 'Inactive', 'e' => 'Encoding', 'x' => 'Encoding Error', 'd' => 'Downloading', 't' => 'Transfering', 'u' => 'Unlisted', 'r' => 'Recording', 'f' => 'FansOnly'); public static $statusActive = 'a'; public static $statusActiveAndEncoding = 'k'; public static $statusInactive = 'i'; public static $statusEncoding = 'e'; public static $statusEncodingError = 'x'; public static $statusDownloading = 'd'; public static $statusTranfering = 't'; public static $statusUnlisted = 'u'; public static $statusRecording = 'r'; public static $statusFansOnly = 'f'; public static $rratingOptions = array('', 'g', 'pg', 'pg-13', 'r', 'nc-17', 'ma'); //ver 3.4 private $youtubeId; public static $typeOptions = array('audio', 'video', 'embed', 'linkVideo', 'linkAudio', 'torrent', 'pdf', 'image', 'gallery', 'article', 'serie', 'image', 'zip', 'notfound', 'blockedUser'); public function __construct($title = "", $filename = "", $id = 0) { global $global; $this->rotation = 0; $this->zoom = 1; if (!empty($id)) { $this->load($id); } if (!empty($title)) { $this->setTitle($title); } if (!empty($filename)) { $this->filename = $filename; } } public function addView($currentTime = 0) { global $global; if (empty($this->id)) { return false; } $sql = "UPDATE videos SET views_count = views_count+1, modified = now() WHERE id = ?"; $insert_row = sqlDAL::writeSql($sql, "i", array($this->id)); if ($insert_row) { $obj = new stdClass(); $obj->videos_statistics_id = VideoStatistic::create($this->id, $currentTime); $obj->videos_id = $this->id; $this->views_count++; AVideoPlugin::addView($this->id, $this->views_count); return $obj; } die($sql . ' Error : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } public function addSecondsWatching($seconds_watching) { global $global; $seconds_watching = intval($seconds_watching); if(empty($seconds_watching)){ return false; } if (empty($this->id)) { return false; } $sql = "UPDATE videos SET total_seconds_watching = total_seconds_watching+{$seconds_watching}, modified = now() WHERE id = ?"; //_error_log($sql."={$this->id}"); return sqlDAL::writeSql($sql, "i", array($this->id)); } public function updateViewsCount($total) { global $global; if (empty($this->id)) { return false; } $total = intval($total); if ($total < 0) { return false; } $sql = "UPDATE videos SET views_count = {$total}, modified = now() WHERE id = ?"; $insert_row = sqlDAL::writeSql($sql, "i", array($this->id)); if ($insert_row) { return $insert_row; } die($sql . ' Error : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } public function addViewPercent($percent = 25) { global $global; if (empty($this->id)) { return false; } $sql = "UPDATE videos SET views_count_{$percent} = IFNULL(views_count_{$percent}, 0)+1, modified = now() WHERE id = ?"; $insert_row = sqlDAL::writeSql($sql, "i", array($this->id)); if ($insert_row) { return true; } die($sql . ' Error : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } // allow users to count a view again in case it is refreshed public static function unsetAddView($videos_id) { // allow users to count a view again in case it is refreshed if (!empty($_SESSION['addViewCount'][$videos_id]['time']) && $_SESSION['addViewCount'][$videos_id]['time'] <= time()) { _session_start(); unset($_SESSION['addViewCount'][$videos_id]); } } public function load($id) { $video = self::getVideoLight($id); if (empty($video)) { return false; } foreach ($video as $key => $value) { $this->$key = $value; } } function getLive_transmitions_history_id() { return $this->live_transmitions_history_id; } function setLive_transmitions_history_id($live_transmitions_history_id) { AVideoPlugin::onVideoSetLive_transmitions_history_id($this->id, $this->live_transmitions_history_id, intval($live_transmitions_history_id)); $this->live_transmitions_history_id = intval($live_transmitions_history_id); } public function getEncoderURL() { return $this->encoderURL; } public function getFilepath() { return $this->filepath; } public function getFilesize() { return intval($this->filesize); } public function setEncoderURL($encoderURL) { if (filter_var($encoderURL, FILTER_VALIDATE_URL) !== false) { AVideoPlugin::onVideoSetEncoderURL($this->id, $this->encoderURL, $encoderURL); $this->encoderURL = $encoderURL; } } public function setFilepath($filepath) { AVideoPlugin::onVideoSetFilepath($this->id, $this->filepath, $filepath); $this->filepath = $filepath; } public function setFilesize($filesize) { AVideoPlugin::onVideoSetFilesize($this->id, $this->filesize, $filesize); $this->filesize = intval($filesize); } public function setUsers_id($users_id) { AVideoPlugin::onVideoSetUsers_id($this->id, $this->users_id, $users_id); $this->users_id = $users_id; } public function getSites_id() { return $this->sites_id; } public function setSites_id($sites_id) { AVideoPlugin::onVideoSetSites_id($this->id, $this->sites_id, $sites_id); $this->sites_id = $sites_id; } public function getVideo_password() { return trim($this->video_password); } public function setVideo_password($video_password) { AVideoPlugin::onVideoSetVideo_password($this->id, $this->video_password, $video_password); $this->video_password = trim($video_password); } public function save($updateVideoGroups = false, $allowOfflineUser = false) { global $advancedCustom; global $global; if (!User::isLogged() && !$allowOfflineUser) { _error_log('Video::save permission denied to save'); return false; } if (empty($this->title)) { $this->title = uniqid(); } $this->clean_title = substr($this->clean_title, 0, 187); if (empty($this->clean_title)) { $this->setClean_title($this->title); } $this->clean_title = self::fixCleanTitle($this->clean_title, 1, $this->id); if (empty($this->status)) { $this->status = 'e'; } if (empty($this->type) || !in_array($this->type, self::$typeOptions)) { $this->type = 'video'; } if (empty($this->isSuggested)) { $this->isSuggested = 0; } else { $this->isSuggested = 1; } if (empty($this->categories_id)) { $p = AVideoPlugin::loadPluginIfEnabled("PredefinedCategory"); $category = Category::getCategoryDefault(); $categories_id = $category['id']; if (empty($categories_id)) { $categories_id = 'NULL'; } if ($p) { $this->categories_id = $p->getCategoryId(); } else { $this->categories_id = $categories_id; } if (empty($this->categories_id)) { $this->categories_id = $categories_id; } } // check if category exists $cat = new Category($this->categories_id); if (empty($cat->getName())) { $catDefault = Category::getCategoryDefault(); $this->categories_id = $catDefault['id']; } $this->setTitle($global['mysqli']->real_escape_string(trim($this->title))); $this->description = ($global['mysqli']->real_escape_string($this->description)); if (forbiddenWords($this->title) || forbiddenWords($this->description)) { return false; } if (empty($this->users_id)) { $this->users_id = User::getId(); } $this->next_videos_id = intval($this->next_videos_id); if (empty($this->next_videos_id)) { $this->next_videos_id = 'NULL'; } $this->sites_id = intval($this->sites_id); if (empty($this->sites_id)) { $this->sites_id = 'NULL'; } $this->serie_playlists_id = intval($this->serie_playlists_id); if (empty($this->serie_playlists_id)) { $this->serie_playlists_id = 'NULL'; } if (empty($this->filename)) { $prefix = $this->type; if (empty($prefix)) { $prefix = 'v'; } $paths = self::getNewVideoFilename($prefix); $this->filename = $paths['filename']; } $this->can_download = intval($this->can_download); $this->can_share = intval($this->can_share); $this->only_for_paid = intval($this->only_for_paid); $this->filesize = intval($this->filesize); $this->rate = floatval($this->rate); if (!filter_var($this->videoLink, FILTER_VALIDATE_URL)) { $this->videoLink = ''; if ($this->type == 'embed') { $this->type = 'video'; } } if (empty($this->live_transmitions_history_id)) { $this->live_transmitions_history_id = 'NULL'; } if (!empty($this->id)) { if (!$this->userCanManageVideo() && !$allowOfflineUser && !Permissions::canModerateVideos()) { header('Content-Type: application/json'); die('{"error":"3 ' . __("Permission denied") . '"}'); } $sql = "UPDATE videos SET title = '{$this->title}',clean_title = '{$this->clean_title}'," . " filename = '{$this->filename}', categories_id = '{$this->categories_id}', status = '{$this->status}'," . " description = '{$this->description}', duration = '{$this->duration}', type = '{$this->type}', videoDownloadedLink = '{$this->videoDownloadedLink}', youtubeId = '{$this->youtubeId}', videoLink = '{$this->videoLink}', next_videos_id = {$this->next_videos_id}, isSuggested = {$this->isSuggested}, users_id = {$this->users_id}, " . " trailer1 = '{$this->trailer1}', trailer2 = '{$this->trailer2}', trailer3 = '{$this->trailer3}', rate = '{$this->rate}', can_download = '{$this->can_download}', can_share = '{$this->can_share}', only_for_paid = '{$this->only_for_paid}', rrating = '{$this->rrating}', externalOptions = '{$this->externalOptions}', sites_id = {$this->sites_id}, serie_playlists_id = {$this->serie_playlists_id} ,live_transmitions_history_id = {$this->live_transmitions_history_id} , video_password = '{$this->video_password}', " . " encoderURL = '{$this->encoderURL}', filepath = '{$this->filepath}' , filesize = '{$this->filesize}' , modified = now()" . " WHERE id = {$this->id}"; $saved = sqlDAL::writeSql($sql); if ($saved) { $insert_row = $this->id; } } else { $sql = "INSERT INTO videos " . "(title,clean_title, filename, users_id, categories_id, status, description, duration,type,videoDownloadedLink, next_videos_id, created, modified, videoLink, can_download, can_share, only_for_paid, rrating, externalOptions, sites_id, serie_playlists_id,live_transmitions_history_id, video_password, encoderURL, filepath , filesize) values " . "('{$this->title}','{$this->clean_title}', '{$this->filename}', {$this->users_id},{$this->categories_id}, '{$this->status}', '{$this->description}', '{$this->duration}', '{$this->type}', '{$this->videoDownloadedLink}', {$this->next_videos_id},now(), now(), '{$this->videoLink}', '{$this->can_download}', '{$this->can_share}','{$this->only_for_paid}', '{$this->rrating}', '$this->externalOptions', {$this->sites_id}, {$this->serie_playlists_id},{$this->live_transmitions_history_id}, '{$this->video_password}', '{$this->encoderURL}', '{$this->filepath}', '{$this->filesize}')"; $insert_row = sqlDAL::writeSql($sql); } if ($insert_row) { _error_log("Video::save ({$this->title}) Saved id = {$insert_row} "); Category::clearCacheCount(); if (empty($this->id)) { $id = $global['mysqli']->insert_id; $this->id = $id; // check if needs to add the video in a user group $p = AVideoPlugin::loadPluginIfEnabled("PredefinedCategory"); if ($p) { $updateVideoGroups = true; $this->videoGroups = $p->getUserGroupsArray(); } } else { $id = $this->id; } ObjectYPT::deleteCache("getItemprop{$this->id}"); ObjectYPT::deleteCache("getLdJson{$this->id}"); ObjectYPT::deleteCache("getVideoTags{$this->id}"); self::deleteTagsAsync($this->id); if ($updateVideoGroups) { require_once $global['systemRootPath'] . 'objects/userGroups.php'; // update the user groups UserGroups::updateVideoGroups($id, $this->videoGroups); } // I am not sure what is it for //Video::autosetCategoryType($id); if (!empty($this->old_categories_id)) { //Video::autosetCategoryType($this->old_categories_id); } self::clearCache($this->id); return $id; } _error_log('Video::save Error : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error . " $sql"); return false; } // i would like to simplify the big part of the method above in this method, but won't work as i want. public static function internalAutoset($catId, $videoFound, $audioFound) { global $config; if ($config->currentVersionLowerThen('5.01')) { return false; } $sql = "SELECT type,categories_id FROM `videos` WHERE categories_id = ?;"; $res = sqlDAL::readSql($sql, "i", array($catId)); $fullResult2 = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); if ($res != false) { foreach ($fullResult2 as $row) { if ($row['type'] == "audio") { $audioFound = true; } elseif ($row['type'] == "video") { $videoFound = true; } } } if (($videoFound == false) || ($audioFound == false)) { $sql = "SELECT parentId,categories_id FROM `categories` WHERE parentId = ?;"; $res = sqlDAL::readSql($sql, "i", array($catId)); $fullResult2 = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); if ($res != false) { foreach ($fullResult2 as $cat) { $sql = "SELECT type,categories_id FROM `videos` WHERE categories_id = ?;"; $res = sqlDAL::readSql($sql, "i", array($cat['parentId'])); $fullResult = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); if ($res != false) { foreach ($fullResult as $row) { if ($row['type'] == 'audio') { $audioFound = true; } elseif ($row['type'] == 'video') { $videoFound = true; } } } } } } return array($videoFound, audioFound); } public function setClean_title($clean_title) { if (preg_match("/video-automatically-booked/i", $clean_title) && !empty($this->clean_title)) { return false; } $clean_title = cleanURLName($clean_title); AVideoPlugin::onVideoSetClean_title($this->id, $this->clean_title, $clean_title); $this->clean_title = $clean_title; } public function setDuration($duration) { AVideoPlugin::onVideoSetDuration($this->id, $this->duration, $duration); $this->duration = $duration; } public function getDuration() { return $this->duration; } public function getIsSuggested() { return $this->isSuggested; } public function setIsSuggested($isSuggested) { if (empty($isSuggested) || $isSuggested === "false") { $new_isSuggested = 0; } else { $new_isSuggested = 1; } AVideoPlugin::onVideoSetIsSuggested($this->id, $this->isSuggested, $new_isSuggested); $this->isSuggested = $new_isSuggested; } public function setStatus($status) { if (!empty($this->id)) { global $global; if (empty(Video::$statusDesc[$status])) { _error_log("Video::setStatus({$status}) NOT found ", AVideoLog::$WARNING); return false; } _error_log("Video::setStatus({$status}) " . json_encode(debug_backtrace()), AVideoLog::$WARNING); $sql = "UPDATE videos SET status = ?, modified = now() WHERE id = ? "; $res = sqlDAL::writeSql($sql, 'si', array($status, $this->id)); if ($global['mysqli']->errno != 0) { die('Error on update Status: (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } self::clearCache($this->id); } AVideoPlugin::onVideoSetStatus($this->id, $this->status, $status); $this->status = $status; return $status; } public function setAutoStatus($default = 'a') { global $advancedCustom; if (empty($advancedCustom)) { $advancedCustom = AVideoPlugin::getDataObject('CustomizeAdvanced'); } if (!empty($_POST['fail'])) { return $this->setStatus(Video::$statusEncodingError); } else { if (!empty($_REQUEST['overrideStatus'])) { return $this->setStatus($_REQUEST['overrideStatus']); } else { // encoder did not provide a status if (!empty($_REQUEST['keepEncoding'])) { return $this->setStatus(Video::$statusActiveAndEncoding); } else { if ($this->getTitle() !== "Video automatically booked") { if (!empty($advancedCustom->makeVideosInactiveAfterEncode)) { return $this->setStatus(Video::$statusInactive); } elseif (!empty($advancedCustom->makeVideosUnlistedAfterEncode)) { return $this->setStatus(Video::$statusUnlisted); } } else { return $this->setStatus(Video::$statusInactive); } } } } return $this->setStatus($default); } public function setType($type, $force = true) { if ($force || empty($this->type)) { AVideoPlugin::onVideoSetType($this->id, $this->type, $type, $force); $this->type = $type; } } public function setRotation($rotation) { $saneRotation = intval($rotation) % 360; AVideoPlugin::onVideoSetRotation($this->id, $this->rotation, $saneRotation); if (!empty($this->id)) { global $global; $sql = "UPDATE videos SET rotation = '{$saneRotation}', modified = now() WHERE id = {$this->id} "; $res = sqlDAL::writeSql($sql); if ($global['mysqli']->errno != 0) { die('Error on update Rotation: (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } } $this->rotation = $saneRotation; } public function getRotation() { return $this->rotation; } public function getUsers_id() { return $this->users_id; } public function setZoom($zoom) { $saneZoom = abs(floatval($zoom)); if ($saneZoom < 0.1 || $saneZoom > 10) { die('Zoom level must be between 0.1 and 10'); } if (!empty($this->id)) { global $global; $sql = "UPDATE videos SET zoom = '{$saneZoom}', modified = now() WHERE id = {$this->id} "; $res = sqlDAL::writeSql($sql); if ($global['mysqli']->errno != 0) { die('Error on update Zoom: (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } } AVideoPlugin::onVideoSetZoom($this->id, $this->zoom, $saneZoom); $this->zoom = $saneZoom; } public function getZoom() { return $this->zoom; } public static function getUserGroupsCanSeeSQL($tableAlias = '') { global $global; if (Permissions::canModerateVideos()) { return ""; } $obj = AVideoPlugin::getDataObject('Subscription'); if ($obj && $obj->allowFreePlayWithAds) { $sql = " AND {$tableAlias}only_for_paid = 0 "; return $sql; } else { $sql = " (SELECT count(id) FROM videos_group_view as gv WHERE gv.videos_id = v.id ) = 0 "; if (User::isLogged()) { require_once $global['systemRootPath'] . 'objects/userGroups.php'; $userGroups = UserGroups::getUserGroups(User::getId()); $groups_id = array(); foreach ($userGroups as $value) { $groups_id[] = $value['id']; } if (!empty($groups_id)) { $sql = " (({$sql}) OR ((SELECT count(id) FROM videos_group_view as gv WHERE gv.videos_id = v.id AND users_groups_id IN ('" . implode("','", $groups_id) . "') ) > 0)) "; } } return " AND " . $sql; } } public static function getVideo($id = "", $status = "viewable", $ignoreGroup = false, $random = false, $suggestedOnly = false, $showUnlisted = false, $ignoreTags = false, $activeUsersOnly = true) { global $global, $config, $advancedCustom, $advancedCustomUser; if ($config->currentVersionLowerThen('5')) { return false; } $status = str_replace("'", "", $status); $id = intval($id); if (AVideoPlugin::isEnabledByName("VideoTags")) { if (!empty($_GET['tags_id']) && empty($videosArrayId)) { $videosArrayId = VideoTags::getAllVideosIdFromTagsId($_GET['tags_id']); } } _mysql_connect(); $sql = "SELECT u.*, v.*, " . " nv.title as next_title," . " nv.clean_title as next_clean_title," . " nv.filename as next_filename," . " nv.id as next_id," . " c.id as category_id,c.iconClass,c.name as category,c.iconClass, c.clean_name as clean_category,c.description as category_description, v.created as videoCreation, " . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = 1 ) as likes, " . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = -1 ) as dislikes "; if (User::isLogged()) { $sql .= ", (SELECT `like` FROM likes as l where l.videos_id = v.id AND users_id = '" . User::getId() . "' ) as myVote "; } else { $sql .= ", 0 as myVote "; } $sql .= " FROM videos as v " . "LEFT JOIN categories c ON categories_id = c.id " . "LEFT JOIN users u ON v.users_id = u.id " . "LEFT JOIN videos nv ON v.next_videos_id = nv.id " . " WHERE 1=1 "; if ($activeUsersOnly) { $sql .= " AND u.status = 'a' "; } if (!empty($id)) { $sql .= " AND v.id = '$id' "; } $sql .= AVideoPlugin::getVideoWhereClause(); $sql .= static::getVideoQueryFileter(); if (!$ignoreGroup) { $sql .= self::getUserGroupsCanSeeSQL('v.'); } if (!empty($_SESSION['type'])) { if ($_SESSION['type'] == 'video' || $_SESSION['type'] == 'linkVideo') { $sql .= " AND (v.type = 'video' OR v.type = 'embed' OR v.type = 'linkVideo')"; } elseif ($_SESSION['type'] == 'audio') { $sql .= " AND (v.type = 'audio' OR v.type = 'linkAudio')"; } else { $sql .= " AND v.type = '{$_SESSION['type']}' "; } } if (!empty($videosArrayId) && is_array($videosArrayId)) { $sql .= " AND v.id IN ( '" . implode("', '", $videosArrayId) . "') "; } if ($status == "viewable") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "')"; } elseif ($status == "viewableNotUnlisted") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus(false)) . "')"; } elseif (!empty($status)) { $sql .= " AND v.status = '{$status}'"; } if (!empty($_GET['catName'])) { $catName = $global['mysqli']->real_escape_string($_GET['catName']); $sql .= " AND (c.clean_name = '{$catName}' OR c.parentId IN (SELECT cs.id from categories cs where cs.clean_name = '{$catName}' ))"; } if (empty($id) && !empty($_GET['channelName'])) { $user = User::getChannelOwner($_GET['channelName']); if (!empty($user['id'])) { $sql .= " AND v.users_id = '{$user['id']}' "; } } if (!empty($_GET['search'])) { $_POST['searchPhrase'] = $_GET['search']; } if (!empty($_POST['searchPhrase'])) { $searchFieldsNames = array('v.title', 'v.description', 'c.name', 'c.description'); if ($advancedCustomUser->videosSearchAlsoSearchesOnChannelName) { $searchFieldsNames[] = 'u.channelName'; } if (AVideoPlugin::isEnabledByName("VideoTags")) { $sql .= " AND ("; $sql .= "v.id IN (select videos_id FROM tags_has_videos LEFT JOIN tags as t ON tags_id = t.id AND t.name LIKE '%{$_POST['searchPhrase']}%' WHERE t.id is NOT NULL)"; $sql .= BootGrid::getSqlSearchFromPost($searchFieldsNames, "OR"); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']); $sql .= ")"; } else { $sql .= ' AND (1=1 ' . BootGrid::getSqlSearchFromPost($searchFieldsNames); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']) . ')'; } } if (!$ignoreGroup) { $arrayNotIN = AVideoPlugin::getAllVideosExcludeVideosIDArray(); if (!empty($arrayNotIN) && is_array($arrayNotIN)) { $sql .= " AND v.id NOT IN ( '" . implode("', '", $arrayNotIN) . "') "; } } // replace random based on this $firstClauseLimit = ""; if (empty($id)) { if (empty($random) && !empty($_GET['videoName'])) { $sql .= " AND v.clean_title = '{$_GET['videoName']}' "; } elseif (!empty($random)) { $sql .= " AND v.id != {$random} "; $rand = rand(0, self::getTotalVideos($status, false, $ignoreGroup, $showUnlisted, $activeUsersOnly, $suggestedOnly)); $rand = ($rand - 2) < 0 ? 0 : $rand - 2; $firstClauseLimit = "$rand, "; //$sql .= " ORDER BY RAND() "; } elseif ($suggestedOnly && empty($_GET['videoName']) && empty($_GET['search']) && empty($_GET['searchPhrase'])) { $sql .= " AND v.isSuggested = 1 "; $rand = rand(0, self::getTotalVideos($status, false, $ignoreGroup, $showUnlisted, $activeUsersOnly, $suggestedOnly)); $rand = ($rand - 2) < 0 ? 0 : $rand - 2; $firstClauseLimit = "$rand, "; //$sql .= " ORDER BY RAND() "; } elseif (!empty($_GET['v']) && is_numeric($_GET['v'])) { $vid = intval($_GET['v']); $sql .= " AND v.id = {$vid} "; } else { $sql .= " ORDER BY v.Created DESC "; } } if (strpos($sql, 'v.id IN') === false && strpos(strtolower($sql), 'limit') === false) { $sql .= " LIMIT {$firstClauseLimit}1"; } //echo $sql, "
";//exit; $res = sqlDAL::readSql($sql); $video = sqlDAL::fetchAssoc($res); // if there is a search, and there is no data and is inside a channel try again without a channel if (!empty($_GET['search']) && empty($video) && !empty($_GET['channelName'])) { $channelName = $_GET['channelName']; unset($_GET['channelName']); $return = self::getVideo($id, $status, $ignoreGroup, $random, $suggestedOnly, $showUnlisted, $ignoreTags, $activeUsersOnly); $_GET['channelName'] = $channelName; return $return; } sqlDAL::close($res); if ($res != false) { require_once $global['systemRootPath'] . 'objects/userGroups.php'; if (!empty($video)) { $video = self::getInfo($video); } } else { $video = false; } return $video; } public static function getVideoLight($id) { global $global, $config; $id = intval($id); $sql = "SELECT * FROM videos WHERE id = '$id' LIMIT 1"; $res = sqlDAL::readSql($sql, "", array(), true); $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); return $video; } public static function getTotalVideosSizeFromUser($users_id) { global $global, $config; $users_id = intval($users_id); $sql = "SELECT sum(filesize) as total FROM videos WHERE 1=1 "; if (!empty($users_id)) { $sql .= " AND users_id = '$users_id'"; } $res = sqlDAL::readSql($sql, "", array(), true); $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); return intval($video['total']); } public static function getTotalVideosFromUser($users_id) { global $global, $config; $users_id = intval($users_id); $sql = "SELECT count(*) as total FROM videos WHERE 1=1 "; if (!empty($users_id)) { $sql .= " AND users_id = '$users_id'"; } $res = sqlDAL::readSql($sql, "", array(), true); $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); return intval($video['total']); } public static function getVideoFromFileName($fileName, $ignoreGroup = false, $ignoreTags = false) { global $global; if (empty($fileName)) { return false; } $parts = explode("/", $fileName); if (!empty($parts[0])) { $fileName = $parts[0]; } $fileName = self::getCleanFilenameFromFile($fileName); $sql = "SELECT id FROM videos WHERE filename = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "s", array($fileName)); if ($res != false) { $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if (!empty($video['id'])) { return self::getVideo($video['id'], "", $ignoreGroup, false, false, true, $ignoreTags); } } return false; } public static function getVideoFromFileNameLight($fileName) { global $global; $fileName = self::getCleanFilenameFromFile($fileName); if (empty($fileName)) { return false; } $sql = "SELECT * FROM videos WHERE filename = ? LIMIT 1"; //var_dump($sql, $fileName); $res = sqlDAL::readSql($sql, "s", array($fileName), true); if ($res != false) { $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); return $video; } return false; } public static function getVideoFromCleanTitle($clean_title) { // even increasing the max_allowed_packet it only goes away when close and reopen the connection global $global; $sql = "SELECT id FROM videos WHERE clean_title = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "s", array($clean_title)); $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if (!empty($video) && $res) { return self::getVideo($video['id'], "", true, false, false, true); //$video['groups'] = UserGroups::getVideoGroups($video['id']); } else { return false; } } static function getRelatedMovies($videos_id, $limit = 10) { global $global; $video = self::getVideoLight($videos_id); if (empty($video)) { return false; } $sql = "SELECT * FROM videos v WHERE v.id != {$videos_id} AND v.status='a' AND (categories_id = {$video['categories_id']} "; if (AVideoPlugin::isEnabledByName("VideoTags")) { $sql .= " OR ("; $sql .= "v.id IN (select videos_id FROM tags_has_videos WHERE tags_id IN " . " (SELECT tags_id FROM tags_has_videos WHERE videos_id = {$videos_id}))"; $sql .= ")"; } $sql .= ") "; $sql .= AVideoPlugin::getVideoWhereClause(); $sql .= "ORDER BY RAND() LIMIT {$limit} "; $res = sqlDAL::readSql($sql); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $rows = array(); if ($res != false) { foreach ($fullData as $row) { $row['images'] = self::getImageFromFilename($row['filename']); if (empty($row['externalOptions'])) { $row['externalOptions'] = json_encode(array('videoStartSeconds' => '00:00:00')); } $rows[] = $row; } } else { die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $rows; } /** * * @global type $global * @param type $status * @param type $showOnlyLoggedUserVideos you may pass an user ID to filter results * @param type $ignoreGroup * @param type $videosArrayId an array with videos to return (for filter only) * @return boolean */ public static function getAllVideos($status = "viewable", $showOnlyLoggedUserVideos = false, $ignoreGroup = false, $videosArrayId = array(), $getStatistcs = false, $showUnlisted = false, $activeUsersOnly = true, $suggestedOnly = false, $is_serie = null) { global $global, $config, $advancedCustom, $advancedCustomUser; if ($config->currentVersionLowerThen('5')) { return false; } if (!empty($_POST['sort']['suggested'])) { $suggestedOnly = true; } if (AVideoPlugin::isEnabledByName("VideoTags")) { if (!empty($_GET['tags_id']) && empty($videosArrayId)) { TimeLogStart("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})"); $videosArrayId = VideoTags::getAllVideosIdFromTagsId($_GET['tags_id']); TimeLogEnd("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})", __LINE__); } } $status = str_replace("'", "", $status); $sql = "SELECT u.*, v.*, c.iconClass, c.name as category, c.clean_name as clean_category,c.description as category_description, v.created as videoCreation, v.modified as videoModified, " . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = 1 ) as likes, " . " (SELECT count(id) FROM likes as l where l.videos_id = v.id AND `like` = -1 ) as dislikes " . " FROM videos as v " . " LEFT JOIN categories c ON categories_id = c.id " . " LEFT JOIN users u ON v.users_id = u.id " . " WHERE 2=2 "; $blockedUsers = self::getBlockedUsersIdsArray(); if (!empty($blockedUsers)) { $sql .= " AND v.users_id NOT IN ('" . implode("','", $blockedUsers) . "') "; } if ($showOnlyLoggedUserVideos === true && !Permissions::canModerateVideos()) { $uid = intval(User::getId()); $sql .= " AND v.users_id = '{$uid}'"; } elseif (!empty($showOnlyLoggedUserVideos)) { $uid = intval($showOnlyLoggedUserVideos); $sql .= " AND v.users_id = '{$uid}'"; } elseif (!empty($_GET['channelName'])) { $user = User::getChannelOwner($_GET['channelName']); $uid = intval($user['id']); $sql .= " AND v.users_id = '{$uid}' "; } if (isset($_REQUEST['is_serie']) && empty($is_serie)) { $is_serie = intval($_REQUEST['is_serie']); } if (isset($is_serie)) { if (empty($is_serie)) { $sql .= " AND v.serie_playlists_id IS NULL "; } else { $sql .= " AND v.serie_playlists_id IS NOT NULL "; } } if (!empty($videosArrayId) && is_array($videosArrayId)) { $sql .= " AND v.id IN ( '" . implode("', '", $videosArrayId) . "') "; } if ($activeUsersOnly) { $sql .= " AND u.status = 'a' "; } $sql .= static::getVideoQueryFileter(); if (!$ignoreGroup) { TimeLogStart("video::getAllVideos::getAllVideosExcludeVideosIDArray"); $arrayNotIN = AVideoPlugin::getAllVideosExcludeVideosIDArray(); if (!empty($arrayNotIN) && is_array($arrayNotIN)) { $sql .= " AND v.id NOT IN ( '" . implode("', '", $arrayNotIN) . "') "; } TimeLogEnd("video::getAllVideos::getAllVideosExcludeVideosIDArray", __LINE__); } if (!$ignoreGroup) { $sql .= self::getUserGroupsCanSeeSQL('v.'); } if (!empty($_SESSION['type'])) { if ($_SESSION['type'] == 'video' || $_SESSION['type'] == 'linkVideo') { $sql .= " AND (v.type = 'video' OR v.type = 'embed' OR v.type = 'linkVideo')"; } elseif ($_SESSION['type'] == 'videoOnly') { $sql .= " AND (v.type = 'video')"; } elseif ($_SESSION['type'] == 'audio') { $sql .= " AND (v.type = 'audio' OR v.type = 'linkAudio')"; } else { $sql .= " AND v.type = '{$_SESSION['type']}' "; } } if ($status == "viewable") { if (User::isLogged()) { $sql .= " AND (v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "') OR (v.status='u' AND v.users_id ='" . User::getId() . "'))"; } else { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "')"; } } elseif ($status == "viewableNotUnlisted") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus(false)) . "')"; } elseif ($status == "publicOnly") { $sql .= " AND v.status IN ('a', 'k') AND (SELECT count(id) FROM videos_group_view as gv WHERE gv.videos_id = v.id ) = 0"; } elseif (!empty($status)) { $sql .= " AND v.status = '{$status}'"; } if (!empty($_GET['catName'])) { $catName = $global['mysqli']->real_escape_string($_GET['catName']); $sql .= " AND (c.clean_name = '{$catName}' OR c.parentId IN (SELECT cs.id from categories cs where cs.clean_name = '{$catName}' ))"; } if (!empty($_GET['search'])) { $_POST['searchPhrase'] = $_GET['search']; } if (!empty($_GET['modified'])) { $_GET['modified'] = str_replace("'", "", $_GET['modified']); $sql .= " AND v.modified >= '{$_GET['modified']}'"; } if (!empty($_POST['searchPhrase'])) { $searchFieldsNames = array('v.title', 'v.description', 'c.name', 'c.description'); if ($advancedCustomUser->videosSearchAlsoSearchesOnChannelName) { $searchFieldsNames[] = 'u.channelName'; } if (AVideoPlugin::isEnabledByName("VideoTags")) { $sql .= " AND ("; $sql .= "v.id IN (select videos_id FROM tags_has_videos LEFT JOIN tags as t ON tags_id = t.id AND t.name LIKE '%{$_POST['searchPhrase']}%' WHERE t.id is NOT NULL)"; $sql .= BootGrid::getSqlSearchFromPost($searchFieldsNames, "OR"); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']); $sql .= ")"; } else { $sql .= ' AND (1=1 ' . BootGrid::getSqlSearchFromPost($searchFieldsNames); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']) . ')'; } } $sql .= AVideoPlugin::getVideoWhereClause(); if ($suggestedOnly) { $sql .= " AND v.isSuggested = 1 "; $sql .= " ORDER BY RAND() "; $sort = @$_POST['sort']; unset($_POST['sort']); $sql .= BootGrid::getSqlFromPost(array(), empty($_POST['sort']['likes']) ? "v." : "", "", true); if (strpos(strtolower($sql), 'limit') === false) { $sql .= " LIMIT 60 "; } $_POST['sort'] = $sort; } elseif (!isset($_POST['sort']['trending']) && !isset($_GET['sort']['trending'])) { if (!empty($_POST['sort']['created']) && !empty($_POST['sort']['likes'])) { $_POST['sort']['v.created'] = $_POST['sort']['created']; unset($_POST['sort']['created']); } $sql .= BootGrid::getSqlFromPost(array(), empty($_POST['sort']['likes']) ? "v." : "", "", true); } else { unset($_POST['sort']['trending'], $_GET['sort']['trending']); $rows = array(); if (!empty($_REQUEST['current']) && $_REQUEST['current'] == 1) { $rows = VideoStatistic::getVideosWithMoreViews($status, $showOnlyLoggedUserVideos, $showUnlisted, $suggestedOnly); } $ids = array(); foreach ($rows as $row) { $ids[] = $row['id']; } if (!empty($ids)) { $sql .= " ORDER BY FIND_IN_SET(v.id, '" . implode(",", $ids) . "') DESC, likes DESC "; } else { $sql .= " ORDER BY likes DESC "; } $sql .= ObjectYPT::getSqlLimit(); } if (strpos(strtolower($sql), 'limit') === false) { if (!empty($_GET['limitOnceToOne'])) { $sql .= " LIMIT 1"; unset($_GET['limitOnceToOne']); } else { $_REQUEST['rowCount'] = getRowCount(); if (!empty($_REQUEST['rowCount'])) { $sql .= " LIMIT {$_REQUEST['rowCount']}"; } else { _error_log("getAllVideos without limit " . json_encode(debug_backtrace())); if (empty($global['limitForUnlimitedVideos'])) { $global['limitForUnlimitedVideos'] = 100; } if ($global['limitForUnlimitedVideos'] > 0) { $sql .= " LIMIT {$global['limitForUnlimitedVideos']}"; } } } } //echo $sql;//exit; //_error_log("getAllVideos($status, $showOnlyLoggedUserVideos , $ignoreGroup , ". json_encode($videosArrayId).")" . $sql); $res = sqlDAL::readSql($sql); $fullData = sqlDAL::fetchAllAssoc($res); // if there is a search, and there is no data and is inside a channel try again without a channel if (!empty($_GET['search']) && empty($fullData) && !empty($_GET['channelName'])) { $channelName = $_GET['channelName']; unset($_GET['channelName']); $return = self::getAllVideos($status, $showOnlyLoggedUserVideos, $ignoreGroup, $videosArrayId, $getStatistcs, $showUnlisted, $activeUsersOnly, $suggestedOnly); $_GET['channelName'] = $channelName; return $return; } sqlDAL::close($res); $videos = array(); if ($res != false) { require_once 'userGroups.php'; TimeLogStart("video::getAllVideos foreach"); foreach ($fullData as $row) { $row = self::getInfo($row, $getStatistcs); $videos[] = $row; } $rowCount = getRowCount(); $tolerance = $rowCount / 100; if ($tolerance < 0.2) { $tolerance = 0.2; } else if ($tolerance > 2) { $tolerance = 2; } TimeLogEnd("video::getAllVideos foreach", __LINE__, $tolerance); //$videos = $res->fetch_all(MYSQLI_ASSOC); } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $videos; } private static function getInfo($row, $getStatistcs = false) { $name = "_getVideoInfo_{$row['id']}"; $cache = ObjectYPT::getSessionCache($name, 3600); if (!empty($cache)) { $externalOptions = $cache->externalOptions; $obj = object_to_array($cache); if (!empty($externalOptions)) { if (is_object($externalOptions)) { $obj['externalOptions'] = $externalOptions; } else if (is_string($externalOptions)) { $obj['externalOptions'] = _json_decode($externalOptions); } $obj['externalOptions'] = json_encode($obj['externalOptions']); } if (empty($obj['externalOptions'])) { $obj['externalOptions'] = json_encode(array('videoStartSeconds' => '00:00:00')); } return $obj; } $row = cleanUpRowFromDatabase($row); if (!self::canEdit($row['id'])) { if (!empty($row['video_password'])) { $row['video_password'] = 1; } else { $row['video_password'] = 0; } } if ($getStatistcs) { TimeLogStart("video::getInfo getStatistcs"); $previewsMonth = date("Y-m-d 00:00:00", strtotime("-30 days")); $previewsWeek = date("Y-m-d 00:00:00", strtotime("-7 days")); $today = date('Y-m-d 23:59:59'); $row['statistc_all'] = VideoStatistic::getStatisticTotalViews($row['id']); $row['statistc_today'] = VideoStatistic::getStatisticTotalViews($row['id'], false, date('Y-m-d 00:00:00'), $today); $row['statistc_week'] = VideoStatistic::getStatisticTotalViews($row['id'], false, $previewsWeek, $today); $row['statistc_month'] = VideoStatistic::getStatisticTotalViews($row['id'], false, $previewsMonth, $today); $row['statistc_unique_user'] = VideoStatistic::getStatisticTotalViews($row['id'], true); TimeLogEnd("video::getInfo getStatistcs", __LINE__, 0.5); } TimeLogStart("video::getInfo otherInfo"); $otherInfocachename = "otherInfo{$row['id']}"; $otherInfo = object_to_array(ObjectYPT::getCache($otherInfocachename), 600); if (empty($otherInfo)) { $otherInfo = array(); $otherInfo['category'] = xss_esc_back($row['category']); $otherInfo['groups'] = UserGroups::getVideoGroups($row['id']); $otherInfo['tags'] = self::getTags($row['id']); $otherInfo['title'] = UTF8encode($row['title']); $otherInfo['description'] = UTF8encode($row['description']); $otherInfo['descriptionHTML'] = self::htmlDescription($otherInfo['description']); //$otherInfo['relatedVideos'] = self::getRelatedMovies($row['id']); if (empty($row['filesize'])) { $otherInfo['filesize'] = Video::updateFilesize($row['id']); } ObjectYPT::setCache($otherInfocachename, $otherInfo); } foreach ($otherInfo as $key => $value) { $row[$key] = $value; } $row['hashId'] = idToHash($row['id']); $row['link'] = self::getLinkToVideo($row['id'], $row['clean_title']); $row['embedlink'] = self::getLinkToVideo($row['id'], $row['clean_title'], true); $row['progress'] = self::getVideoPogressPercent($row['id']); $row['isFavorite'] = self::isFavorite($row['id']); $row['isWatchLater'] = self::isWatchLater($row['id']); $row['favoriteId'] = self::getFavoriteIdFromUser(User::getId()); $row['watchLaterId'] = self::getWatchLaterIdFromUser(User::getId()); $row['total_seconds_watching_human'] = seconds2human($row['total_seconds_watching']); $row['views_count_short'] = number_format_short($row['views_count']); if (empty($row['externalOptions'])) { $row['externalOptions'] = json_encode(array('videoStartSeconds' => '00:00:00')); } TimeLogEnd("video::getInfo otherInfo", __LINE__, 0.5); TimeLogStart("video::getInfo getAllVideosArray"); $row = array_merge($row, AVideoPlugin::getAllVideosArray($row['id'])); TimeLogEnd("video::getInfo getAllVideosArray", __LINE__); ObjectYPT::setCache($name, $row); return $row; } public static function htmlDescription($description) { if (strip_tags($description) != $description) { return $description; } else { return nl2br(textToLink(htmlentities($description))); } } public static function isFavorite($videos_id) { if (AVideoPlugin::isEnabledByName("PlayLists")) { return PlayList::isVideoOnFavorite($videos_id, User::getId()); } return false; } public static function isSerie($videos_id) { $v = new Video("", "", $videos_id); return !empty($v->getSerie_playlists_id()); } public static function isWatchLater($videos_id) { if (AVideoPlugin::isEnabledByName("PlayLists")) { return PlayList::isVideoOnWatchLater($videos_id, User::getId()); } return false; } public static function getFavoriteIdFromUser($users_id) { if (AVideoPlugin::isEnabledByName("PlayLists")) { return PlayList::getFavoriteIdFromUser($users_id); } return false; } public static function getWatchLaterIdFromUser($users_id) { if (AVideoPlugin::isEnabledByName("PlayLists")) { return PlayList::getWatchLaterIdFromUser($users_id); } return false; } public static function updateFilesize($videos_id) { global $config; if ($config->currentVersionLowerThen('8.5')) { return false; } TimeLogStart("Video::updateFilesize {$videos_id}"); ini_set('max_execution_time', 300); // 5 set_time_limit(300); $video = new Video("", "", $videos_id); $filename = $video->getFilename(); if (empty($filename) || !($video->getType() == "video" || $video->getType() == "audio" || $video->getType() == "zip" || $video->getType() == "image")) { //_error_log("updateFilesize: Not updated, this filetype is ".$video->getType()); return false; } $filesize = getUsageFromFilename($filename); if (empty($filesize)) { $obj = AVideoPlugin::getObjectDataIfEnabled("DiskUploadQuota"); if (!empty($obj->deleteVideosWith0Bytes)) { try { _error_log("updateFilesize: DELETE videos_id=$videos_id filename=$filename filesize=$filesize"); return $video->delete(); } catch (Exception $exc) { _error_log("updateFilesize: ERROR " . $exc->getTraceAsString()); return false; } } } if ($video->getFilesize() == $filesize) { //_error_log("updateFilesize: No need to update videos_id=$videos_id filename=$filename filesize=$filesize"); return $filesize; } $video->setFilesize($filesize); TimeLogEnd("Video::updateFilesize {$videos_id}", __LINE__); if ($video->save(false, true)) { _error_log("updateFilesize: videos_id=$videos_id filename=$filename filesize=$filesize"); return $filesize; } else { _error_log("updateFilesize: ERROR videos_id=$videos_id filename=$filename filesize=$filesize"); return false; } } /** * Same as getAllVideos() method but a lighter query * @global type $global * @global type $config * @param type $showOnlyLoggedUserVideos * @return boolean */ public static function getAllVideosLight($status = "viewable", $showOnlyLoggedUserVideos = false, $showUnlisted = false, $suggestedOnly = false) { global $global, $config; if ($config->currentVersionLowerThen('5')) { return false; } $status = str_replace("'", "", $status); $sql = "SELECT v.* " . " FROM videos as v " . " WHERE 1=1 "; $blockedUsers = self::getBlockedUsersIdsArray(); if (!empty($blockedUsers)) { $sql .= " AND v.users_id NOT IN ('" . implode("','", $blockedUsers) . "') "; } if ($showOnlyLoggedUserVideos === true && !Permissions::canModerateVideos()) { $sql .= " AND v.users_id = '" . User::getId() . "'"; } elseif (!empty($showOnlyLoggedUserVideos)) { $sql .= " AND v.users_id = '{$showOnlyLoggedUserVideos}'"; } if ($status == "viewable") { if (User::isLogged()) { $sql .= " AND (v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "') OR (v.status='u' AND v.users_id ='" . User::getId() . "'))"; } else { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "')"; } } elseif ($status == "viewableNotUnlisted") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus(false)) . "')"; } elseif (!empty($status)) { $sql .= " AND v.status = '{$status}'"; } if (!empty($_GET['channelName'])) { $user = User::getChannelOwner($_GET['channelName']); $sql .= " AND v.users_id = '{$user['id']}' "; } $sql .= AVideoPlugin::getVideoWhereClause(); if ($suggestedOnly) { $sql .= " AND v.isSuggested = 1 "; $sql .= " ORDER BY RAND() "; } if (strpos(strtolower($sql), 'limit') === false) { if (empty($global['limitForUnlimitedVideos'])) { $global['limitForUnlimitedVideos'] = empty($global['rowCount']) ? 1000 : $global['rowCount']; } if ($global['limitForUnlimitedVideos'] > 0) { $sql .= " LIMIT {$global['limitForUnlimitedVideos']}"; } } //echo $sql; $res = sqlDAL::readSql($sql); $fullData = sqlDAL::fetchAllAssoc($res); // if there is a search, and there is no data and is inside a channel try again without a channel if (!empty($_GET['search']) && empty($fullData) && !empty($_GET['channelName'])) { $channelName = $_GET['channelName']; unset($_GET['channelName']); $return = self::getAllVideosLight($status, $showOnlyLoggedUserVideos, $showUnlisted, $suggestedOnly); $_GET['channelName'] = $channelName; return $return; } sqlDAL::close($res); $videos = array(); if ($res != false) { foreach ($fullData as $row) { if (empty($row['filesize'])) { $row['filesize'] = Video::updateFilesize($row['id']); } $videos[] = $row; } //$videos = $res->fetch_all(MYSQLI_ASSOC); } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $videos; } public static function getTotalVideos($status = "viewable", $showOnlyLoggedUserVideos = false, $ignoreGroup = false, $showUnlisted = false, $activeUsersOnly = true, $suggestedOnly = false) { global $global, $config, $advancedCustomUser; if ($config->currentVersionLowerThen('5')) { return false; } if (!empty($_POST['sort']['suggested'])) { $suggestedOnly = true; } $status = str_replace("'", "", $status); $cn = ""; if (!empty($_GET['catName'])) { $cn .= ", c.clean_name as cn"; } if (AVideoPlugin::isEnabledByName("VideoTags")) { if (!empty($_GET['tags_id']) && empty($videosArrayId)) { TimeLogStart("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})"); $videosArrayId = VideoTags::getAllVideosIdFromTagsId($_GET['tags_id']); TimeLogEnd("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})", __LINE__); } } $sql = "SELECT v.users_id, v.type, v.id, v.title,v.description, c.name as category {$cn} " . "FROM videos v " . "LEFT JOIN categories c ON categories_id = c.id " . " LEFT JOIN users u ON v.users_id = u.id " . " WHERE 1=1 "; $blockedUsers = self::getBlockedUsersIdsArray(); if (!empty($blockedUsers)) { $sql .= " AND v.users_id NOT IN ('" . implode("','", $blockedUsers) . "') "; } if ($activeUsersOnly) { $sql .= " AND u.status = 'a' "; } $sql .= static::getVideoQueryFileter(); if (!$ignoreGroup) { $sql .= self::getUserGroupsCanSeeSQL('v.'); } if (!empty($videosArrayId) && is_array($videosArrayId)) { $sql .= " AND v.id IN ( '" . implode("', '", $videosArrayId) . "') "; } if ($status == "viewable") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus($showUnlisted)) . "')"; } elseif ($status == "viewableNotUnlisted") { $sql .= " AND v.status IN ('" . implode("','", Video::getViewableStatus(false)) . "')"; } elseif (!empty($status)) { $sql .= " AND v.status = '{$status}'"; } if ($showOnlyLoggedUserVideos === true && !Permissions::canModerateVideos()) { $sql .= " AND v.users_id = '" . User::getId() . "'"; } elseif (is_int($showOnlyLoggedUserVideos)) { $sql .= " AND v.users_id = '{$showOnlyLoggedUserVideos}'"; } if (isset($_REQUEST['is_serie'])) { $is_serie = intval($_REQUEST['is_serie']); if (empty($is_serie)) { $sql .= " AND v.serie_playlists_id IS NULL "; } else { $sql .= " AND v.serie_playlists_id IS NOT NULL "; } } if (!empty($_GET['catName'])) { $catName = $global['mysqli']->real_escape_string($_GET['catName']); $sql .= " AND c.clean_name = '{$catName}'"; } if (!empty($_SESSION['type'])) { if ($_SESSION['type'] == 'video') { $sql .= " AND (v.type = 'video' OR v.type = 'embed' OR v.type = 'linkVideo')"; } elseif ($_SESSION['type'] == 'audio') { $sql .= " AND (v.type = 'audio' OR v.type = 'linkAudio')"; } else { $sql .= " AND v.type = '{$_SESSION['type']}' "; } } if (!$ignoreGroup) { $arrayNotIN = AVideoPlugin::getAllVideosExcludeVideosIDArray(); if (!empty($arrayNotIN) && is_array($arrayNotIN)) { $sql .= " AND v.id NOT IN ( '" . implode("', '", $arrayNotIN) . "') "; } } if (!empty($_GET['channelName'])) { $user = User::getChannelOwner($_GET['channelName']); $uid = intval($user['id']); $sql .= " AND v.users_id = '{$uid}' "; } $sql .= AVideoPlugin::getVideoWhereClause(); if (!empty($_POST['searchPhrase'])) { $searchFieldsNames = array('v.title', 'v.description', 'c.name', 'c.description'); if ($advancedCustomUser->videosSearchAlsoSearchesOnChannelName) { $searchFieldsNames[] = 'u.channelName'; } if (AVideoPlugin::isEnabledByName("VideoTags")) { $sql .= " AND ("; $sql .= "v.id IN (select videos_id FROM tags_has_videos LEFT JOIN tags as t ON tags_id = t.id AND t.name LIKE '%{$_POST['searchPhrase']}%' WHERE t.id is NOT NULL)"; $sql .= BootGrid::getSqlSearchFromPost($searchFieldsNames, "OR"); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']); $sql .= ")"; } else { $sql .= ' AND (1=1 ' . BootGrid::getSqlSearchFromPost($searchFieldsNames); $searchFieldsNames = array('v.title'); $sql .= self::getFullTextSearch($searchFieldsNames, $_POST['searchPhrase']) . ')'; } } if ($suggestedOnly) { $sql .= " AND v.isSuggested = 1 "; } $res = sqlDAL::readSql($sql); $numRows = sqlDal::num_rows($res); sqlDAL::close($res); // if there is a search, and there is no data and is inside a channel try again without a channel if (!empty($_GET['search']) && empty($numRows) && !empty($_GET['channelName'])) { $channelName = $_GET['channelName']; unset($_GET['channelName']); $return = self::getTotalVideos($status, $showOnlyLoggedUserVideos, $ignoreGroup, $showUnlisted, $activeUsersOnly, $suggestedOnly); $_GET['channelName'] = $channelName; return $return; } return $numRows; } public static function getTotalVideosInfo($status = "viewable", $showOnlyLoggedUserVideos = false, $ignoreGroup = false, $videosArrayId = array()) { $obj = new stdClass(); $obj->likes = 0; $obj->disLikes = 0; $obj->views_count = 0; $obj->total_minutes = 0; $videos = static::getAllVideos($status, $showOnlyLoggedUserVideos, $ignoreGroup, $videosArrayId); foreach ($videos as $value) { $obj->likes += intval($value['likes']); $obj->disLikes += intval($value['dislikes']); $obj->views_count += intval($value['views_count']); $obj->total_minutes += intval(parseDurationToSeconds($value['duration']) / 60); } return $obj; } public static function getTotalVideosInfoAsync($status = "viewable", $showOnlyLoggedUserVideos = false, $ignoreGroup = false, $videosArrayId = array(), $getStatistcs = false) { global $global, $advancedCustom; $path = getCacheDir() . "getTotalVideosInfo/"; make_path($path); $cacheFileName = "{$path}_{$status}_{$showOnlyLoggedUserVideos}_{$ignoreGroup}_" . implode($videosArrayId) . "_{$getStatistcs}"; $return = array(); if (!file_exists($cacheFileName)) { if (file_exists($cacheFileName . ".lock")) { return array(); } file_put_contents($cacheFileName . ".lock", 1); $total = static::getTotalVideosInfo($status, $showOnlyLoggedUserVideos, $ignoreGroup, $videosArrayId, $getStatistcs); file_put_contents($cacheFileName, json_encode($total)); unlink($cacheFileName . ".lock"); return $total; } $return = _json_decode(file_get_contents($cacheFileName)); if (time() - filemtime($cacheFileName) > cacheExpirationTime()) { // file older than 1 min $command = ("php '{$global['systemRootPath']}objects/getTotalVideosInfoAsync.php' " . " '$status' '$showOnlyLoggedUserVideos' '$ignoreGroup', '" . json_encode($videosArrayId) . "', " . " '$getStatistcs', '$cacheFileName'"); //_error_log("getTotalVideosInfoAsync: {$command}"); exec($command . " > /dev/null 2>/dev/null &"); } return $return; } public static function getViewableStatus($showUnlisted = false) { $viewable = array('a', 'k', 'f'); if ($showUnlisted) { $viewable[] = "u"; } $videos_id = getVideos_id(); if (!empty($videos_id)) { $post = $_POST; if (self::isOwner($videos_id) || Permissions::canModerateVideos()) { $viewable[] = "u"; } $_POST = $post; } return $viewable; } public static function getVideoConversionStatus($filename) { global $global; require_once $global['systemRootPath'] . 'objects/user.php'; if (!User::isLogged()) { die("Only logged users can upload"); } $object = new stdClass(); foreach (self::$types as $value) { $progressFilename = self::getStoragePathFromFileName($filename) . "progress_{$value}.txt"; $content = @url_get_contents($progressFilename); $object->$value = new stdClass(); if (!empty($content)) { $object->$value = self::parseProgress($content); } else { } if (!empty($object->$value->progress) && !is_numeric($object->$value->progress)) { $video = self::getVideoFromFileName($filename); //var_dump($video, $filename); if (!empty($video)) { $object->$value->progress = self::$statusDesc[$video['status']]; } } $object->$value->filename = $progressFilename; } return $object; } private static function parseProgress($content) { //get duration of source $obj = new stdClass(); $obj->duration = 0; $obj->currentTime = 0; $obj->progress = 0; //var_dump($content);exit; preg_match("/Duration: (.*?), start:/", $content, $matches); if (!empty($matches[1])) { $rawDuration = $matches[1]; //rawDuration is in 00:00:00.00 format. This converts it to seconds. $ar = array_reverse(explode(":", $rawDuration)); $duration = floatval($ar[0]); if (!empty($ar[1])) { $duration += intval($ar[1]) * 60; } if (!empty($ar[2])) { $duration += intval($ar[2]) * 60 * 60; } //get the time in the file that is already encoded preg_match_all("/time=(.*?) bitrate/", $content, $matches); $rawTime = array_pop($matches); //this is needed if there is more than one match if (is_array($rawTime)) { $rawTime = array_pop($rawTime); } //rawTime is in 00:00:00.00 format. This converts it to seconds. $ar = array_reverse(explode(":", $rawTime)); $time = floatval($ar[0]); if (!empty($ar[1])) { $time += intval($ar[1]) * 60; } if (!empty($ar[2])) { $time += intval($ar[2]) * 60 * 60; } if (!empty($duration)) { //calculate the progress $progress = round(($time / $duration) * 100); } else { $progress = 'undefined'; } $obj->duration = $duration; $obj->currentTime = $time; $obj->progress = $progress; } return $obj; } public function delete($allowOfflineUser = false) { if (!$allowOfflineUser && !$this->userCanManageVideo()) { return false; } global $global; if (!empty($this->id)) { $this->removeNextVideos($this->id); $this->removeTrailerReference($this->id); $this->removeCampaign($this->id); $video = self::getVideoLight($this->id); $sql = "DELETE FROM videos WHERE id = ?"; } else { return false; } $resp = sqlDAL::writeSql($sql, "i", array($this->id)); if ($resp == false) { _error_log('Error (delete on video) : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); return false; } else { $this->removeVideoFiles(); } return $resp; } public function removeVideoFiles() { $filename = $this->getFilename(); if (empty($filename)) { return false; } $aws_s3 = AVideoPlugin::loadPluginIfEnabled('AWS_S3'); $bb_b2 = AVideoPlugin::loadPluginIfEnabled('Blackblaze_B2'); $ftp = AVideoPlugin::loadPluginIfEnabled('FTP_Storage'); $YPTStorage = AVideoPlugin::loadPluginIfEnabled('YPTStorage'); if (!empty($aws_s3)) { $aws_s3->removeFiles($filename); } if (!empty($bb_b2)) { $bb_b2->removeFiles($filename); } if (!empty($ftp)) { $ftp->removeFiles($filename); } if (!empty($YPTStorage) && !empty($this->getSites_id())) { $YPTStorage->removeFiles($filename, $this->getSites_id()); } $this->removeFiles($filename); self::deleteThumbs($filename); } private function removeNextVideos($videos_id) { if (!$this->userCanManageVideo()) { return false; } global $global; if (!empty($videos_id)) { $sql = "UPDATE videos SET next_videos_id = NULL WHERE next_videos_id = ?"; sqlDAL::writeSql($sql, "s", array($videos_id)); } else { return false; } return true; } private function removeTrailerReference($videos_id) { if (!$this->userCanManageVideo()) { return false; } global $global; if (!empty($videos_id)) { $videoURL = self::getLink($videos_id, '', true); $sql = "UPDATE videos SET trailer1 = '' WHERE trailer1 = ?"; sqlDAL::writeSql($sql, "s", array($videoURL)); $sql = "UPDATE videos SET trailer2 = '' WHERE trailer2 = ?"; sqlDAL::writeSql($sql, "s", array($videoURL)); $sql = "UPDATE videos SET trailer3 = '' WHERE trailer3 = ?"; sqlDAL::writeSql($sql, "s", array($videoURL)); } else { return false; } return true; } private function removeCampaign($videos_id) { if (ObjectYPT::isTableInstalled('vast_campaigns_has_videos')) { if (!empty($this->id)) { $sql = "DELETE FROM vast_campaigns_has_videos "; $sql .= " WHERE videos_id = ?"; $global['lastQuery'] = $sql; return sqlDAL::writeSql($sql, "i", array($videos_id)); } } return false; } private function removeFiles($filename) { if (empty($filename)) { return false; } global $global; $file = self::getStoragePath() . "original_{$filename}"; $this->removeFilePath($file); $files = self::getStoragePath() . "{$filename}"; $this->removeFilePath($files); } private function removeFilePath($filePath) { if (empty($filePath)) { return false; } // Streamlined for less coding space. $files = glob("{$filePath}*"); foreach ($files as $file) { if (file_exists($file)) { if (is_dir($file)) { self::rrmdir($file); } else { @unlink($file); } } } } private static function rrmdir($dir) { if (is_dir($dir)) { $objects = scandir($dir); foreach ($objects as $object) { if ($object != "." && $object != "..") { if (is_dir($dir . "/" . $object)) { self::rrmdir($dir . "/" . $object); } else { unlink($dir . "/" . $object); } } } rmdir($dir); } } public function setDescription($description) { global $global, $advancedCustom; if (empty($advancedCustom->disableHTMLDescription)) { $articleObj = AVideoPlugin::getObjectData('Articles'); $configPuri = HTMLPurifier_Config::createDefault(); $purifier = new HTMLPurifier($configPuri); if (empty($articleObj->allowAttributes)) { $configPuri->set('HTML.AllowedAttributes', array('a.href', 'a.target', 'a.title', 'a.title', 'img.src', 'img.width', 'img.height')); // remove all attributes except a.href $configPuri->set('Attr.AllowedFrameTargets', array('_blank')); } if (empty($articleObj->allowAttributes)) { $configPuri->set('CSS.AllowedProperties', array()); // remove all CSS } $configPuri->set('AutoFormat.RemoveEmpty', true); // remove empty elements $pure = $purifier->purify($description); $parts = explode("", $pure); if (!empty($parts[1])) { $parts = explode("", $parts[1]); } $new_description = $parts[0]; } else { $new_description = strip_tags(br2nl($description)); } AVideoPlugin::onVideoSetDescription($this->id, $this->description, $new_description); //$new_description= preg_replace('/[\xE2\x80\xAF\xBA\x96]/', '', $new_description); if (function_exists('mb_convert_encoding')) { $new_description = mb_convert_encoding($new_description, 'UTF-8', 'UTF-8'); } $this->description = $new_description; //var_dump($this->description, $description, $parts);exit; } public function setCategories_id($categories_id) { if (!Category::userCanAddInCategory($categories_id)) { return false; } // to update old cat as well when auto.. if (!empty($this->categories_id)) { $this->old_categories_id = $this->categories_id; } AVideoPlugin::onVideoSetCategories_id($this->id, $this->categories_id, $categories_id); $this->categories_id = $categories_id; } public static function getCleanDuration($duration = "") { if (empty($duration)) { if (!empty($this) && !empty($this->duration)) { $durationParts = explode(".", $this->duration); } else { return "00:00:00"; } } else { $durationParts = explode(".", $duration); } if (empty($durationParts[0])) { return "00:00:00"; } else { $duration = $durationParts[0]; $durationParts = explode(':', $duration); if (count($durationParts) == 1) { return '0:00:' . static::addZero($durationParts[0]); } elseif (count($durationParts) == 2) { return '0:' . static::addZero($durationParts[0]) . ':' . static::addZero($durationParts[1]); } return $duration; } } private static function addZero($str) { if (intval($str) < 10) { return '0' . intval($str); } return $str; } public static function getItemPropDuration($duration = '') { $duration = static::getCleanDuration($duration); $parts = explode(':', $duration); $duration = 'PT' . intval($parts[0]) . 'H' . intval($parts[1]) . 'M' . intval($parts[2]) . 'S'; if ($duration == "PT0H0M0S") { $duration = "PT0H0M1S"; } return $duration; } public static function getItemDurationSeconds($duration = '') { if ($duration == "EE:EE:EE") { return 0; } $duration = static::getCleanDuration($duration); $parts = explode(':', $duration); return intval($parts[0] * 60 * 60) + intval($parts[1] * 60) + intval($parts[2]); } public static function getDurationFromFile($file) { global $global; // get movie duration HOURS:MM:SS.MICROSECONDS if (!file_exists($file)) { _error_log('{"status":"error", "msg":"getDurationFromFile ERROR, File (' . $file . ') Not Found"}'); return "EE:EE:EE"; } // Initialize getID3 engine $getID3 = new getID3; // Analyze file and store returned data in $ThisFileInfo $ThisFileInfo = $getID3->analyze($file); return static::getCleanDuration(@$ThisFileInfo['playtime_string']); } public static function getResolution($file) { global $videogetResolution; if (!isset($videogetResolution)) { $videogetResolution = array(); } if (isset($videogetResolution[$file])) { return $videogetResolution[$file]; } if ( AVideoPlugin::isEnabledByName("Blackblaze_B2") || AVideoPlugin::isEnabledByName("AWS_S3") || AVideoPlugin::isEnabledByName("FTP_Storage") || AVideoPlugin::isEnabledByName("YPTStorage") || !file_exists($file)) { $videogetResolution[$file] = 0; return 0; } global $global; if (preg_match("/.m3u8$/i", $file) && AVideoPlugin::isEnabledByName('VideoHLS') && method_exists(new VideoHLS(), 'getHLSHigestResolutionFromFile')) { $videogetResolution[$file] = VideoHLS::getHLSHigestResolutionFromFile($file); } else { $getID3 = new getID3; $ThisFileInfo = $getID3->analyze($file); $videogetResolution[$file] = intval(@$ThisFileInfo['video']['resolution_y']); } return $videogetResolution[$file]; } public static function getHLSDurationFromFile($file) { $plugin = AVideoPlugin::loadPluginIfEnabled("VideoHLS"); if (empty($plugin)) { return 0; } return VideoHLS::getHLSDurationFromFile($file); } public function updateHLSDurationIfNeed() { $plugin = AVideoPlugin::loadPluginIfEnabled("VideoHLS"); if (empty($plugin)) { return false; } return VideoHLS::updateHLSDurationIfNeed($this); } public function updateDurationIfNeed($fileExtension = ".mp4") { global $global; $source = self::getSourceFile($this->filename, $fileExtension, true); $file = $source['path']; if (!empty($this->id) && $this->duration == "EE:EE:EE" && file_exists($file)) { $this->duration = Video::getDurationFromFile($file); _error_log("Duration Updated: " . json_encode($this)); $sql = "UPDATE videos SET duration = ?, modified = now() WHERE id = ?"; $res = sqlDAL::writeSql($sql, "si", array($this->duration, $this->id)); return $this->id; } else { _error_log("Do not need update duration: "); return false; } } public function getFilename() { return $this->filename; } public function getStatus() { return $this->status; } public function getId() { return $this->id; } public function getVideoDownloadedLink() { return $this->videoDownloadedLink; } public function setVideoDownloadedLink($videoDownloadedLink) { AVideoPlugin::onVideoSetVideoDownloadedLink($this->id, $this->videoDownloadedLink, $videoDownloadedLink); $this->videoDownloadedLink = $videoDownloadedLink; } public static function isLandscape($pathFileName) { global $config; // get movie duration HOURS:MM:SS.MICROSECONDS if (!file_exists($pathFileName)) { echo '{"status":"error", "msg":"isLandscape ERROR, File (' . $pathFileName . ') Not Found"}'; return true; } eval('$cmd="' . $config->getExiftool() . '";'); $resp = true; // is landscape by default exec($cmd . ' 2>&1', $output, $return_val); if ($return_val !== 0) { $resp = true; } else { $w = 1; $h = 0; $rotation = 0; foreach ($output as $value) { preg_match("/Image Size.*:[^0-9]*([0-9]+x[0-9]+)/i", $value, $match); if (!empty($match)) { $parts = explode("x", $match[1]); $w = $parts[0]; $h = $parts[1]; } preg_match("/Rotation.*:[^0-9]*([0-9]+)/i", $value, $match); if (!empty($match)) { $rotation = $match[1]; } } if ($rotation == 0) { if ($w > $h) { $resp = true; } else { $resp = false; } } else { if ($w < $h) { $resp = true; } else { $resp = false; } } } //var_dump($cmd, $w, $h, $rotation, $resp);exit; return $resp; } public function userCanManageVideo() { global $advancedCustomUser; if (Permissions::canAdminVideos()) { return true; } if (empty($this->users_id) || !User::canUpload()) { return false; } // if you not admin you can only manager yours video $users_id = $this->users_id; if ($advancedCustomUser->userCanChangeVideoOwner) { $video = new Video("", "", $this->id); // query again to make sure the user is not changing the owner $users_id = $video->getUsers_id(); } if ($users_id != User::getId()) { return false; } return true; } public function getVideoGroups() { return $this->videoGroups; } public function setVideoGroups($userGroups) { if (is_array($userGroups)) { AVideoPlugin::onVideoSetVideoGroups($this->id, $this->videoGroups, $userGroups); $this->videoGroups = $userGroups; } } /** * * @param type $user_id * text * label Default Primary Success Info Warning Danger */ public static function getTags($video_id, $type = "") { global $advancedCustom, $videos_getTags; if (empty($videos_getTags)) { $videos_getTags = array(); } $name = "{$video_id}_{$type}"; if (!empty($videos_getTags[$name])) { return $videos_getTags[$name]; } $videos_getTags[$name] = self::getTags_($video_id, $type); return $videos_getTags[$name]; } public static function getTagsHTMLLabelArray($video_id) { global $_getTagsHTMLLabelArray; if (!isset($_getTagsHTMLLabelArray)) { $_getTagsHTMLLabelArray = array(); } if (isset($_getTagsHTMLLabelArray[$video_id])) { return $_getTagsHTMLLabelArray[$video_id]; } $tags = Video::getTags($video_id); $_getTagsHTMLLabelArray[$video_id] = array(); foreach ($tags as $value2) { if (empty($value2->label) || ($value2->label !== __("Paid Content") && $value2->label !== __("Group") && $value2->label !== __("Plugin"))) { continue; } $tooltip = ''; if (!empty($value2->tooltip)) { $icon = $value2->text; if (!empty($value2->tooltipIcon)) { $icon = $value2->tooltipIcon; } $tooltip = ' data-toggle="tooltip" title="' . htmlentities($icon . ' ' . $value2->tooltip) . '" data-html="true"'; } $_getTagsHTMLLabelArray[$video_id][] = '' . $value2->text . ''; } return $_getTagsHTMLLabelArray[$video_id]; } public static function getTags_($video_id, $type = "") { global $advancedCustom, $advancedCustomUser; if (empty($advancedCustom)) { $advancedCustomUser = AVideoPlugin::getObjectData("CustomizeUser"); } if (empty($advancedCustom)) { $advancedCustom = AVideoPlugin::getObjectData("CustomizeAdvanced"); } $currentPage = getCurrentPage(); $rowCount = getRowCount(); $_REQUEST['current'] = 1; $_REQUEST['rowCount'] = 1000; $video = new Video("", "", $video_id); $tags = array(); if (empty($type) || $type === "paid") { $objTag = new stdClass(); $objTag->label = __("Paid Content"); if (!empty($advancedCustom->paidOnlyShowLabels)) { if (!empty($video->getOnly_for_paid())) { $objTag->type = "warning"; $objTag->text = ''; $objTag->tooltip = $advancedCustom->paidOnlyLabel; } else { $objTag->type = "success"; $objTag->text = ''; $objTag->tooltip = $advancedCustom->paidOnlyFreeLabel; } } else { $ppv = AVideoPlugin::getObjectDataIfEnabled("PayPerView"); if ($video->getStatus() === self::$statusFansOnly) { $objTag->type = "warning"; $objTag->text = ''; $objTag->tooltip = __("Fans Only"); } elseif ($advancedCustomUser->userCanProtectVideosWithPassword && !empty($video->getVideo_password())) { $objTag->type = "danger"; $objTag->text = ''; $objTag->tooltip = __("Password Protected"); } elseif (!empty($video->getOnly_for_paid())) { $objTag->type = "warning"; $objTag->text = ''; $objTag->tooltip = $advancedCustom->paidOnlyLabel; } elseif ($ppv && PayPerView::isVideoPayPerView($video_id)) { if (!empty($ppv->showPPVLabel)) { $objTag->type = "warning"; $objTag->text = "PPV"; $objTag->tooltip = __("Pay Per View"); } else { $objTag->type = "warning"; $objTag->text = ''; $objTag->tooltip = __("Private"); } } elseif (!Video::isPublic($video_id)) { $objTag->type = "warning"; $objTag->text = ''; $objTag->tooltip = __("Private"); } else { $objTag->type = "success"; $objTag->text = ''; $objTag->tooltip = $advancedCustom->paidOnlyFreeLabel; } } $tags[] = $objTag; $objTag = new stdClass(); } /** a = active i = inactive e = encoding x = encoding error d = downloading u = unlisted */ if (empty($type) || $type === "status") { $objTag = new stdClass(); $objTag->label = __("Status"); $status = $video->getStatus(); $objTag->text = __(Video::$statusDesc[$status]); switch ($status) { case Video::$statusActive: $objTag->type = "success"; break; case Video::$statusActiveAndEncoding: $objTag->type = "success"; break; case Video::$statusInactive: $objTag->type = "warning"; break; case Video::$statusEncoding: $objTag->type = "info"; break; case Video::$statusDownloading: $objTag->type = "info"; break; case Video::$statusUnlisted: $objTag->type = "info"; break; case Video::$statusRecording: $objTag->type = "danger isRecording isRecordingIcon"; break; default: $objTag->type = "danger"; break; } $objTag->text = $objTag->text; $tags[] = $objTag; $objTag = new stdClass(); } if (empty($type) || $type === "userGroups") { $groups = UserGroups::getVideoGroups($video_id); $objTag = new stdClass(); $objTag->label = __("Group"); if (empty($groups)) { $status = $video->getStatus(); if ($status == 'u') { $objTag->type = "info"; $objTag->text = ''; $objTag->tooltip = __("Unlisted"); $tags[] = $objTag; $objTag = new stdClass(); } else { //$objTag->type = "success"; //$objTag->text = __("Public"); } } else { foreach ($groups as $value) { $objTag = new stdClass(); $objTag->label = __("Group"); $objTag->type = "info"; $objTag->text = ''; $objTag->tooltip = $value['group_name']; $tags[] = $objTag; $objTag = new stdClass(); } } } if (empty($type) || $type === "category") { require_once 'category.php'; $sort = null; if (!empty($_POST['sort']['title'])) { $sort = $_POST['sort']; unset($_POST['sort']); } $category = Category::getCategory($video->getCategories_id()); if (!empty($sort)) { $_POST['sort'] = $sort; } $objTag = new stdClass(); $objTag->label = __("Category"); if (!empty($category)) { $objTag->type = "default"; $objTag->text = $category['name']; $tags[] = $objTag; $objTag = new stdClass(); } } if (empty($type) || $type === "source") { $url = $video->getVideoDownloadedLink(); $parse = parse_url($url); $objTag = new stdClass(); $objTag->label = __("Source"); if (!empty($parse['host'])) { $objTag->type = "danger"; $objTag->text = $parse['host']; $tags[] = $objTag; $objTag = new stdClass(); } else { $objTag->type = "info"; $objTag->text = __("Local File"); $tags[] = $objTag; $objTag = new stdClass(); } } $array2 = AVideoPlugin::getVideoTags($video_id); if (is_array($array2)) { $tags = array_merge($tags, $array2); } //var_dump($tags); $_REQUEST['current'] = $currentPage; $_REQUEST['rowCount'] = $rowCount; return $tags; } public static function deleteTagsAsync($video_id) { global $global; if (empty($video_id)) { return false; } $name = "getVideoTags{$video_id}"; ObjectYPT::deleteCache($name); _session_start(); unset($_SESSION['getVideoTags'][$video_id]); $path = getCacheDir() . "getTagsAsync/"; if (!is_dir($path)) { return false; } $cacheFileName = "{$path}_{$video_id}_"; $files = glob("{$cacheFileName}*"); foreach ($files as $file) { unlink($file); } } public static function getTagsAsync($video_id, $type = "video") { global $global, $advancedCustom; $path = getCacheDir() . "getTagsAsync/"; make_path($path); $cacheFileName = "{$path}_{$video_id}_{$type}"; $return = array(); if (!file_exists($cacheFileName)) { if (file_exists($cacheFileName . ".lock")) { return array(); } file_put_contents($cacheFileName . ".lock", 1); $total = static::getTags_($video_id, $type); file_put_contents($cacheFileName, json_encode($total)); unlink($cacheFileName . ".lock"); return $total; } $return = _json_decode(file_get_contents($cacheFileName)); if (time() - filemtime($cacheFileName) > 300) { // file older than 1 min $command = ("php '{$global['systemRootPath']}objects/getTags.php' '$video_id' '$type' '{$cacheFileName}'"); //_error_log("getTags: {$command}"); exec($command . " > /dev/null 2>/dev/null &"); } return (array) $return; } public function getCategories_id() { return $this->categories_id; } public function getType() { return $this->type; } public static function fixCleanTitle($clean_title, $count, $videoId, $original_title = "") { global $global; if (empty($original_title)) { $original_title = $clean_title; } $sql = "SELECT * FROM videos WHERE clean_title = '{$clean_title}' "; if (!empty($videoId)) { $sql .= " AND id != {$videoId} "; } $sql .= " LIMIT 1"; $res = sqlDAL::readSql($sql, "", array(), true); $cleanTitleExists = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($cleanTitleExists != false) { return self::fixCleanTitle($original_title . "-" . $count, $count + 1, $videoId, $original_title); } return $clean_title; } /** * * @global type $global * @param type $videos_id * @param type $users_id if is empty will use the logged user * @return boolean */ public static function isOwner($videos_id, $users_id = 0) { global $global; if (empty($users_id)) { $users_id = User::getId(); if (empty($users_id)) { return false; } } $video_owner = self::getOwner($videos_id); if ($video_owner) { if ($video_owner == $users_id) { return true; } } return false; } public static function isOwnerFromCleanTitle($clean_title, $users_id = 0) { global $global; $video = self::getVideoFromCleanTitle($clean_title); return self::isOwner($video['id'], $users_id); } /** * * @global type $global * @param type $videos_id * @param type $users_id if is empty will use the logged user * @return boolean */ public static function getOwner($videos_id) { global $global; $sql = "SELECT users_id FROM videos WHERE id = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "i", array($videos_id)); $videoRow = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { if ($videoRow != false) { return $videoRow['users_id']; } } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return false; } /** * * @param type $videos_id * @param type $users_id if is empty will use the logged user * @return boolean */ public static function canEdit($videos_id, $users_id = 0) { if (empty($videos_id)) { return false; } if (empty($users_id)) { $users_id = User::getId(); if (empty($users_id)) { return false; } } $user = new User($users_id); if (empty($user)) { return false; } if ($user->getIsAdmin()) { return true; } if (Permissions::canAdminVideos()) { return true; } return self::isOwner($videos_id, $users_id); } public static function getRandom($excludeVideoId = false) { return static::getVideo("", "viewable", false, $excludeVideoId); } public static function getVideoQueryFileter() { global $global; $sql = ""; if (!empty($_GET['playlist_id'])) { require_once $global['systemRootPath'] . 'objects/playlist.php'; $ids = PlayList::getVideosIdFromPlaylist($_GET['playlist_id']); if (!empty($ids)) { $sql .= " AND v.id IN (" . implode(",", $ids) . ") "; } } return $sql; } public function getTitle() { return $this->title; } public function getClean_title() { return $this->clean_title; } public function getDescription() { return $this->description; } public function getExistingVideoFile() { $source = self::getHigestResolutionVideoMP4Source($this->getFilename(), true); if (empty($source)) { _error_log("getExistingVideoFile:: resources are empty " . $this->getFilename()); return false; } $size = filesize($source['path']); if ($size <= 20) {// it is a dummy file $url = $source['url']; _error_log("getExistingVideoFile:: dummy file, download it " . json_encode($source)); $filename = getTmpDir("getExistingVideoFile") . md5($url); copyfile_chunked($url, $filename); wget($url, $filename); return $filename; } return $source['path']; } public function getTrailer1() { return $this->trailer1; } public function getTrailer2() { return $this->trailer2; } public function getTrailer3() { return $this->trailer3; } public function getRate() { return $this->rate; } public function setTrailer1($trailer1) { if (filter_var($trailer1, FILTER_VALIDATE_URL)) { $new_trailer1 = $trailer1; } else { $new_trailer1 = ""; } AVideoPlugin::onVideoSetTrailer1($this->id, $this->trailer1, $new_trailer1); $this->trailer1 = $new_trailer1; } public function setTrailer2($trailer2) { if (filter_var($trailer2, FILTER_VALIDATE_URL)) { $new_trailer2 = $trailer2; } else { $new_trailer2 = ""; } AVideoPlugin::onVideoSetTrailer2($this->id, $this->trailer2, $new_trailer2); $this->trailer2 = $new_trailer2; } public function setTrailer3($trailer3) { if (filter_var($trailer3, FILTER_VALIDATE_URL)) { $new_trailer3 = $trailer3; } else { $new_trailer3 = ""; } AVideoPlugin::onVideoSetTrailer3($this->id, $this->trailer3, $new_trailer3); $this->trailer3 = $new_trailer3; } public function setRate($rate) { AVideoPlugin::onVideoSetRate($this->id, $this->rate, floatval($rate)); $this->rate = floatval($rate); } public function getYoutubeId() { return $this->youtubeId; } public function setYoutubeId($youtubeId) { AVideoPlugin::onVideoSetYoutubeId($this->id, $this->youtubeId, $youtubeId); $this->youtubeId = $youtubeId; } public function setTitle($title) { if ($title === "Video automatically booked" && !empty($this->title)) { return false; } $new_title = strip_tags($title); if (strlen($new_title) > 190) { $new_title = substr($new_title, 0, 187) . '...'; } AVideoPlugin::onVideoSetTitle($this->id, $this->title, $new_title); $this->title = $new_title; } public function setFilename($filename, $force = false) { if ($force || empty($this->filename)) { AVideoPlugin::onVideoSetFilename($this->id, $this->filename, $filename, $force); $this->filename = $filename; } else { _error_log('setFilename: fail ' . $filename . " {$this->id}"); } return $this->filename; } public function getNext_videos_id() { return $this->next_videos_id; } public function setNext_videos_id($next_videos_id) { AVideoPlugin::onVideoSetNext_videos_id($this->id, $this->next_videos_id, $next_videos_id); $this->next_videos_id = $next_videos_id; } public function queue($types = array()) { global $config; if (!User::canUpload()) { return false; } global $global; $obj = new stdClass(); $obj->error = true; $target = $config->getEncoderURL() . "queue"; $postFields = array( 'user' => User::getUserName(), 'pass' => User::getUserPass(), 'fileURI' => $global['webSiteRootURL'] . "videos/original_{$this->getFilename()}", 'filename' => $this->getFilename(), 'videos_id' => $this->getId(), "notifyURL" => "{$global['webSiteRootURL']}" ); if (empty($types) && AVideoPlugin::isEnabledByName("VideoHLS")) { $postFields['inputHLS'] = 1; } elseif (!empty($types)) { foreach ($types as $key => $value) { $postFields[$key] = $value; } } _error_log("SEND To QUEUE: ($target) " . json_encode($postFields)); $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $target); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POST, 1); curl_setopt($curl, CURLOPT_SAFE_UPLOAD, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $postFields); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false); $r = curl_exec($curl); $obj->response = $r; if ($errno = curl_errno($curl)) { $error_message = curl_strerror($errno); //echo "cURL error ({$errno}):\n {$error_message}"; $obj->msg = "cURL error ({$errno}):\n {$error_message}"; } else { $obj->error = false; } _error_log("QUEUE CURL: ($target) " . json_encode($obj)); curl_close($curl); return $obj; } public function getVideoLink() { return $this->videoLink; } public function setVideoLink($videoLink) { AVideoPlugin::onVideoSetVideoLink($this->id, $this->videoLink, $videoLink); $this->videoLink = $videoLink; } public function getCan_download() { return $this->can_download; } public function getCan_share() { return $this->can_share; } public function setCan_download($can_download) { $new_can_download = (empty($can_download) || $can_download === "false") ? 0 : 1; AVideoPlugin::onVideoSetCan_download($this->id, $this->can_download, $new_can_download); $this->can_download = $new_can_download; } public function setCan_share($can_share) { $new_can_share = (empty($can_share) || $can_share === "false") ? 0 : 1; AVideoPlugin::onVideoSetCan_share($this->id, $this->can_share, $new_can_share); $this->can_share = $new_can_share; } public function getOnly_for_paid() { return $this->only_for_paid; } public function setOnly_for_paid($only_for_paid) { $new_only_for_paid = (empty($only_for_paid) || $only_for_paid === "false") ? 0 : 1; AVideoPlugin::onVideoSetOnly_for_paid($this->id, $this->only_for_paid, $new_only_for_paid); $this->only_for_paid = $new_only_for_paid; } /** * * @param type $filename * @param type $type * @return type .jpg .gif .webp _thumbs.jpg _Low.mp4 _SD.mp4 _HD.mp4 */ public static function getSourceFile($filename, $type = ".jpg", $includeS3 = false) { global $global, $advancedCustom, $videosPaths, $VideoGetSourceFile; //if(!isValidFormats($type)){ //return array(); //} self::_moveSourceFilesToDir($filename); $paths = self::getPaths($filename); if ($type == '_thumbsSmallV2.jpg' && empty($advancedCustom->usePreloadLowResolutionImages)) { return array('path' => $global['systemRootPath'] . 'view/img/loading-gif.png', 'url' => getCDN() . 'view/img/loading-gif.png'); } $cacheName = md5($filename . $type . $includeS3); if (0 && isset($VideoGetSourceFile[$cacheName]) && is_array($VideoGetSourceFile[$cacheName])) { if (!preg_match("/token=/", $VideoGetSourceFile[$cacheName]['url'])) { return $VideoGetSourceFile[$cacheName]; } } // check if there is a webp image if ($type === '.gif' && (empty($_SERVER['HTTP_USER_AGENT']) || get_browser_name($_SERVER['HTTP_USER_AGENT']) !== 'Safari')) { $path = "{$paths['path']}{$filename}.webp"; if (file_exists($path)) { $type = ".webp"; } } if (empty($videosPaths[$filename][$type][intval($includeS3)])) { $aws_s3 = AVideoPlugin::loadPluginIfEnabled('AWS_S3'); $bb_b2 = AVideoPlugin::loadPluginIfEnabled('Blackblaze_B2'); $ftp = AVideoPlugin::loadPluginIfEnabled('FTP_Storage'); if (!empty($aws_s3)) { $aws_s3_obj = $aws_s3->getDataObject(); if (!empty($aws_s3_obj->useS3DirectLink)) { $includeS3 = true; } } elseif (!empty($bb_b2)) { $bb_b2_obj = $bb_b2->getDataObject(); if (!empty($bb_b2_obj->useDirectLink)) { $includeS3 = true; } } elseif (!empty($ftp)) { $includeS3 = true; } $token = ""; $secure = AVideoPlugin::loadPluginIfEnabled('SecureVideosDirectory'); if ((preg_match("/.*\\.mp3$/", $type) || preg_match("/.*\\.mp4$/", $type) || preg_match("/.*\\.webm$/", $type) || $type == ".m3u8" || $type == ".pdf" || $type == ".zip")) { $vars = array(); if (!empty($secure)) { $vars[] = $secure->getToken($filename); } if (!empty($vars)) { $token = "?" . implode("&", $vars); } } $paths = self::getPaths($filename); $source = array(); $source['path'] = $paths['path'] . "{$filename}{$type}"; if ($type == ".m3u8") { $source['path'] = self::getStoragePath() . "{$filename}/index{$type}"; } $cleanFileName = self::getCleanFilenameFromFile($filename); $video = Video::getVideoFromFileNameLight($cleanFileName); if (empty($video)) { _error_log("Video::getSourceFile($filename, $type, $includeS3) ERROR video not found ($cleanFileName)"); $VideoGetSourceFile[$cacheName] = false; return false; } $canUseCDN = canUseCDN($video['id']); if (!empty($video['sites_id']) && (preg_match("/.*\\.mp3$/", $type) || preg_match("/.*\\.mp4$/", $type) || preg_match("/.*\\.webm$/", $type) || $type == ".m3u8" || $type == ".pdf" || $type == ".zip") && @filesize($source['path']) < 20) { $site = new Sites($video['sites_id']); $siteURL = getCDNOrURL($site->getUrl(), 'CDN_YPTStorage', $video['sites_id']); $source['url'] = "{$siteURL}{$paths['relative']}{$filename}{$type}{$token}"; if ($type == ".m3u8") { $source['url'] = "{$siteURL}videos/{$filename}/index{$type}{$token}"; } } elseif (!empty($advancedCustom->videosCDN) && $canUseCDN) { $advancedCustom->videosCDN = rtrim($advancedCustom->videosCDN, '/') . '/'; $source['url'] = "{$advancedCustom->videosCDN}{$paths['relative']}{$filename}{$type}{$token}"; if ($type == ".m3u8") { $source['url'] = "{$advancedCustom->videosCDN}videos/{$filename}/index{$type}{$token}"; } } else { $source['url'] = getCDN() . "{$paths['relative']}{$filename}{$type}{$token}"; if ($type == ".m3u8") { $source['url'] = getCDN() . "videos/{$filename}/index{$type}{$token}"; } } /* need it because getDurationFromFile */ if ($includeS3 && ($type == ".mp4" || $type == ".webm" || $type == ".mp3" || $type == ".ogg" || $type == ".pdf" || $type == ".zip")) { if (file_exists($source['path']) && filesize($source['path']) < 1024) { if (!empty($aws_s3)) { $source = $aws_s3->getAddress("{$filename}{$type}"); $source['url'] = replaceCDNIfNeed($source['url'], 'CDN_S3'); } elseif (!empty($bb_b2)) { $source = $bb_b2->getAddress("{$filename}{$type}"); $source['url'] = replaceCDNIfNeed($source['url'], 'CDN_B2'); } elseif (!empty($ftp)) { $source = $ftp->getAddress("{$filename}{$type}"); $source['url'] = replaceCDNIfNeed($source['url'], 'CDN_FTP'); } } } if (!file_exists($source['path']) || ($type !== ".m3u8" && !is_dir($source['path']) && (filesize($source['path']) < 1000 && filesize($source['path']) != 10))) { if ($type != "_thumbsV2.jpg" && $type != "_thumbsSmallV2.jpg" && $type != "_portrait_thumbsV2.jpg" && $type != "_portrait_thumbsSmallV2.jpg") { $VideoGetSourceFile[$cacheName] = array('path' => false, 'url' => false); //if($type=='.jpg'){echo '----'.PHP_EOL;var_dump($type, $source);echo '----'.PHP_EOL;}; //echo PHP_EOL.'---'.PHP_EOL;var_dump($source, $type, !file_exists($source['path']), ($type !== ".m3u8" && !is_dir($source['path']) && (filesize($source['path']) < 1000 && filesize($source['path']) != 10)));echo PHP_EOL.'+++'.PHP_EOL; return $VideoGetSourceFile[$cacheName]; } } $videosPaths[$filename][$type][intval($includeS3)] = $source; } else { $source = $videosPaths[$filename][$type][intval($includeS3)]; } if (substr($type, -4) === ".jpg" || substr($type, -4) === ".png" || substr($type, -4) === ".gif" || substr($type, -4) === ".webp") { $x = uniqid(); if (file_exists($source['path'])) { - $x = filemtime($source['path']); + $x = filemtime($source['path']).filectime($source['path']); } elseif (!empty($video)) { $x = strtotime($video['modified']); } - $source['url'] .= "?{$x}"; + $source['url'] .= "?cache={$x}"; } //ObjectYPT::setCache($name, $source); $VideoGetSourceFile[$cacheName] = $source; return $VideoGetSourceFile[$cacheName]; } private static function _moveSourceFilesToDir($videoFilename) { $videoFilename = self::getCleanFilenameFromFile($videoFilename); if (preg_match('/^(hd|low|sd|(res[0-9]{3,4}))$/', $videoFilename)) { return false; } $paths = self::getPaths($videoFilename); $lock = "{$paths['path']}.move_v1.lock"; if (file_exists($lock)) { return true; } $videosDir = self::getStoragePath(); make_path($paths['path']); $files = _glob($videosDir, '/' . $videoFilename . '[._][a-z0-9_]+/i'); //var_dump($paths['path'], is_dir($paths['path']), $files);exit; foreach ($files as $oldname) { if (is_dir($oldname)) { continue; } $newname = str_replace($videosDir, $paths['path'], $oldname); rename($oldname, $newname); } return file_put_contents($lock, time()); } public static function getPaths($videoFilename, $createDir = false) { global $global, $__getPaths; if (!isset($__getPaths)) { $__getPaths = array(); } if (!empty($__getPaths[$videoFilename])) { return $__getPaths[$videoFilename]; } $cleanVideoFilename = self::getCleanFilenameFromFile($videoFilename); $videosDir = self::getStoragePath(); if (is_dir("{$videosDir}{$videoFilename}")) { $path = addLastSlash("{$videosDir}{$videoFilename}"); //} else if (preg_match('/index\.m3u8$/', $videoFilename)) { // $path = addLastSlash($videosDir); } else { $path = addLastSlash("{$videosDir}{$cleanVideoFilename}"); } $path = fixPath($path); if ($createDir) { make_path(addLastSlash($path)); } $relative = addLastSlash("videos/{$cleanVideoFilename}"); $url = getCDN() . "{$relative}"; $__getPaths[$videoFilename] = array('filename' => $cleanVideoFilename, 'path' => $path, 'url' => $url, 'relative' => $relative); return $__getPaths[$videoFilename]; } public static function getPathToFile($videoFilename, $createDir = false) { $videosDir = self::getStoragePath(); $videoFilename = str_replace($videosDir, '', $videoFilename); $paths = Video::getPaths($videoFilename, $createDir); if (preg_match('/index.m3u8$/', $videoFilename)) { $paths['path'] = rtrim($paths['path'], DIRECTORY_SEPARATOR); $videoFilename = str_replace($paths['filename'], '', $videoFilename); } return "{$paths['path']}{$videoFilename}"; } public static function getURLToFile($videoFilename, $createDir = false) { $videosDir = self::getStoragePath(); $videoFilename = str_replace($videosDir, '', $videoFilename); $paths = Video::getPaths($videoFilename, $createDir); return "{$paths['url']}{$videoFilename}"; } public static function getURLToFileIfExists($videoFilename) { $paths = Video::getPaths($videoFilename); if (!file_exists("{$paths['path']}{$videoFilename}")) { return false; } return "{$paths['url']}{$videoFilename}"; } public static function getNewVideoFilename($prefix = '', $time = '') { $uid = substr(uniqid(), -4); if (empty($time)) { $time = time(); } $prefix = preg_replace('/[^a-z0-9]/i', '', $prefix); if (empty($prefix)) { $prefix = 'v'; } $date = date('ymdHis', $time); $videoFilename = strtolower("{$prefix}_{$date}_{$uid}"); return self::getPaths($videoFilename); } public static function isNewVideoFilename($filename) { $filename = self::getCleanFilenameFromFile($filename); return preg_match('/_([0-9]{12})_([0-9a-z]{4})$/i', $filename); } public static function getNewVideoFilenameWithPrefixFromFilename($filename) { $video = self::getVideoFromFileNameLight($filename); if (empty($video)) { return self::getNewVideoFilename(); } return self::getNewVideoFilename($video['type']); } public static function updateDirectoryFilename($directory) { if (!is_dir($directory)) { _error_log('Video::updateDirectoryFilename directory not found ' . "[{$directory}]"); return false; } $video = self::getVideoFromFileNameLight($directory); if (empty($video)) { _error_log('Video::updateDirectoryFilename video not found for directory ' . "[{$directory}]"); return false; } if (isAnyStorageEnabled()) { $newFilename = self::getPaths($video['filename']); $id = $video['id']; } else { $newFilename = self::getNewVideoFilename($video['type'], strtotime($video['created'])); $v = new Video('', '', $video['id']); $v->setFilename($newFilename['filename'], true); $id = $v->save(false, true); } if ($id) { $renamed = rename($directory, $newFilename['path']); if (empty($renamed)) { // rename dir fail rollback _error_log('Video::updateDirectoryFilename rename dir fail, we will rollback changes ' . "[olddir={$directory}] [newdir={$newFilename['path']}]"); $v = new Video('', '', $video['id']); $v->setFilename($video['filename'], true); $id = $v->save(false, true); return false; } else { _error_log('Video::updateDirectoryFilename video folder renamed from ' . "[olddir={$directory}] [newdir={$newFilename['path']}]"); self::updateFilesInDirectoryFilename($newFilename['path']); } } return array('videos_id' => $video['id'], 'filename' => $newFilename['filename'], 'oldDir' => $directory, 'newDir' => $newFilename['path']); } public static function updateFilesInDirectoryFilename($directory) { if (!is_dir($directory)) { _error_log('Video::updateFilesInDirectoryFilename directory not found ' . "[{$directory}]"); return false; } $video = self::getVideoFromFileNameLight($directory); if (empty($video)) { _error_log('Video::updateFilesInDirectoryFilename video not found for directory ' . "[{$directory}]"); return false; } $newFilename = $video['filename']; $files = glob("{$directory}*.{jpg,png,gif,webp,vtt,srt,mp4,webm,mp3,ogg,notfound}", GLOB_BRACE); _error_log('Video::updateFilesInDirectoryFilename total files found ' . count($files)); foreach ($files as $value) { $oldFilename = self::getCleanFilenameFromFile($value); $newFilenamePath = str_replace($oldFilename, $newFilename, $value); $renamed = rename($value, $newFilenamePath); if (empty($renamed)) { // rename dir fail rollback _error_log('Video::updateFilesInDirectoryFilename rename file fail ' . "[olddir={$value}] [newdir={$newFilenamePath}]"); } else { _error_log('Video::updateFilesInDirectoryFilename video file renamed from ' . "[olddir={$value}] [newdir={$newFilenamePath}]"); } } } public function getVideoIdHash() { $obj = new stdClass(); $obj->videos_id = $this->id; return encryptString(json_encode($obj)); } public static function getVideoIdFromHash($hash) { $string = decryptString($hash); if (!empty($string)) { $json = json_decode($string); if (!empty($json) && !empty($json->videos_id)) { return $json->videos_id; } } return false; } public static function getCleanFilenameFromFile($filename) { global $global; if (empty($filename)) { return ""; } $filename = fixPath($filename); $filename = str_replace(getVideosDir(), '', $filename); if (preg_match('/videos[\/\\\]([^\/\\\]+)[\/\\\].*index.m3u8$/', $filename, $matches)) { return $matches[1]; } $search = array('_Low', '_SD', '_HD', '_thumbsV2', '_thumbsSmallV2', '_thumbsSprit', '_roku', '_portrait', '_portrait_thumbsV2', '_portrait_thumbsSmallV2', '_spectrum', '_tvg', '.notfound'); if (!empty($global['langs_codes_values_withdot']) && is_array($global['langs_codes_values_withdot'])) { $search = array_merge($search, $global['langs_codes_values_withdot']); } if (empty($global['avideo_resolutions']) || !is_array($global['avideo_resolutions'])) { $global['avideo_resolutions'] = array(240, 360, 480, 540, 720, 1080, 1440, 2160); } foreach ($global['avideo_resolutions'] as $value) { $search[] = "_{$value}"; $search[] = "res{$value}"; } $cleanName = str_replace($search, '', $filename); $path_parts = pathinfo($cleanName); if (empty($path_parts['extension'])) { //_error_log("Video::getCleanFilenameFromFile could not find extension of ".$filename); if (!empty($path_parts['filename'])) { return $path_parts['filename']; } else { return $filename; } } else if (strlen($path_parts['extension']) > 4) { return $cleanName; } else if ($path_parts['filename'] == 'index' && $path_parts['extension'] == 'm3u8') { $parts = explode(DIRECTORY_SEPARATOR, $cleanName); if (!empty($parts[0])) { return $parts[0]; } return $parts[1]; } else { return $path_parts['filename']; } } public static function getSpecificResolution($filename, $desired_resolution) { $filename = self::getCleanFilenameFromFile($filename); $cacheName = "getSpecificResolution($filename)"; $return = ObjectYPT::getCache($cacheName, 0); if (!empty($return)) { return object_to_array($return); } $name0 = "Video:::getSpecificResolution($filename)"; TimeLogStart($name0); $name1 = "Video:::getSpecificResolution::getVideosURL_V2($filename)"; TimeLogStart($name1); $sources = getVideosURL_V2($filename); if (!is_array($sources)) { _error_log("Video:::getSpecificResolution::getVideosURL_V2($filename) does not return an array " . json_encode($sources)); return array(); } TimeLogEnd($name1, __LINE__); $return = array(); foreach ($sources as $key => $value) { if ($value['type'] === 'video') { $parts = explode("_", $key); $resolution = intval(@$parts[1]); if (empty($resolution)) { $name2 = "Video:::getSpecificResolution::getResolution({$value["path"]})"; TimeLogStart($name2); $resolution = self::getResolution($value["path"]); TimeLogEnd($name2, __LINE__); } if (!isset($return['resolution']) || $resolution == $desired_resolution) { $return = $value; $return['resolution'] = $resolution; $return['resolution_text'] = getResolutionText($return['resolution']); $return['resolution_label'] = getResolutionLabel($return['resolution']); $return['resolution_string'] = trim($resolution . "p {$return['resolution_label']}"); } } } TimeLogEnd($name0, __LINE__); ObjectYPT::setCache($cacheName, $return); return $return; } public static function getHigestResolution($filename) { global $global; $filename = self::getCleanFilenameFromFile($filename); $cacheName = "getHigestResolution($filename)"; $return = ObjectYPT::getCache($cacheName, 0); if (!empty($return)) { return object_to_array($return); } $name0 = "Video:::getHigestResolution($filename)"; TimeLogStart($name0); $name1 = "Video:::getHigestResolution::getVideosURL_V2($filename)"; TimeLogStart($name1); $sources = getVideosURL_V2($filename); if (!is_array($sources)) { _error_log("Video:::getHigestResolution::getVideosURL_V2($filename) does not return an array " . json_encode($sources)); return array(); } TimeLogEnd($name1, __LINE__); $return = array(); foreach ($sources as $key => $value) { if ($value['type'] === 'video') { $parts = explode("_", $key); $resolution = intval(@$parts[1]); if (empty($resolution)) { $name2 = "Video:::getHigestResolution::getResolution({$value["path"]})"; TimeLogStart($name2); $resolution = self::getResolutionFromFilename($value["path"]); // this is faster if ($resolution && empty($global['onlyGetResolutionFromFilename'])) { _error_log("Video:::getHigestResolution:: could not get the resolution from file name [{$value["path"]}], trying a slower method"); $resolution = self::getResolution($value["path"]); } TimeLogEnd($name2, __LINE__); } if (!isset($return['resolution']) || $resolution > $return['resolution']) { $return = $value; $return['resolution'] = $resolution; $return['resolution_text'] = getResolutionText($return['resolution']); $return['resolution_label'] = getResolutionLabel($return['resolution']); $return['resolution_string'] = trim($resolution . "p {$return['resolution_label']}"); } } } TimeLogEnd($name0, __LINE__); ObjectYPT::setCache($cacheName, $return); return $return; } public static function getResolutionFromFilename($filename) { $resolution = false; if (preg_match("/_([0-9]+).(mp4|webm)/i", $filename, $matches)) { if (!empty($matches[1])) { $resolution = intval($matches[1]); } } elseif (preg_match('/res([0-9]+)\/index.m3u8/i', $filename, $matches)) { if (!empty($matches[1])) { $resolution = intval($matches[1]); } } //var_dump($filename, $resolution);exit; return $resolution; } public static function getHigestResolutionVideoMP4Source($filename, $includeS3 = false) { global $global; $types = array('', '_HD', '_SD', '_Low'); $resolutions = $global['avideo_resolutions']; rsort($resolutions); foreach ($resolutions as $value) { $types[] = "_{$value}"; } foreach ($types as $value) { $source = self::getSourceFile($filename, $value . ".mp4", $includeS3); if (!empty($source['url'])) { return $source; } } return false; } public static function getHigherVideoPathFromID($videos_id) { global $global; if (empty($videos_id)) { return false; } $paths = self::getVideosPathsFromID($videos_id); $types = array(0, 2160, 1440, 1080, 720, 'HD', 'SD', 'Low', 540, 480, 360, 240); if (!empty($paths['mp4'])) { foreach ($types as $value) { if (!empty($paths['mp4'][$value])) { if (is_string($paths['mp4'][$value])) { return $paths['mp4'][$value]; } else { return $paths['mp4'][$value]["url"]; } } } } if (!empty($paths['webm'])) { foreach ($types as $value) { if (!empty($paths['webm'][$value])) { if (is_string($paths['webm'][$value])) { return $paths['webm'][$value]; } else { return $paths['webm'][$value]["url"]; } } } } if (!empty($paths['m3u8'])) { if (!empty($paths['m3u8'])) { if (is_string($paths['m3u8']["url"])) { return $paths['m3u8']["url"]; } elseif (is_string($paths['m3u8'][$value])) { return $paths['m3u8'][$value]; } else { return $paths['m3u8'][$value]["url"]; } } } if (!empty($paths['mp3'])) { return $paths['mp3']; } return false; } public static function getVideosPathsFromID($videos_id) { if (empty($videos_id)) { return false; } $video = new Video("", "", $videos_id); return self::getVideosPaths($video->getFilename(), true); } public static function getVideosPaths($filename, $includeS3 = false) { global $global; $types = array('', '_Low', '_SD', '_HD'); foreach ($global['avideo_resolutions'] as $value) { $types[] = "_{$value}"; } $videos = array(); $plugin = AVideoPlugin::loadPluginIfEnabled("VideoHLS"); if (!empty($plugin)) { $videos = VideoHLS::getSourceFile($filename, $includeS3); } foreach ($types as $value) { $source = self::getSourceFile($filename, $value . ".mp4", $includeS3); if (!empty($source['url'])) { $videos['mp4'][str_replace("_", "", $value)] = $source['url']; } } foreach ($types as $value) { $source = self::getSourceFile($filename, $value . ".webm", $includeS3); if (!empty($source['url'])) { $videos['webm'][str_replace("_", "", $value)] = $source['url']; } } $source = self::getSourceFile($filename, ".pdf", $includeS3); if (!empty($source['url'])) { $videos['pdf'] = $source['url']; } $source = self::getSourceFile($filename, ".zip", $includeS3); if (!empty($source['url'])) { $videos['zip'] = $source['url']; } $source = self::getSourceFile($filename, ".mp3", $includeS3); if (!empty($source['url'])) { $videos['mp3'] = $source['url']; } return $videos; } public static function getStoragePath() { global $global; $path = "{$global['systemRootPath']}videos" . DIRECTORY_SEPARATOR; return $path; } public static function getStoragePathFromFileName($filename) { $cleanFileName = self::getCleanFilenameFromFile($filename); $path = self::getStoragePath() . "{$cleanFileName}/"; make_path($path); return $path; } public static function getStoragePathFromVideosId($videos_id) { $v = new Video("", "", $videos_id); return self::getStoragePathFromFileName($v->getFilename()); } public static function getImageFromFilename($filename, $type = "video", $async = false) { global $advancedCustom; // I dont know why but I had to remove it to avoid ERR_RESPONSE_HEADERS_TOO_BIG header_remove('Set-Cookie'); if (!$async) { return self::getImageFromFilename_($filename, $type); } else { return self::getImageFromFilenameAsync($filename, $type); } } public static function getPoster($videos_id) { $images = self::getImageFromID($videos_id); if (!empty($images->poster)) { return $images->poster; } if (!empty($images->posterPortrait)) { return $images->poster; } return false; } public static function getRokuImage($videos_id) { global $global; $images = self::getImageFromID($videos_id); $imagePath = $images->posterLandscapePath; if (empty($imagePath) || !file_exists($imagePath)) { $imagePath = $images->posterLandscapeThumbs; } if (empty($imagePath) || !file_exists($imagePath)) { $imagePath = $images->poster; } $rokuImage = str_replace(".jpg", "_roku.jpg", $imagePath); if (convertImageToRoku($images->posterLandscapePath, $rokuImage)) { return str_replace($global['systemRootPath'], $global['webSiteRootURL'], $rokuImage); } return "" . getCDN() . "view/img/notfound.jpg"; } public static function clearImageCache($filename, $type = "video") { $cacheFileName = "getImageFromFilename_" . $filename . $type . (get_browser_name() == 'Safari' ? "s" : ""); return ObjectYPT::deleteCache($cacheFileName); } public static function getImageFromFilename_($filename, $type = "video") { if (empty($filename)) { return array(); } global $_getImageFromFilename_; if (empty($_getImageFromFilename_)) { $_getImageFromFilename_ = array(); } $cacheFileName = "getImageFromFilename_" . $filename . $type . (get_browser_name() == 'Safari' ? "s" : ""); if (!empty($_getImageFromFilename_[$cacheFileName])) { $obj = $_getImageFromFilename_[$cacheFileName]; } else { $cache = ObjectYPT::getCache($cacheFileName, 0); if (!empty($cache)) { return $cache; } global $global, $advancedCustom; /* $name = "getImageFromFilename_{$filename}{$type}_"; $cached = ObjectYPT::getCache($name, 86400);//one day if(!empty($cached)){ return $cached; } * */ $obj = new stdClass(); $gifSource = self::getSourceFile($filename, ".gif"); $gifPortraitSource = self::getSourceFile($filename, "_portrait.gif"); $jpegSource = self::getSourceFile($filename, ".jpg"); $jpegPortraitSource = self::getSourceFile($filename, "_portrait.jpg"); $jpegPortraitThumbs = self::getSourceFile($filename, "_portrait_thumbsV2.jpg"); $jpegPortraitThumbsSmall = self::getSourceFile($filename, "_portrait_thumbsSmallV2.jpg"); $thumbsSource = self::getSourceFile($filename, "_thumbsV2.jpg"); $thumbsSmallSource = self::getSourceFile($filename, "_thumbsSmallV2.jpg"); $spectrumSource = self::getSourceFile($filename, "_spectrum.jpg"); if (empty($jpegSource)) { return array(); } $obj->poster = $jpegSource['url']; $obj->posterPortrait = $jpegPortraitSource['url']; $obj->posterPortraitPath = $jpegPortraitSource['path']; $obj->posterPortraitThumbs = $jpegPortraitThumbs['url']; $obj->posterPortraitThumbsSmall = $jpegPortraitThumbsSmall['url']; $obj->thumbsGif = $gifSource['url']; $obj->gifPortrait = $gifPortraitSource['url']; $obj->thumbsJpg = $thumbsSource['url']; $obj->thumbsJpgSmall = $thumbsSmallSource['url']; $obj->spectrumSource = $spectrumSource['url']; $obj->posterLandscape = $jpegSource['url']; $obj->posterLandscapePath = $jpegSource['path']; $obj->posterLandscapeThumbs = $thumbsSource['url']; $obj->posterLandscapeThumbsSmall = $thumbsSmallSource['url']; if (file_exists($gifSource['path'])) { $obj->thumbsGif = $gifSource['url']; } if (file_exists($jpegPortraitSource['path'])) { // create thumbs if (!file_exists($jpegPortraitThumbs['path']) && filesize($jpegPortraitSource['path']) > 1024) { _error_log("Resize JPG {$jpegPortraitSource['path']}, {$jpegPortraitThumbs['path']}"); if (!empty($advancedCustom->useFFMPEGToGenerateThumbs)) { im_resizeV3($jpegPortraitSource['path'], $jpegPortraitThumbs['path'], $advancedCustom->thumbsWidthPortrait, $advancedCustom->thumbsHeightPortrait); } else { im_resizeV2($jpegPortraitSource['path'], $jpegPortraitThumbs['path'], $advancedCustom->thumbsWidthPortrait, $advancedCustom->thumbsHeightPortrait); } } // create thumbs if (!file_exists($jpegPortraitThumbsSmall['path']) && filesize($jpegPortraitSource['path']) > 1024) { _error_log("Resize JPG {$jpegPortraitSource['path']}, {$jpegPortraitThumbsSmall['path']}"); if (!empty($advancedCustom->useFFMPEGToGenerateThumbs)) { im_resizeV3($jpegPortraitSource['path'], $jpegPortraitThumbsSmall['path'], $advancedCustom->thumbsWidthPortrait, $advancedCustom->thumbsHeightPortrait); } else { im_resizeV2($jpegPortraitSource['path'], $jpegPortraitThumbsSmall['path'], $advancedCustom->thumbsWidthPortrait, $advancedCustom->thumbsHeightPortrait, 5); } } } else { if ($type == "article") { $obj->posterPortrait = "" . getCDN() . "view/img/article_portrait.png"; $obj->posterPortraitPath = "{$global['systemRootPath']}view/img/article_portrait.png"; $obj->posterPortraitThumbs = "" . getCDN() . "view/img/article_portrait.png"; $obj->posterPortraitThumbsSmall = "" . getCDN() . "view/img/article_portrait.png"; } elseif ($type == "pdf") { $obj->posterPortrait = "" . getCDN() . "view/img/pdf_portrait.png"; $obj->posterPortraitPath = "{$global['systemRootPath']}view/img/pdf_portrait.png"; $obj->posterPortraitThumbs = "" . getCDN() . "view/img/pdf_portrait.png"; $obj->posterPortraitThumbsSmall = "" . getCDN() . "view/img/pdf_portrait.png"; } /* else if ($type == "image") { $obj->posterPortrait = "".getCDN()."view/img/image_portrait.png"; $obj->posterPortraitPath = "{$global['systemRootPath']}view/img/image_portrait.png"; $obj->posterPortraitThumbs = "".getCDN()."view/img/image_portrait.png"; $obj->posterPortraitThumbsSmall = "".getCDN()."view/img/image_portrait.png"; } */ elseif ($type == "zip") { $obj->posterPortrait = "" . getCDN() . "view/img/zip_portrait.png"; $obj->posterPortraitPath = "{$global['systemRootPath']}view/img/zip_portrait.png"; $obj->posterPortraitThumbs = "" . getCDN() . "view/img/zip_portrait.png"; $obj->posterPortraitThumbsSmall = "" . getCDN() . "view/img/zip_portrait.png"; } else { $obj->posterPortrait = "" . getCDN() . "view/img/notfound_portrait.jpg"; $obj->posterPortraitPath = "{$global['systemRootPath']}view/img/notfound_portrait.png"; $obj->posterPortraitThumbs = "" . getCDN() . "view/img/notfound_portrait.jpg"; $obj->posterPortraitThumbsSmall = "" . getCDN() . "view/img/notfound_portrait.jpg"; } } if (file_exists($jpegSource['path'])) { $obj->poster = $jpegSource['url']; $obj->thumbsJpg = $thumbsSource['url']; // create thumbs if (!file_exists($thumbsSource['path']) && filesize($jpegSource['path']) > 1024) { _error_log("Resize JPG {$jpegSource['path']}, {$thumbsSource['path']}"); if (!empty($advancedCustom->useFFMPEGToGenerateThumbs)) { im_resizeV3($jpegSource['path'], $thumbsSource['path'], $advancedCustom->thumbsWidthLandscape, $advancedCustom->thumbsHeightLandscape); } else { im_resizeV2($jpegSource['path'], $thumbsSource['path'], $advancedCustom->thumbsWidthLandscape, $advancedCustom->thumbsHeightLandscape); } } // create thumbs if (!file_exists($thumbsSmallSource['path']) && filesize($jpegSource['path']) > 1024) { _error_log("Resize Small JPG {$jpegSource['path']}, {$thumbsSmallSource['path']}"); if (!empty($advancedCustom->useFFMPEGToGenerateThumbs)) { im_resizeV3($jpegSource['path'], $thumbsSmallSource['path'], $advancedCustom->thumbsWidthLandscape, $advancedCustom->thumbsHeightLandscape); } else { im_resizeV2($jpegSource['path'], $thumbsSmallSource['path'], $advancedCustom->thumbsWidthLandscape, $advancedCustom->thumbsHeightLandscape, 5); } } } else { if ($type == "article") { $obj->poster = "" . getCDN() . "view/img/article.png"; $obj->thumbsJpg = "" . getCDN() . "view/img/article.png"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/article.png"; } elseif ($type == "pdf") { $obj->poster = "" . getCDN() . "view/img/pdf.png"; $obj->thumbsJpg = "" . getCDN() . "view/img/pdf.png"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/pdf.png"; } elseif ($type == "image") { $obj->poster = "" . getCDN() . "view/img/image.png"; $obj->thumbsJpg = "" . getCDN() . "view/img/image.png"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/image.png"; } elseif ($type == "zip") { $obj->poster = "" . getCDN() . "view/img/zip.png"; $obj->thumbsJpg = "" . getCDN() . "view/img/zip.png"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/zip.png"; } elseif (($type !== "audio") && ($type !== "linkAudio")) { if (file_exists($spectrumSource['path'])) { $obj->poster = $spectrumSource['url']; $obj->thumbsJpg = $spectrumSource['url']; $obj->thumbsJpgSmall = $spectrumSource['url']; } else { $obj->poster = "" . getCDN() . "view/img/notfound.jpg"; $obj->thumbsJpg = "" . getCDN() . "view/img/notfoundThumbs.jpg"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/notfoundThumbsSmall.jpg"; } } else { $obj->poster = "" . getCDN() . "view/img/audio_wave.jpg"; $obj->thumbsJpg = "" . getCDN() . "view/img/audio_waveThumbs.jpg"; $obj->thumbsJpgSmall = "" . getCDN() . "view/img/audio_waveThumbsSmall.jpg"; } } if (empty($obj->thumbsJpg)) { $obj->thumbsJpg = $obj->poster; } if (empty($obj->thumbsJpgSmall)) { $obj->thumbsJpgSmall = $obj->poster; } //ObjectYPT::setCache($name, $obj); if (!empty($advancedCustom->disableAnimatedGif)) { $obj->thumbsGif = false; } ObjectYPT::setCache($cacheFileName, $obj); $_getImageFromFilename_[$cacheFileName] = $obj; } return $obj; } public static function getImageFromFilenameAsync($filename, $type = "video") { global $global, $advancedCustom; $return = array(); $path = getCacheDir() . "getImageFromFilenameAsync/"; make_path($path); $cacheFileName = "{$path}_{$filename}_{$type}"; if (!file_exists($cacheFileName)) { if (file_exists($cacheFileName . ".lock")) { return array(); } file_put_contents($cacheFileName . ".lock", 1); $total = static::getImageFromFilename_($filename, $type); file_put_contents($cacheFileName, json_encode($total)); unlink($cacheFileName . ".lock"); return $total; } $return = _json_decode(file_get_contents($cacheFileName)); if (time() - filemtime($cacheFileName) > cacheExpirationTime()) { // file older than 1 min $command = ("php '{$global['systemRootPath']}objects/getImageFromFilenameAsync.php' '$filename' '$type' '{$cacheFileName}'"); //_error_log("getImageFromFilenameAsync: {$command}"); exec($command . " > /dev/null 2>/dev/null &"); } return $return; } public static function getImageFromID($videos_id, $type = "video") { $video = new Video("", "", $videos_id); return self::getImageFromFilename($video->getFilename()); } public function getViews_count() { return intval($this->views_count); } public static function get_clean_title($videos_id) { global $global; $sql = "SELECT * FROM videos WHERE id = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "i", array($videos_id)); $videoRow = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res != false) { if ($videoRow != false) { return $videoRow['clean_title']; } } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return false; } public static function get_id_from_clean_title($clean_title) { global $global; $sql = "SELECT * FROM videos WHERE clean_title = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "s", array($clean_title)); $videoRow = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res != false) { if ($videoRow != false) { return $videoRow['id']; } } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return false; } public function getChannelName() { return User::_getChannelName($this->getUsers_id()); } public function getChannelLink() { return User::getChannelLink($this->getUsers_id()); } /** * * @global type $global * @param type $videos_id * @param type $clean_title * @param type $embed * @param type $type URLFriendly or permalink * @return String a web link */ public static function getLinkToVideo($videos_id, $clean_title = "", $embed = false, $type = "URLFriendly", $get = array()) { if (!empty($_GET['evideo'])) { $v = self::decodeEvideo(); if (!empty($v['video']['videoLink'])) { if ($embed) { return parseVideos($v['video']['videoLink']); } else { return $v['video']['videoLink']; } } } global $global, $advancedCustomUser, $advancedCustom; if (!is_object($advancedCustomUser)) { $advancedCustomUser = AVideoPlugin::getDataObject('CustomizeUser'); } if (empty($videos_id) && !empty($clean_title)) { $videos_id = self::get_id_from_clean_title($clean_title); } $video = new Video("", "", $videos_id); if ($advancedCustomUser->addChannelNameOnLinks) { $get['channelName'] = $video->getChannelName(); } unset($get['v'], $get['videoName'], $get['videoName'], $get['isMediaPlaySite'], $get['parentsOnly']); $get_http = http_build_query($get); if (empty($get_http)) { $get_http = ""; } else { $get_http = "?{$get_http}"; } if ($type == "URLFriendly") { $cat = ""; if (!empty($_GET['catName'])) { $cat = "cat/{$_GET['catName']}/"; } if (empty($clean_title)) { $clean_title = $video->getClean_title(); } $clean_title = urlencode($clean_title); $subDir = "video"; $subEmbedDir = "videoEmbed"; if ($video->getType() == 'article') { $subDir = "article"; $subEmbedDir = "articleEmbed"; } if (!empty($advancedCustom->makeVideosIDHarderToGuess)) { $encryptedVideos_id = '.' . idToHash($videos_id); $videos_id = $encryptedVideos_id; } if ($embed) { if (empty($advancedCustom->useVideoIDOnSEOLinks)) { return "{$global['webSiteRootURL']}{$subEmbedDir}/{$clean_title}{$get_http}"; } else { return "{$global['webSiteRootURL']}{$subEmbedDir}/{$videos_id}/{$clean_title}{$get_http}"; } } else { if (empty($advancedCustom->useVideoIDOnSEOLinks)) { return "{$global['webSiteRootURL']}{$cat}{$subDir}/{$clean_title}{$get_http}"; } else { return "{$global['webSiteRootURL']}{$subDir}/{$videos_id}/{$clean_title}{$get_http}"; } } } else { if (!empty($advancedCustom->makeVideosIDHarderToGuess)) { $encryptedVideos_id = '.' . idToHash($videos_id); $videos_id = $encryptedVideos_id; } if ($embed) { return "{$global['webSiteRootURL']}vEmbed/{$videos_id}{$get_http}"; } else { return "{$global['webSiteRootURL']}v/{$videos_id}{$get_http}"; } } } public static function getPermaLink($videos_id, $embed = false, $get = array()) { return self::getLinkToVideo($videos_id, "", $embed, "permalink", $get); } public static function getURLFriendly($videos_id, $embed = false, $get = array()) { return self::getLinkToVideo($videos_id, "", $embed, "URLFriendly", $get); } public static function getPermaLinkFromCleanTitle($clean_title, $embed = false, $get = array()) { return self::getLinkToVideo("", $clean_title, $embed, "permalink", $get); } public static function getURLFriendlyFromCleanTitle($clean_title, $embed = false, $get = array()) { return self::getLinkToVideo("", $clean_title, $embed, "URLFriendly", $get); } public static function getLink($videos_id, $clean_title, $embed = false, $get = array()) { global $advancedCustom; if (!empty($advancedCustom->usePermalinks)) { $type = "permalink"; } else { $type = "URLFriendly"; } return self::getLinkToVideo($videos_id, $clean_title, $embed, $type, $get); } public static function getTotalVideosThumbsUpFromUser($users_id, $startDate, $endDate) { global $global; $sql = "SELECT id from videos WHERE users_id = ? "; $res = sqlDAL::readSql($sql, "i", array($users_id)); $videoRows = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $r = array('thumbsUp' => 0, 'thumbsDown' => 0); if ($res != false) { foreach ($videoRows as $row) { $values = array($row['id']); $format = "i"; $sql = "SELECT id from likes WHERE videos_id = ? AND `like` = 1 "; if (!empty($startDate)) { $sql .= " AND `created` >= ? "; $format .= "s"; $values[] = $startDate; } if (!empty($endDate)) { $sql .= " AND `created` <= ? "; $format .= "s"; $values[] = $endDate; } $res = sqlDAL::readSql($sql, $format, $values); $countRow = sqlDAL::num_rows($res); sqlDAL::close($res); $r['thumbsUp'] += $countRow; $format = ""; $values = array(); $sql = "SELECT id from likes WHERE videos_id = {$row['id']} AND `like` = -1 "; if (!empty($startDate)) { $sql .= " AND `created` >= ? "; $format .= "s"; $values[] = $startDate; } if (!empty($endDate)) { $sql .= " AND `created` <= ? "; $format .= "s"; $values[] = $endDate; } $res = sqlDAL::readSql($sql, $format, $values); $countRow = sqlDAL::num_rows($res); sqlDAL::close($res); $r['thumbsDown'] += $countRow; } } return $r; } public static function deleteThumbs($filename, $doNotDeleteSprit = false) { if (empty($filename)) { return false; } global $global; $filePath = Video::getPathToFile($filename); // Streamlined for less coding space. $files = glob("{$filePath}*_thumbs*.jpg"); foreach ($files as $file) { if (file_exists($file)) { if ($doNotDeleteSprit && strpos($file, '_thumbsSprit.jpg') !== false) { continue; } @unlink($file); } } ObjectYPT::deleteCache($filename); ObjectYPT::deleteCache($filename . "article"); ObjectYPT::deleteCache($filename . "pdf"); ObjectYPT::deleteCache($filename . "video"); Video::clearImageCache($filename); Video::clearImageCache($filename, "article"); Video::clearImageCache($filename, "pdf"); Video::clearImageCache($filename, "audio"); clearVideosURL($filename); return true; } public static function deleteGifAndWebp($filename) { if (empty($filename)) { return false; } global $global; $filePath = Video::getPathToFile($filename); @unlink("{$filePath}.gif"); @unlink("{$filePath}.webp"); ObjectYPT::deleteCache($filename); ObjectYPT::deleteCache($filename . "article"); ObjectYPT::deleteCache($filename . "pdf"); ObjectYPT::deleteCache($filename . "video"); Video::clearImageCache($filename); Video::clearImageCache($filename, "article"); Video::clearImageCache($filename, "pdf"); Video::clearImageCache($filename, "audio"); clearVideosURL($filename); return true; } public static function clearCache($videos_id) { _error_log("Video:clearCache($videos_id)"); $video = new Video("", "", $videos_id); $filename = $video->getFilename(); if (empty($filename)) { _error_log("Video:clearCache filename not found"); return false; } self::deleteThumbs($filename, true); ObjectYPT::deleteCache("otherInfo{$videos_id}"); ObjectYPT::deleteCache($filename); ObjectYPT::deleteCache("getVideosURL_V2$filename"); ObjectYPT::deleteCache($filename . "article"); ObjectYPT::deleteCache($filename . "pdf"); ObjectYPT::deleteCache($filename . "video"); ObjectYPT::deleteCache(md5($filename . ".m3u8")); ObjectYPT::deleteCache(md5($filename . ".mp4")); ObjectYPT::deleteCache(md5($filename . ".m3u81")); ObjectYPT::deleteCache(md5($filename . ".mp41")); ObjectYPT::deleteCache("getSourceFile($filename)1"); ObjectYPT::deleteCache("getSourceFile($filename)0"); Video::clearImageCache($filename); Video::clearImageCache($filename, "article"); Video::clearImageCache($filename, "pdf"); Video::clearImageCache($filename, "audio"); Video::deleteTagsAsync($videos_id); clearVideosURL($filename); AVideoPlugin::deleteVideoTags($videos_id); ObjectYPT::setLastDeleteALLCacheTime(); return true; } public static function clearCacheFromFilename($fileName) { if ($fileName == '.zip') { return false; } _error_log("Video:clearCacheFromFilename($fileName)"); $video = self::getVideoFromFileNameLight($fileName); if (empty($video['id'])) { return false; } return self::clearCache($video['id']); } public static function getVideoPogress($videos_id, $users_id = 0) { if (empty($users_id)) { if (!User::isLogged()) { return 0; } $users_id = User::getId(); } return VideoStatistic::getLastVideoTimeFromVideo($videos_id, $users_id); } public static function getLastVideoTimePosition($videos_id, $users_id = 0) { return self::getVideoPogress($videos_id, $users_id); } public static function getVideoPogressPercent($videos_id, $users_id = 0) { $lastVideoTime = self::getVideoPogress($videos_id, $users_id); if (empty($lastVideoTime)) { return array('percent' => 0, 'lastVideoTime' => 0); } // start incremental search and save $sql = "SELECT duration FROM `videos` WHERE id = ? LIMIT 1"; $res = sqlDAL::readSql($sql, "i", array($videos_id)); $row = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if (empty($row) || empty($row['duration'])) { return array('percent' => 0, 'lastVideoTime' => 0); } $duration = parseDurationToSeconds($row['duration']); if (empty($duration)) { return array('percent' => 0, 'lastVideoTime' => 0); } if ($lastVideoTime > $duration) { return array('percent' => 100, 'lastVideoTime' => $lastVideoTime); } return array('percent' => ($lastVideoTime / $duration) * 100, 'lastVideoTime' => $lastVideoTime); } public function getRrating() { return $this->rrating; } public function setRrating($rrating) { $rrating = strtolower($rrating); if (!in_array($rrating, self::$rratingOptions)) { $rrating = ''; } AVideoPlugin::onVideoSetRrating($this->id, $this->rrating, $rrating); $this->rrating = $rrating; } public static function getVideoType($filename) { global $_getVideoType; if (!isset($_getVideoType)) { $_getVideoType = array(); } if (isset($_getVideoType[$filename])) { return $_getVideoType[$filename]; } $obj = new stdClass(); $paths = self::getVideosPaths($filename); $obj->mp4 = !empty($paths['mp4']) ? true : false; $obj->webm = !empty($paths['webm']) ? true : false; $obj->m3u8 = !empty($paths['m3u8']) ? true : false; $obj->pdf = !empty($paths['pdf']) ? true : false; $obj->mp3 = !empty($paths['mp3']) ? true : false; $_getVideoType[$filename] = $obj; return $obj; } public static function getVideoTypeLabels($filename) { $obj = self::getVideoType($filename); $labels = ""; if (empty($obj->mp4) && empty($obj->webm) && empty($obj->m3u8) && empty($obj->pdf) && empty($obj->mp3)) { return 'Other'; } if ($obj->mp4) { $labels .= 'MP4'; } if ($obj->webm) { $labels .= 'Webm'; } if ($obj->m3u8) { $labels .= 'HLS'; } if ($obj->pdf) { $labels .= 'PDF'; } if ($obj->mp3) { $labels .= 'MP3'; } return $labels; } /** * Based on Roku Type * @param type $filename * @return string */ public static function getVideoTypeText($filename) { $obj = self::getVideoType($filename); $labels = ""; if (empty($obj->mp4) && empty($obj->webm) && empty($obj->m3u8) && empty($obj->pdf) && empty($obj->mp3)) { return __('Other'); } if ($obj->mp4) { return 'MP4'; } if ($obj->webm) { return 'WEBM'; } if ($obj->m3u8) { return 'HLS'; } if ($obj->pdf) { return 'PDF'; } if ($obj->mp3) { return 'MP3'; } return $labels; } public static function isPublic($videos_id) { // check if the video is not public $rows = UserGroups::getVideoGroups($videos_id); if (empty($rows)) { return true; } return false; } public static function userGroupAndVideoGroupMatch($users_id, $videos_id) { if (empty($videos_id)) { return false; } $ppv = AVideoPlugin::loadPluginIfEnabled("PayPerView"); if ($ppv) { $ppv->userCanWatchVideo($users_id, $videos_id); } // check if the video is not public $rows = UserGroups::getVideoGroups($videos_id); if (empty($rows)) { return true; } if (empty($users_id)) { return false; } $rowsUser = UserGroups::getUserGroups(User::getId()); if (empty($rowsUser)) { return false; } foreach ($rows as $value) { foreach ($rowsUser as $value2) { if ($value['id'] === $value2['id']) { return true; } } } return false; } public function getExternalOptions() { return $this->externalOptions; } public function setExternalOptions($externalOptions) { AVideoPlugin::onVideoSetExternalOptions($this->id, $this->externalOptions, $externalOptions); $this->externalOptions = $externalOptions; } public function setVideoStartSeconds($videoStartSeconds) { $externalOptions = _json_decode($this->getExternalOptions()); AVideoPlugin::onVideoSetVideoStartSeconds($this->id, $this->videoStartSeconds, $videoStartSeconds); $externalOptions->videoStartSeconds = intval($videoStartSeconds); $this->setExternalOptions(json_encode($externalOptions)); } public function setVideoEmbedWhitelist($embedWhitelist) { $externalOptions = _json_decode($this->getExternalOptions()); $externalOptions->embedWhitelist = $embedWhitelist; $this->setExternalOptions(json_encode($externalOptions)); } public function getVideoEmbedWhitelist() { $externalOptions = _json_decode($this->getExternalOptions()); if (empty($externalOptions->embedWhitelist)) { return ''; } return $externalOptions->embedWhitelist; } static public function getEmbedWhitelist($videos_id) { $v = new Video('', '', $videos_id); return $v->getVideoEmbedWhitelist(); } public function getSerie_playlists_id() { return $this->serie_playlists_id; } public function setSerie_playlists_id($serie_playlists_id) { AVideoPlugin::onVideoSetSerie_playlists_id($this->id, $this->serie_playlists_id, $serie_playlists_id); $this->serie_playlists_id = $serie_playlists_id; } public static function getVideoFromSeriePlayListsId($serie_playlists_id) { global $global, $config; $serie_playlists_id = intval($serie_playlists_id); $sql = "SELECT * FROM videos WHERE serie_playlists_id = '$serie_playlists_id' LIMIT 1"; $res = sqlDAL::readSql($sql, "", array(), true); $video = sqlDAL::fetchAssoc($res); sqlDAL::close($res); return $video; } /** * if will show likes, comments, share, etc * @return boolean */ public static function showYoutubeModeOptions() { global $video; if (!empty($_GET['evideo'])) { $v = self::decodeEvideo(); if (empty($v['video']['views_count'])) { return false; } else { return true; } } if (empty($video) || $video['type'] === 'notfound') { return false; } return true; } public static function decodeEvideo() { $evideo = false; if (!empty($_GET['evideo'])) { $evideo = _json_decode(decryptString($_GET['evideo'])); } $video = array(); if (!empty($evideo)) { $video['id'] = 0; $video['type'] = 'embed'; $video['rotation'] = 0; $video['videoLink'] = $evideo->videoLink; $video['title'] = $evideo->title; $video['clean_title'] = preg_replace('/[!#$&\'()*+,\\/:;=?@[\\] ]+/', '-', trim(strtolower(cleanString($evideo->title)))); if (empty($evideo->description) && !empty($evideo->videos_id)) { $divId = uniqid(); $video['description'] = '
'; } else { $video['description'] = @$evideo->description; } $video['duration'] = @$evideo->duration; $video['creator'] = @$evideo->creator; $video['likes'] = ""; $video['dislikes'] = ""; $video['category'] = "embed"; $video['views_count'] = intval(@$evideo->views_count); } return array('evideo' => $evideo, 'video' => $video); } private static function getBlockedUsersIdsArray($users_id = 0) { if (empty($users_id)) { $users_id = intval(User::getId()); } if (empty($users_id)) { return array(); } if (!User::isLogged()) { return array(); } $report = AVideoPlugin::getDataObjectIfEnabled("ReportVideo"); if (empty($report)) { return array(); } return ReportVideo::getAllReportedUsersIdFromUser($users_id); } public static function getIncludeType($video) { $vType = $video['type']; if ($vType == 'linkVideo') { if (!preg_match('/m3u8/', $video['videoLink'])) { $vType = isHTMLPage($video['videoLink']) ? 'embed' : 'video'; } else { $vType = 'video'; } } elseif ($vType == 'live') { $vType = '../../plugin/Live/view/liveVideo'; } elseif ($vType == 'linkAudio') { $vType = 'audio'; } if (!in_array($vType, Video::$typeOptions)) { $vType = 'video'; } return $vType; } private static function getFullTextSearch($columnsArray, $search, $connection = "OR") { global $global; $search = $global['mysqli']->real_escape_string(xss_esc($search)); if (empty($columnsArray) || empty($search)) { return ""; } $sql = "("; $matches = array(); foreach ($columnsArray as $value) { $matches[] = " (MATCH({$value}) AGAINST ('{$search}' IN NATURAL LANGUAGE MODE)) "; } $sql .= implode(" OR ", $matches); $sql .= ")"; return "{$connection} {$sql}"; } public static function getChangeVideoStatusButton($videos_id) { $video = new Video('', '', $videos_id); $status = $video->getStatus(); $activeBtn = ''; $inactiveBtn = ''; $unlistedBtn = ''; return "{$activeBtn}{$inactiveBtn}{$unlistedBtn}"; } static function canVideoBePurchased($videos_id) { global $global; $obj = new stdClass(); $obj->plugin = ''; $obj->buyURL = ''; $obj->canVideoBePurchased = false; // check for Subscription plugin if (AVideoPlugin::isEnabledByName('Subscription')) { $sub = new Subscription(); $plans = $sub->getPlansFromVideo($videos_id); if (!empty($plans)) { $obj->plugin = 'Subscription'; $obj->buyURL = "{$global['webSiteRootURL']}plugin/Subscription/showPlans.php?videos_id={$videos_id}"; $obj->canVideoBePurchased = true; return $obj; } } // check for PPV plugin if (AVideoPlugin::isEnabledByName('PayPerView')) { if (PayPerView::isVideoPayPerView($videos_id) || $obj->onlyPlayVideosWithPayPerViewActive) { $url = "{$global['webSiteRootURL']}plugin/PayPerView/page/buy.php"; if (isSerie()) { $redirectUri = getSelfURI(); } else { $redirectUri = getRedirectToVideo($videos_id); } if (!empty($redirectUri)) { $url = addQueryStringParameter($url, 'redirectUri', $redirectUri); } $url = addQueryStringParameter($url, 'videos_id', $videos_id); $obj->plugin = 'PayPerView'; $obj->buyURL = $url; $obj->canVideoBePurchased = true; return $obj; } } // check for fansSubscription if (AVideoPlugin::isEnabledByName('FansSubscriptions')) { if (FansSubscriptions::hasPlansFromVideosID($videos_id)) { $url = "{$global['webSiteRootURL']}plugin/FansSubscriptions/View/buy.php"; if (isSerie()) { $redirectUri = getSelfURI(); } else { $redirectUri = getRedirectToVideo($videos_id); } if (!empty($redirectUri)) { $url = addQueryStringParameter($url, 'redirectUri', $redirectUri); } $url = addQueryStringParameter($url, 'videos_id', $videos_id); $obj->plugin = 'FansSubscriptions'; $obj->buyURL = $url; $obj->canVideoBePurchased = true; return $obj; } } return false; } static function getCreatorHTML($users_id, $html = '', $small=false) { global $global; if($small){ $template = $global['systemRootPath'] . 'view/videoCreatorSmall.html'; }else{ $template = $global['systemRootPath'] . 'view/videoCreator.html'; } $content = local_get_contents($template); $name = User::getNameIdentificationById($users_id); $search = array( '{photo}', '{channelLink}', '{name}', '{icon}', '{subscriptionButton}', '{html}'); $replace = array( User::getPhoto($users_id), User::getChannelLink($users_id), strip_tags($name), User::getEmailVerifiedIcon($users_id), Subscribe::getButton($users_id), $html ); $btnHTML = str_replace($search, $replace, $content); return $btnHTML; } static function getVideosListItem($videos_id, $divID='', $style='') { global $global, $advancedCustom; $get = array(); $get = array('channelName' => @$_GET['channelName'], 'catName' => @$_GET['catName']); if(empty($divID)){ $divID = "divVideo-{$videos_id}"; } $objGallery = AVideoPlugin::getObjectData("Gallery"); $program = AVideoPlugin::loadPluginIfEnabled('PlayLists'); $template = $global['systemRootPath'] . 'view/videosListItem.html'; $templateContent = file_get_contents($template); $value = Video::getVideoLight($videos_id); $link = Video::getLink($value['id'], $value['clean_title'], "", $get); if (!empty($_GET['page']) && $_GET['page'] > 1) { $link = addQueryStringParameter($link, 'page', $_GET['page']); } $title = $value['title']; $images = Video::getImageFromFilename($value['filename'], $value['type']); if (!is_object($images)) { $images = new stdClass(); $images->thumbsGif = ""; $images->poster = getCDN() . "view/img/notfound.jpg"; $images->thumbsJpg = getCDN() . "view/img/notfoundThumbs.jpg"; $images->thumbsJpgSmall = getCDN() . "view/img/notfoundThumbsSmall.jpg"; } $imgJPGLow = $images->thumbsJpgSmall; $imgJPGHight = $images->thumbsJpg; $imgGif = $images->thumbsGif; $imgGifHTML = ''; if (!empty($images->posterPortrait) && basename($images->posterPortrait) !== 'notfound_portrait.jpg' && basename($images->posterPortrait) !== 'pdf_portrait.png' && basename($images->posterPortrait) !== 'article_portrait.png') { $imgGif = $images->gifPortrait; $imgJPGHight = $images->posterPortrait; } if (!empty($imgGif)) { $imgGifHTML = ''; } $timeHTML = ''; if (isToShowDuration($value['type'])) { $timeHTML = ''; } $loggedUserHTML = ''; if (User::isLogged() && !empty($program)) { $value['favoriteId'] = self::getFavoriteIdFromUser(User::getId()); $value['watchLaterId'] = self::getWatchLaterIdFromUser(User::getId()); if (!empty($value['isWatchLater'])) { $watchLaterBtnAddedStyle = ""; $watchLaterBtnStyle = "display: none;"; } else { $watchLaterBtnAddedStyle = "display: none;"; $watchLaterBtnStyle = ""; } if (!empty($value['isFavorite'])) { $favoriteBtnAddedStyle = ""; $favoriteBtnStyle = "display: none;"; } else { $favoriteBtnAddedStyle = "display: none;"; $favoriteBtnStyle = ""; } $loggedUserHTML = '
'; $loggedUserHTML .= ' '; $loggedUserHTML .= ''; $loggedUserHTML .= '
'; $loggedUserHTML .= ' '; $loggedUserHTML .= ' '; $loggedUserHTML .= '
'; } $progress = self::getVideoPogressPercent($value['id']);; $category = new Category($value['categories_id']); $categoryLink = $category->getLink(); $categoryIcon = $category->getIconClass(); $category = $category->getName(); $tagsHTML = ''; $tagsWhitelist = array(__("Paid Content"), __("Group"), __("Plugin")); if (!empty($objGallery->showTags) && !empty($value['tags']) && is_array($value['tags'])) { foreach ($value['tags'] as $value2) { if (!empty($value2->label) && in_array($value2->label, $tagsWhitelist)) { $tagsHTML .= '' . $value2->text . ''; } } } $viewsHTML = ''; if (empty($advancedCustom->doNotDisplayViews)) { if (AVideoPlugin::isEnabledByName('LiveUsers')) { $viewsHTML = '
' . getLiveUsersLabelVideo($value['id'], $value['views_count']) . '
'; } else { $viewsHTML = '
' . number_format($value['views_count'], 0) . '
'; } } $creator = self::getCreatorHTML($value['users_id'], '', true); $search = array( '{style}', '{divID}', '{link}', '{title}', '{imgJPGLow}', '{imgJPGHight}', '{imgGifHTML}', '{timeHTML}', '{loggedUserHTML}', '{progress}', '{categoryLink}', '{categoryIcon}', '{category}', '{tagsHTML}', '{viewsHTML}', '{creator}'); $replace = array( $style, $divID, $link, $title, $imgJPGLow, $imgJPGHight, $imgGifHTML, $timeHTML, $loggedUserHTML, $progress, $categoryLink, $categoryIcon, $category, $tagsHTML, $viewsHTML, $creator ); $btnHTML = str_replace( $search, $replace, $templateContent); return $btnHTML; } function getTotal_seconds_watching() { return $this->total_seconds_watching; } function setTotal_seconds_watching($total_seconds_watching) { $this->total_seconds_watching = $total_seconds_watching; } } } // just to convert permalink into clean_title if (!empty($_GET['v']) && empty($_GET['videoName'])) { $_GET['videoName'] = Video::get_clean_title($_GET['v']); } diff --git a/plugin/Live/Live.php b/plugin/Live/Live.php index 502a02150..cae89aab5 100644 --- a/plugin/Live/Live.php +++ b/plugin/Live/Live.php @@ -1,2524 +1,2532 @@ and receive HLS streaming from servers"; $lu = AVideoPlugin::loadPlugin("LiveUsers"); if (!empty($lu)) { if (version_compare($lu->getPluginVersion(), "2.0") < 0) { $desc .= "
You MUST update your LiveUsers plugin to version 2.0 or greater
"; } } return $desc; } public function getName() { return "Live"; } public function getHTMLMenuRight() { global $global; $buttonTitle = $this->getButtonTitle(); $obj = $this->getDataObject(); if (!empty($obj->hideTopButton)) { return ''; } include $global['systemRootPath'] . 'plugin/Live/view/menuRight.php'; } public function getUUID() { return "e06b161c-cbd0-4c1d-a484-71018efa2f35"; } public function getPluginVersion() { return "7.2"; } public function updateScript() { global $global; //update version 2.0 $sql = "SELECT 1 FROM live_transmitions_history LIMIT 1"; $res = sqlDAL::readSql($sql); $fetch = sqlDAL::fetchAssoc($res); if (!$fetch) { sqlDal::writeSql(file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV2.0.sql')); } //update version 3.0 $sql = "SELECT 1 FROM live_transmition_history_log LIMIT 1"; $res = sqlDAL::readSql($sql); $fetch = sqlDAL::fetchAssoc($res); if (!$fetch) { sqlDal::writeSql(file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV3.0.sql')); } //update version 4.0 $sql = "SELECT 1 FROM live_servers LIMIT 1"; $res = sqlDAL::readSql($sql); $fetch = sqlDAL::fetchAssoc($res); if (!$fetch) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV4.0.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } //update version 5.0 $sql = "SELECT 1 FROM live_restreams LIMIT 1"; $res = sqlDAL::readSql($sql); $fetch = sqlDAL::fetchAssoc($res); if (!$fetch) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV5.0.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } //update version 5.1 if (AVideoPlugin::compareVersion($this->getName(), "5.1") < 0) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV5.1.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } //update version 5.2 if (AVideoPlugin::compareVersion($this->getName(), "5.2") < 0) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV5.2.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } if (AVideoPlugin::compareVersion($this->getName(), "6.0") < 0) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV6.0.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } if (AVideoPlugin::compareVersion($this->getName(), "7.0") < 0) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV7.0.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } if (AVideoPlugin::compareVersion($this->getName(), "7.2") < 0) { $sqls = file_get_contents($global['systemRootPath'] . 'plugin/Live/install/updateV7.2.sql'); $sqlParts = explode(";", $sqls); foreach ($sqlParts as $value) { sqlDal::writeSql(trim($value)); } } return true; } public function getEmptyDataObject() { global $global; $server = parse_url($global['webSiteRootURL']); $scheme = "http"; $port = "8080"; if (strtolower($server["scheme"]) == "https") { $scheme = "https"; $port = "8443"; } $obj = new stdClass(); $obj->button_title = "LIVE"; self::addDataObjectHelper('button_title', 'Button Title', 'This is the title that will appear in your button to enter in the Live panel'); $obj->server = "rtmp://{$server['host']}/live"; self::addDataObjectHelper('server', 'RTMP Server URL', 'Usually it is ' . "rtmp://{$server['host']}/live"); $obj->playerServer = "{$scheme}://{$server['host']}:{$port}/live"; self::addDataObjectHelper('playerServer', 'Player URL', 'This is a URL to your NGINX server, this URL will be used by the HTML5 player, If your site is HTTPS your player URL MUST be HTTPS as well, usually it is ' . "{$scheme}://{$server['host']}:{$port}/live"); $obj->stats = "{$scheme}://{$server['host']}:{$port}/stat"; self::addDataObjectHelper('stats', 'Stats Page URL', 'When you installed the NGINX you also install the stat.xsl, we will use it to grab the information when you have livestreams running, usually it is ' . "{$scheme}://{$server['host']}:{$port}/stat"); $obj->restreamerURL = "{$global['webSiteRootURL']}plugin/Live/standAloneFiles/restreamer.json.php"; self::addDataObjectHelper('restreamerURL', 'Restreamer URL', 'https://github.com/WWBN/AVideo/wiki/Restream'); $obj->controlURL = "{$global['webSiteRootURL']}plugin/Live/standAloneFiles/control.json.php"; self::addDataObjectHelper('controlURL', 'Control URL'); $obj->controlServer = "http://localhost:8080/"; self::addDataObjectHelper('controlServer', 'Control Server'); $obj->disableRestream = false; self::addDataObjectHelper('disableRestream', 'Disable Restream', 'If you check this, we will not send requests to your Restreamer URL'); $obj->disableDVR = false; self::addDataObjectHelper('disableDVR', 'Disable DVR', 'Enable or disable the DVR Feature, you can control the DVR length in your nginx.conf on the parameter hls_playlist_length'); $obj->disableGifThumbs = false; self::addDataObjectHelper('disableGifThumbs', 'Disable Gif Thumbs', 'This option will disable the Animated Gif render, it will save some hardware capacity from your encoder and may speedup your page'); $obj->disableLiveThumbs = false; self::addDataObjectHelper('disableLiveThumbs', 'Disable Live thumbnails', 'This option will disable the çive image extraction and will use the user static image, it will save some hardware capacity from your encoder and may speedup your page'); $obj->hideTopButton = false; self::addDataObjectHelper('hideTopButton', 'Hide Top Button', 'This will hide the "Go Live" button on the top menu bar'); $obj->useAadaptiveMode = false; self::addDataObjectHelper('useAadaptiveMode', 'Adaptive mode', 'https://github.com/WWBN/AVideo/wiki/Adaptive-Bitrates-on-Livestream'); $obj->protectLive = false; self::addDataObjectHelper('protectLive', 'Live Protection', 'With this your encryption key will be protected, and only your site player will be able to play your videos, download tools will not be able to download your video. if you want to share your live externally you can use the embed and you will still be protected. but if you want to use the m3u8 file you must disable this'); $obj->experimentalWebcam = false; self::addDataObjectHelper('experimentalWebcam', 'Experimental Webcam', 'Requires flash and it is deprecated, will be removed. not recommend to enable it.'); $obj->doNotShowLiveOnVideosList = false; self::addDataObjectHelper('doNotShowLiveOnVideosList', 'Do not show live on videos list', 'We will not show the live thumbs on the main Gallery page'); $obj->doNotShowOnlineOfflineLabel = false; self::addDataObjectHelper('doNotShowOnlineOfflineLabel', 'Hide the Online/Offline Badge on live streams'); $obj->doNotShowLiveOnCategoryList = false; self::addDataObjectHelper('doNotShowLiveOnCategoryList', 'Do not show live on site category list', 'We will not show the live thumbs on the main Gallery page'); $obj->doNotShowOfflineLiveOnCategoryList = false; self::addDataObjectHelper('doNotShowOfflineLiveOnCategoryList', 'Do not show offline lives on site category list', 'We will not show the live thumbs on the main Gallery page if it is offline'); $obj->limitLiveOnVideosList = 12; self::addDataObjectHelper('limitLiveOnVideosList', 'Videos List Limit', 'This will limit the maximum of videos that you will see in the Videos page'); $obj->doNotShowGoLiveButton = false; self::addDataObjectHelper('doNotShowGoLiveButton', 'Hide Top Go live Button', 'This will hide the "Go Live" button on the top menu bar'); $obj->doNotProcessNotifications = false; self::addDataObjectHelper('doNotProcessNotifications', 'Do not show notifications', 'Do not show the notification on the top bar'); $obj->useLiveServers = false; self::addDataObjectHelper('useLiveServers', 'Use Live Servers', 'Check this if you will use External Live Servers https://github.com/WWBN/AVideo/wiki/Live-Plugin#livestream-server-balance '); $obj->disableMeetCamera = false; self::addDataObjectHelper('disableMeetCamera', 'Disable Meet camera', 'This requires out Meet Server, with the Meet camera you can use your PC webcam directly in the webpage or mobile to make livestreams'); $obj->playLiveInFullScreen = false; self::addDataObjectHelper('playLiveInFullScreen', 'Play Livestream in Full Screen'); $obj->playLiveInFullScreenOnIframe = false; self::addDataObjectHelper('playLiveInFullScreenOnIframe', 'Play Livestream in Full Screen on IFrame'); $obj->hls_path = "/HLS/live"; self::addDataObjectHelper('hls_path', 'HLS Path URL', 'Used only when we stop a Live, we use this path to delete the files'); $obj->requestStatsTimout = 4; // if the server does not respond we stop wait self::addDataObjectHelper('requestStatsTimout', 'Stats Timout', 'If a remote server (stats page) does not respond we stop waiting after this timeout'); $obj->cacheStatsTimout = 15; // we will cache the result self::addDataObjectHelper('cacheStatsTimout', 'Stats Cache Timeout', 'we will cache the result, this will save some resources'); $obj->requestStatsInterval = 15; // how many seconds untill request the stats again self::addDataObjectHelper('requestStatsInterval', 'Stats Request Interval', 'how many seconds until request the stats again'); $obj->streamDeniedMsg = "You can not stream live videos"; self::addDataObjectHelper('streamDeniedMsg', 'Denied Message', 'We will show this message when a user is not allowed so watch a livestream'); $obj->allowMultipleLivesPerUser = true; self::addDataObjectHelper('allowMultipleLivesPerUser', 'Allow Multiple Lives Per User', 'Your users will be able to make unlimited livestreams'); $obj->controllButtonsShowOnlyToAdmin_record_start = false; self::addDataObjectHelper('controllButtonsShowOnlyToAdmin_record_start', 'Show Record Start Button Only to Admin', 'Regular users will not able to see this button'); $obj->controllButtonsShowOnlyToAdmin_record_stop = false; self::addDataObjectHelper('controllButtonsShowOnlyToAdmin_record_stop', 'Show Record Stop Button Only to Admin', 'Regular users will not able to see this button'); $obj->controllButtonsShowOnlyToAdmin_drop_publisher = false; self::addDataObjectHelper('controllButtonsShowOnlyToAdmin_drop_publisher', 'Show Drop Publisher Button Only to Admin', 'Regular users will not able to see this button'); $obj->controllButtonsShowOnlyToAdmin_drop_publisher_reset_key = false; self::addDataObjectHelper('controllButtonsShowOnlyToAdmin_drop_publisher_reset_key', 'Show Drop Publisher and Reset Key Button Only to Admin', 'Regular users will not able to see this button'); $obj->controllButtonsShowOnlyToAdmin_save_dvr = false; self::addDataObjectHelper('controllButtonsShowOnlyToAdmin_save_dvr', 'Show Save DVR Button Only to Admin', 'Regular users will not able to see this button'); $obj->webRTC_player = 'https://webrtc.ypt.me/player/'; return $obj; } public function getHeadCode() { global $global; $obj = $this->getDataObject(); // preload image $js = ""; $css = ''; if (!empty($obj->playLiveInFullScreen)) { if ((isLive() || isEmbed()) && canFullScreen()) { $css .= ''; $css .= ''; } $js .= ''; $css .= ''; } return $js . $css; } public function getFooterCode() { $obj = $this->getDataObject(); global $global; $js = ''; if (!empty($obj->playLiveInFullScreen)) { $js = ''; $js .= ''; } else if (!empty($obj->playLiveInFullScreenOnIframe)) { $js = ''; $js .= ''; } include $global['systemRootPath'] . 'plugin/Live/view/footer.php'; return $js; } public function getButtonTitle() { $o = $this->getDataObject(); return $o->button_title; } public function getKey() { $o = $this->getDataObject(); return $o->key; } static function getDestinationApplicationName() { $server = self::getPlayerServer(); $server = rtrim($server, "/"); $parts = explode("/", $server); $app = array_pop($parts); $domain = self::getControl(); //return "{$domain}/control/drop/publisher?app={$app}&name={$key}"; return "{$app}?p=" . User::getUserPass(); } static function getDestinationHost() { $server = self::getServer(); $host = parse_url($server, PHP_URL_HOST); return $host; } static function getDestinationPort() { $server = self::getServer(); $port = parse_url($server, PHP_URL_PORT); if (empty($port)) { $port = 1935; } return $port; } static function getServer($live_servers_id = -1) { $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj->useLiveServers)) { if ($live_servers_id < 0) { $live_servers_id = self::getCurrentLiveServersId(); } $ls = new Live_servers($live_servers_id); if (!empty($ls->getRtmp_server())) { return $ls->getRtmp_server(); } } return trim($obj->server); } static function getDropURL($key, $live_servers_id = 0) { $server = self::getPlayerServer(); $server = rtrim($server, "/"); $parts = explode("/", $server); $app = array_pop($parts); $domain = self::getControl($live_servers_id); //return "{$domain}/control/drop/publisher?app={$app}&name={$key}"; return "{$domain}?command=drop_publisher&app={$app}&name={$key}&token=" . getToken(60); } static function getIsRecording($key, $live_servers_id = 0) { $server = self::getPlayerServer(); $server = rtrim($server, "/"); $parts = explode("/", $server); $app = array_pop($parts); $domain = self::getControl($live_servers_id); //return "{$domain}/control/drop/publisher?app={$app}&name={$key}"; return "{$domain}?command=is_recording&app={$app}&name={$key}&token=" . getToken(60); } static function getStartRecordURL($key, $live_servers_id = 0) { $server = self::getPlayerServer(); $server = rtrim($server, "/"); $parts = explode("/", $server); $app = array_pop($parts); $domain = self::getControl($live_servers_id); //return "{$domain}/control/drop/publisher?app={$app}&name={$key}"; return "{$domain}?command=record_start&app={$app}&name={$key}&token=" . getToken(60); } static function getStopRecordURL($key, $live_servers_id = 0) { $server = self::getPlayerServer(); $server = rtrim($server, "/"); $parts = explode("/", $server); $app = array_pop($parts); $domain = self::getControl($live_servers_id); return "{$domain}?command=record_stop&app={$app}&name={$key}&token=" . getToken(60); } static function controlRecording($key, $live_servers_id, $start = true, $try = 0) { if ($start) { $url = self::getStartRecordURL($key, $live_servers_id); } else { $url = self::getStopRecordURL($key, $live_servers_id); } $response = url_get_contents($url, '', 5); _error_log("Live:controlRecording {$url} {$live_servers_id} - [{$response}]"); $obj = new stdClass(); $obj->error = true; $obj->msg = ""; $obj->remoteResponse = false; if (!empty($response)) { $json = json_decode($response); if (!empty($json)) { if ($start && empty($json->error) && empty($json->response) && $try < 4) { _error_log("Live:controlRecording start record is not ready trying again in 5 seconds " . (isCommandLineInterface() ? 'From Command Line' : 'Not Command Line')); _error_log("Live:controlRecording " . json_encode(debug_backtrace())); sleep(5); return self::controlRecording($key, $live_servers_id, $start, $try + 1); } _error_log("Live:controlRecording start record is ready {$json->response}"); $obj->error = $json->error; $obj->msg = $json->msg; $obj->remoteResponse = true; } else { $obj->msg = "JSON response fail"; } } else { $obj->msg = "Control response fail"; } if ($obj->error) { _error_log("Live::controlRecording: [$key], [$live_servers_id], [$start] " . json_encode($obj)); } return $obj; } static function controlRecordingAsync($key, $live_servers_id, $start = true) { global $global; outputAndContinueInBackground(); $command = "php {$global['systemRootPath']}plugin/Live/controlRecording.php '$key' '$live_servers_id' '$start'"; _error_log("NGINX Live::controlRecordingAsync start ($command)"); $pid = execAsync($command); _error_log("NGINX Live::controlRecordingAsync end {$pid}"); return $pid; } static function userCanRecordLive($users_id) { if (!AVideoPlugin::isEnabledByName('SendRecordedToEncoder')) { return false; } return SendRecordedToEncoder::canRecord($users_id); } static function getButton($command, $key, $live_servers_id = 0, $iconsOnly = false, $label = "", $class = "", $tooltip = "") { if (!User::canStream()) { return ''; } global $global; $id = "getButton" . uniqid(); $afterLabel = ""; $obj = AVideoPlugin::getDataObject('Live'); switch ($command) { case "record_start": if ($obj->controllButtonsShowOnlyToAdmin_record_start && !User::isAdmin()) { return ''; } if (!self::userCanRecordLive(User::getId())) { return ''; } $buttonClass = "btn btn-success"; $iconClass = "fas fa-video"; if (empty($label)) { $label = __("Start Record"); } if (empty($tooltip)) { $tooltip = __("Start Record"); } $afterLabel = ''; break; case "record_stop": if (!self::userCanRecordLive(User::getId())) { return ''; } if ($obj->controllButtonsShowOnlyToAdmin_record_stop && !User::isAdmin()) { return ''; } $buttonClass = "btn btn-danger"; $iconClass = "fas fa-video-slash"; if (empty($label)) { $label = __("Stop Record"); } if (empty($tooltip)) { $tooltip = __("Stop Record"); } break; case "drop_publisher": if ($obj->controllButtonsShowOnlyToAdmin_drop_publisher && !User::isAdmin()) { return ''; } $buttonClass = "btn btn-default"; $iconClass = "fas fa-wifi"; if (empty($label)) { $label = __("Disconnect Livestream"); } if (empty($tooltip)) { $tooltip = __("Disconnect Livestream"); } break; case "drop_publisher_reset_key": if ($obj->controllButtonsShowOnlyToAdmin_drop_publisher_reset_key && !User::isAdmin()) { return ''; } $buttonClass = "btn btn-default"; $iconClass = "fas fa-key"; if (empty($label)) { $label = __("Disconnect Livestream"); } if (empty($tooltip)) { $tooltip = __("Disconnect Livestream") . __(" and also reset the stream name/key"); } break; case "save_dvr": $obj2 = AVideoPlugin::getDataObjectIfEnabled('SendRecordedToEncoder'); if (empty($obj2) || empty($obj2->saveDVREnable)) { return ''; } if ($obj->controllButtonsShowOnlyToAdmin_save_dvr && !User::isAdmin()) { return ''; } if (!self::userCanRecordLive(User::getId())) { return ''; } return '' . SendRecordedToEncoder::getSaveDVRButton($key, $live_servers_id, $class); break; default: return ''; } if ($iconsOnly) { $label = ""; } $html = ""; return $html; } static function getRecordControlls($key, $live_servers_id = 0, $iconsOnly = false) { if (!User::canStream()) { return ""; } $btn = "
"; $btn .= self::getButton("record_start", $key, $live_servers_id, $iconsOnly); $btn .= self::getButton("record_stop", $key, $live_servers_id, $iconsOnly); $btn .= "
"; return $btn; } static function getAllControlls($key, $live_servers_id = 0, $iconsOnly = false, $btnClass = '') { if (!Live::canManageLiveFromLiveKey($key, User::getId())) { return ''; } $btn = "
"; //$btn .= self::getButton("drop_publisher", $live_transmition_id, $live_servers_id); $btn .= self::getButton("save_dvr", $key, $live_servers_id, $iconsOnly, '', $btnClass); $btn .= self::getButton("drop_publisher_reset_key", $key, $live_servers_id, $iconsOnly, '', $btnClass); $btn .= self::getButton("record_start", $key, $live_servers_id, $iconsOnly, '', $btnClass); $btn .= self::getButton("record_stop", $key, $live_servers_id, $iconsOnly, '', $btnClass); $btn .= "
"; $btn .= ""; return $btn; } static function getRestreamer($live_servers_id = -1) { $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj->useLiveServers)) { if ($live_servers_id < 0) { $live_servers_id = self::getCurrentLiveServersId(); } $ls = new Live_servers($live_servers_id); if (!empty($ls->getRestreamerURL())) { return $ls->getRestreamerURL(); } } return $obj->restreamerURL; } static function getControl($live_servers_id = -1) { $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj->useLiveServers) && !empty($live_servers_id)) { if ($live_servers_id < 0) { $live_servers_id = self::getCurrentLiveServersId(); } $ls = new Live_servers($live_servers_id); if (!empty($ls->getControlURL())) { return $ls->getControlURL(); } } return $obj->controlURL; } static function getRTMPLink($users_id, $forceIndex = false) { $key = self::getKeyFromUser($users_id); - if (!empty($forceIndex)) { - // make sure the key is unique - $parts = explode('-', $key); - $key = $parts[0] . "-{$forceIndex}"; - } - return self::getRTMPLinkFromKey($key); + return self::getRTMPLinkFromKey($key, $forceIndex); } - static function getRTMPLinkFromKey($key) { + static function getRTMPLinkFromKey($key, $forceIndex=false) { $lso = new LiveStreamObject($key); - return $lso->getRTMPLink(); + return $lso->getRTMPLink($forceIndex); } static function getRTMPLinkWithOutKey($users_id) { $lso = new LiveStreamObject(self::getKeyFromUser($users_id)); return $lso->getRTMPLinkWithOutKey(); } static function getRTMPLinkWithOutKeyFromKey($key) { $lso = new LiveStreamObject($key); return $lso->getRTMPLinkWithOutKey(); } static function getKeyFromUser($users_id) { if (!User::isLogged() || ($users_id !== User::getId() && !User::isAdmin())) { return false; } $user = new User($users_id); $trasnmition = LiveTransmition::createTransmitionIfNeed($users_id); return $trasnmition['key']; } static function getDynamicKey($key) { $objLive = AVideoPlugin::getDataObject("Live"); if ($objLive->allowMultipleLivesPerUser) { $key .= '-' . date('His'); } return $key; } static function getPlayerServer() { $obj = AVideoPlugin::getObjectData("Live"); $url = $obj->playerServer; $url = getCDNOrURL($url, 'CDN_Live'); if (!empty($obj->useLiveServers)) { $ls = new Live_servers(self::getLiveServersIdRequest()); if (!empty($ls->getPlayerServer())) { $url = $ls->getPlayerServer(); $url = getCDNOrURL($url, 'CDN_LiveServers', $ls->getId()); } } //$url = str_replace("encoder.gdrive.local", "192.168.1.18", $url); return $url; } static function getUseAadaptiveMode() { $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj->useLiveServers)) { $ls = new Live_servers(self::getCurrentLiveServersId()); return $ls->getUseAadaptiveMode(); } return $obj->useAadaptiveMode; } static function getRemoteFile() { return self::getRemoteFileFromLiveServersID(self::getCurrentLiveServersId()); } static function getRemoteFileFromLiveServersID($live_servers_id) { global $global; $obj = AVideoPlugin::getObjectData("Live"); if (empty($live_servers_id) || !empty($obj->useLiveServers)) { $ls = new Live_servers($live_servers_id); $url = $ls->getGetRemoteFile(); if (IsValidURL($url)) { return $url; } } return "{$global['webSiteRootURL']}plugin/Live/standAloneFiles/getRecordedFile.php"; } static function getRemoteFileFromRTMPHost($rtmpHostURI) { $live_servers_id = Live_servers::getServerIdFromRTMPHost($rtmpHostURI); return self::getRemoteFileFromLiveServersID($live_servers_id); } static function getLiveServersIdRequest() { if (empty($_REQUEST['live_servers_id'])) { return 0; } return intval($_REQUEST['live_servers_id']); } static function getM3U8File($uuid, $doNotProtect = false) { $live_servers_id = self::getLiveServersIdRequest(); $lso = new LiveStreamObject($uuid, $live_servers_id, false, false); return $lso->getM3U8($doNotProtect); } public function getDisableGifThumbs() { $o = $this->getDataObject(); return $o->disableGifThumbs; } public function getStatsURL($live_servers_id = 0) { global $global; $o = $this->getDataObject(); if (!empty($live_servers_id)) { $liveServer = new Live_servers($live_servers_id); if ($liveServer->getStats_url()) { return $liveServer->getStats_url(); } } return $o->stats; } public function getChat($uuid) { global $global; //check if LiveChat Plugin is available $filename = $global['systemRootPath'] . 'plugin/LiveChat/LiveChat.php'; if (file_exists($filename)) { require_once $filename; LiveChat::includeChatPanel($uuid); } } function getStatsObject($live_servers_id = 0, $force_recreate = false, $tries = 0) { if (!function_exists('simplexml_load_file')) { _error_log("Live::getStatsObject: You need to install the simplexml_load_file function to be able to see the Live stats", AVideoLog::$ERROR); return false; } $name = "getStats" . DIRECTORY_SEPARATOR . "live_servers_id_{$live_servers_id}" . DIRECTORY_SEPARATOR . "getStatsObject"; global $getStatsObject; if (!isset($getStatsObject)) { $getStatsObject = array(); } if (empty($force_recreate)) { //_error_log("Live::getStatsObject[$live_servers_id] 1: searching for cache"); if (isset($getStatsObject[$live_servers_id])) { _error_log("Live::getStatsObject[$live_servers_id] 2: return cached result"); return $getStatsObject[$live_servers_id]; } $result = ObjectYPT::getCache($name, maxLifetime() + 60, true); if (!empty($result)) { _error_log("Live::getStatsObject[$live_servers_id] 3: return cached result $name [lifetime=" . (maxLifetime() + 60) . "]"); return _json_decode($result); } _error_log("Live::getStatsObject[$live_servers_id] 4: cache not found"); } else { _error_log("Live::getStatsObject[$live_servers_id] 5: forced to be recreated"); } $o = $this->getDataObject(); if ($o->doNotProcessNotifications) { $xml = new stdClass(); $xml->server = new stdClass(); $xml->server->application = array(); $getStatsObject[$live_servers_id] = $xml; ObjectYPT::setCache($name, json_encode($xml)); return $xml; } if (empty($o->requestStatsTimout)) { $o->requestStatsTimout = 2; } ini_set('allow_url_fopen ', 'ON'); $url = $this->getStatsURL($live_servers_id); if (!empty($_SESSION['getStatsObjectRequestStatsTimout'][$url])) { _error_log("Live::getStatsObject[$live_servers_id] RTMP Server ($url) is NOT responding we will wait less from now on => live_servers_id = ($live_servers_id) "); // if the server already fail, do not wait mutch for it next time, just wait 0.5 seconds $o->requestStatsTimout = $_SESSION['getStatsObjectRequestStatsTimout'][$url]; } //_error_log_debug("Live::getStatsObject ($url) ({$o->requestStatsTimout}) "); $waitFile = getTmpDir() . md5($name); if (file_exists($waitFile) && filemtime($waitFile) > time() - 10 && $tries < 10) { _error_log("Live::getStatsObject[$live_servers_id]: there is a request in progeress, please wait {$waitFile}"); sleep(1); return self::getStatsObject($live_servers_id, $force_recreate, $tries + 1); } _error_log("Live::getStatsObject[$live_servers_id]: Creating a waitfile {$waitFile}"); file_put_contents($waitFile, time()); $data = $this->get_data($url, $o->requestStatsTimout); unlink($waitFile); if (empty($data)) { _session_start(); if (empty($_SESSION['getStatsObjectRequestStatsTimout'])) { $_SESSION['getStatsObjectRequestStatsTimout'] = array(); } $_SESSION['getStatsObjectRequestStatsTimout'][$url] = $o->requestStatsTimout - 1; if ($_SESSION['getStatsObjectRequestStatsTimout'][$url] < 1) { $_SESSION['getStatsObjectRequestStatsTimout'][$url] = 2; } _error_log("Live::getStatsObject RTMP Server ($url) is OFFLINE, timeout=({$o->requestStatsTimout}) we could not connect on it => live_servers_id = ($live_servers_id) ", AVideoLog::$ERROR); $data = 'The RTMP Server is Unavailable0'; } else { if (!empty($_SESSION['getStatsObjectRequestStatsTimout'][$url])) { _error_log("Live::getStatsObject RTMP Server ($url) is respond again => live_servers_id = ($live_servers_id) "); // the server respont again, wait the default time _session_start(); $_SESSION['getStatsObjectRequestStatsTimout'][$url] = 0; unset($_SESSION['getStatsObjectRequestStatsTimout'][$url]); } } $xml = simplexml_load_string($data); $getStatsObject[$live_servers_id] = $xml; ObjectYPT::setCache($name, json_encode($xml)); return $xml; } function get_data($url, $timeout) { global $global; if (!IsValidURL($url)) { return false; } _error_log_debug("Live::get_data($url, $timeout)"); return url_get_contents($url, '', $timeout); } public function getChartTabs() { return '
  • ' . __('Live videos') . '
  • '; } public function getChartContent() { global $global; include $global['systemRootPath'] . 'plugin/Live/report.php'; } static public function saveHistoryLog($key) { // get the latest history for this key $latest = LiveTransmitionHistory::getLatest($key); if (!empty($latest)) { LiveTransmitionHistoryLog::addLog($latest['id']); } } public function dataSetup() { $obj = $this->getDataObject(); if (!isLive() || $obj->disableDVR) { return ""; } return "liveui: true"; } static function stopLive($users_id) { if (!User::isAdmin() && User::getId() != $users_id) { return false; } $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj)) { $server = str_replace("stats", "", $obj->stats); $lt = new LiveTransmition(0); $lt->loadByUser($users_id); $key = $lt->getKey(); $appName = self::getApplicationName(); $url = "{$server}control/drop/publisher?app={$appName}&name=$key"; url_get_contents($url); $dir = $obj->hls_path . "/$key"; if (is_dir($dir)) { exec("rm -fR $dir"); rrmdir($dir); } } } // not implemented yet static function startRecording($users_id) { if (!User::isAdmin() && User::getId() != $users_id) { return false; } $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj)) { $server = str_replace("stats", "", $obj->stats); $lt = new LiveTransmition(0); $lt->loadByUser($users_id); $key = $lt->getKey(); $appName = self::getApplicationName(); $url = "{$server}control/record/start?app={$appName}&name=$key"; url_get_contents($url); } } static function getApplicationName() { $rtmpServer = self::getServer(); $parts = explode('/', $rtmpServer); $live = end($parts); if (!preg_match('/^live/i', $live)) { $live = 'live'; } return trim($live); } // not implemented yet static function stopRecording($users_id) { if (!User::isAdmin() && User::getId() != $users_id) { return false; } $obj = AVideoPlugin::getObjectData("Live"); if (!empty($obj)) { $server = str_replace("stats", "", $obj->stats); $lt = new LiveTransmition(0); $lt->loadByUser($users_id); $key = $lt->getKey(); $appName = self::getApplicationName(); $url = "{$server}control/record/stop?app={$appName}&name=$key"; url_get_contents($url); } } static function getLinkToLiveFromUsers_id($users_id) { $live_servers_id = self::getCurrentLiveServersId(); return self::getLinkToLiveFromUsers_idAndLiveServer($users_id, $live_servers_id); } static function getLinkToLiveFromUsers_idAndLiveServer($users_id, $live_servers_id, $live_index = null) { if (empty($users_id)) { return false; } global $global; $user = new User($users_id); if (empty($user->getChannelName())) { return false; } return self::getLinkToLiveFromChannelNameAndLiveServer($user->getChannelName(), $live_servers_id, $live_index); } static function getLinkToLiveFromChannelNameAndLiveServer($channelName, $live_servers_id, $live_index = null) { global $global; $live_servers_id = intval($live_servers_id); $channelName = trim($channelName); if (empty($channelName)) { return false; } $url = "{$global['webSiteRootURL']}live/{$live_servers_id}/" . urlencode($channelName); if (!empty($live_index)) { $url .= '/' . urlencode($live_index); } else if (!isset($live_index) && !empty($_REQUEST['live_index'])) { $url .= '/' . urlencode($_REQUEST['live_index']); } if (!empty($_REQUEST['playlists_id_live'])) { $url = addQueryStringParameter($url, 'playlists_id_live', $_REQUEST['playlists_id_live']); } //return "{$global['webSiteRootURL']}plugin/Live/?live_servers_id={$live_servers_id}&c=" . urlencode($channelName); return $url; } static function getAvailableLiveServersId() { $ls = self::getAvailableLiveServer(); if (empty($ls)) { return 0; } else { return intval($ls->live_servers_id); } } static function getLastServersIdFromUser($users_id) { $last = LiveTransmitionHistory::getLatestFromUser($users_id); if (empty($last)) { return 0; } else { return intval($last['live_servers_id']); } } static function getLastsLiveHistoriesFromUser($users_id, $count = 10) { return LiveTransmitionHistory::getLastsLiveHistoriesFromUser($users_id, $count); } static function getLinkToLiveFromUsers_idWithLastServersId($users_id) { $live_servers_id = self::getLastServersIdFromUser($users_id); return self::getLinkToLiveFromUsers_idAndLiveServer($users_id, $live_servers_id); } static function getCurrentLiveServersId() { $live_servers_id = self::getLiveServersIdRequest(); if ($live_servers_id) { return $live_servers_id; } else { return self::getAvailableLiveServersId(); } } public function getVideosManagerListButtonTitle() { global $global; if (!User::isAdmin()) { return ""; } $btn = '
    '; return $btn; } public function getPluginMenu() { global $global; $obj = $this->getDataObject(); $btn = ''; if ($obj->useLiveServers) { $servers = Live_servers::getAll(); foreach ($servers as $value) { $btn .= ''; } } else { $btn .= ''; } return $btn; } static function getStats($force_recreate = false) { global $getStatsLive, $_getStats, $getStatsObject; if (empty($force_recreate)) { if (isset($getStatsLive)) { _error_log('Live::getStats: return cached result'); return $getStatsLive; } } $obj = AVideoPlugin::getObjectData("Live"); if (empty($obj->useLiveServers)) { //_error_log('getStats getStats 1: ' . ($force_recreate?'force_recreate':'DO NOT force_recreate')); $getStatsLive = self::_getStats(0, $force_recreate); //_error_log('Live::getStats(0) 1'); return $getStatsLive; } else { $rows = Live_servers::getAllActive(); foreach ($rows as $key => $value) { $ls = new Live_servers(Live::getLiveServersIdRequest()); if (!empty($row['playerServer'])) { //_error_log('getStats getStats 2: ' . ($force_recreate?'force_recreate':'DO NOT force_recreate')); $server = self::_getStats($row['id'], $force_recreate); $server->live_servers_id = $row['id']; $server->playerServer = $row['playerServer']; $getStatsLive = $server; return $server; } } } $ls = Live_servers::getAllActive(); $liveServers = array(); $getLiveServersIdRequest = self::getLiveServersIdRequest(); foreach ($ls as $value) { $server = Live_servers::getStatsFromId($value['id'], $force_recreate); if (!empty($server) && is_object($server)) { $server->live_servers_id = $value['id']; $server->playerServer = $value['playerServer']; $server->applications = object_to_array($server->applications); foreach ($server->applications as $key => $app) { if (self::isAdaptive($app['key'])) { continue; } $_REQUEST['live_servers_id'] = $value['id']; if (empty($app['key'])) { $app['key'] = ""; } $server->applications[$key]['m3u8'] = self::getM3U8File($app['key']); $server->applications[$key]['isURL200'] = isURL200($server->applications[$key]['m3u8']); } $liveServers[] = $server; } else { _error_log("Live::getStats Live Server NOT found {$value['id']} " . json_encode($server) . " " . json_encode($value)); } } _error_log("Live::getStats return " . json_encode($liveServers)); $_REQUEST['live_servers_id'] = $getLiveServersIdRequest; $getStatsLive = $liveServers; return $liveServers; } static function isAdaptive($key) { if (preg_match('/_(hi|low|mid)$/i', $key)) { return true; } return false; } static function getAllServers() { $obj = AVideoPlugin::getObjectData("Live"); if (empty($obj->useLiveServers)) { return array("id" => 0, "name" => __("Default"), "status" => "a", "rtmp_server" => $obj->server, 'playerServer' => $obj->playerServer, "stats_url" => $obj->stats, "disableDVR" => $obj->disableDVR, "disableGifThumbs" => $obj->disableGifThumbs, "useAadaptiveMode" => $obj->useAadaptiveMode, "protectLive" => $obj->protectLive, "getRemoteFile" => ""); } else { return Live_servers::getAllActive(); } } static function getAvailableLiveServer() { global $_getAvailableLiveServer; if (isset($_getAvailableLiveServer)) { return $_getAvailableLiveServer; } // create 1 min cache $name = "Live::getAvailableLiveServer"; $return = ObjectYPT::getCache($name, 60, true); if (empty($return)) { $obj = AVideoPlugin::getObjectData("Live"); if (empty($obj->useLiveServers)) { $return = false; } else { $stats = getStatsNotifications(); $liveServers = array(); $servers = Live_servers::getAllActive(); foreach ($servers as $value) { $obj = new stdClass(); $obj->live_servers_id = $value['id']; $obj->countLiveStream = 0; $liveServers[$value['id']] = $obj; } foreach ($stats['applications'] as $value) { if (!empty($value['live_servers_id'])) { $liveServers[$value['live_servers_id']]->countLiveStream++; } } usort($liveServers, function($a, $b) { if ($a->countLiveStream == $b->countLiveStream) { $_getAvailableLiveServer = 0; return 0; } $_getAvailableLiveServer = ($a->countLiveStream < $b->countLiveStream) ? -1 : 1; return $_getAvailableLiveServer; }); if (empty($liveServers[0])) { _error_log("Live::getAvailableLiveServer we could not get server status, try to uncheck useLiveServers parameter from the Live plugin"); $_getAvailableLiveServer = array(); return array(); } $return = $liveServers[0]; ObjectYPT::setCache($name, $return); } } $_getAvailableLiveServer = $return; return $return; } static function canSeeLiveFromLiveKey($key) { $lt = self::getLiveTransmitionObjectFromKey($key); if (empty($lt)) { return false; } return $lt->userCanSeeTransmition(); } static function canManageLiveFromLiveKey($key, $users_id) { if (empty($users_id)) { return false; } $lt = self::getLiveTransmitionObjectFromKey($key); if (empty($lt)) { return false; } $user = new User($users_id); if ($user->getIsAdmin()) { return true; } $u_id = $lt->getUsers_id(); return $u_id == $users_id; } static function isAPrivateLiveFromLiveKey($key) { $lt = self::getLiveTransmitionObjectFromKey($key); if (empty($lt)) { return false; } return $lt->isAPrivateLive(); } static function getTitleFromUsers_Id($users_id) { $lt = self::getLiveTransmitionObjectFromUsers_id($users_id); return $lt->getTitle(); } static function getLiveTransmitionObjectFromUsers_id($users_id) { $latest = LiveTransmitionHistory::getLatestFromUser($users_id); if (!empty($latest)) { $key = $latest['key']; } else { $key = self::getLiveKey($users_id); } return self::getLiveTransmitionObjectFromKey($key); } static function getLiveTransmitionObjectFromKey($key) { global $getLiveTransmitionObjectFromKey; if (empty($getLiveTransmitionObjectFromKey)) { $getLiveTransmitionObjectFromKey = array(); } $parts = explode("_", $key); if (empty($parts[0])) { return false; } if (!isset($getLiveTransmitionObjectFromKey[$parts[0]])) { $livet = LiveTransmition::keyExists($parts[0]); if (empty($livet)) { $getLiveTransmitionObjectFromKey[$parts[0]] = false; } else { $lt = new LiveTransmition($livet['id']); $getLiveTransmitionObjectFromKey[$parts[0]] = $lt; } } return $getLiveTransmitionObjectFromKey[$parts[0]]; } static function _getStats($live_servers_id = 0, $force_recreate = false) { global $global, $_getStats; if (empty($_REQUEST['name'])) { //_error_log("Live::_getStats {$live_servers_id} GET " . json_encode($_GET)); //_error_log("Live::_getStats {$live_servers_id} POST " . json_encode($_POST)); //_error_log("Live::_getStats {$live_servers_id} REQUEST " . json_encode($_REQUEST)); $_REQUEST['name'] = "undefined"; } //_error_log('_getStats: ' . ($force_recreate?'force_recreate':'DO NOT force_recreate')); $cacheName = "getStats" . DIRECTORY_SEPARATOR . "live_servers_id_{$live_servers_id}" . DIRECTORY_SEPARATOR . "{$_REQUEST['name']}_" . User::getId(); if (empty($force_recreate)) { if (!empty($_getStats[$live_servers_id][$_REQUEST['name']]) && is_object($_getStats[$live_servers_id][$_REQUEST['name']])) { _error_log("Live::_getStats cached result 1 {$_REQUEST['name']} "); return $_getStats[$live_servers_id][$_REQUEST['name']]; } $result = ObjectYPT::getCache($cacheName, maxLifetime() + 60, true); if (!empty($result)) { _error_log("Live::_getStats cached result 2 {$_REQUEST['name']} {$cacheName}"); return _json_decode($result); } } session_write_close(); $obj = new stdClass(); $obj->error = true; $obj->msg = "OFFLINE"; $obj->nclients = 0; $obj->applications = array(); $obj->hidden_applications = array(); $obj->name = $_REQUEST['name']; $_getStats[$live_servers_id][$_REQUEST['name']] = $obj; $liveUsersEnabled = AVideoPlugin::isEnabledByName("LiveUsers"); $p = AVideoPlugin::loadPlugin("Live"); $xml = $p->getStatsObject($live_servers_id, $force_recreate); $xml = json_encode($xml); $xml = _json_decode($xml); $stream = false; $lifeStream = array(); $applicationName = self::getApplicationName(); if (empty($xml) || !is_object($xml)) { _error_log("_getStats XML is not an object live_servers_id=$live_servers_id"); } else { //$obj->server = $xml->server; if (!empty($xml->server->application) && !is_array($xml->server->application)) { $application = $xml->server->application; $xml->server->application = array(); $xml->server->application[] = $application; } foreach ($xml->server->application as $key => $application) { if ($application->name !== $applicationName && $application->name !== 'adaptive') { continue; } if (!empty($application->live->stream)) { if (empty($lifeStream)) { $lifeStream = array(); } $stream = $application->live->stream; if (empty($application->live->stream->name) && !empty($application->live->stream[0]->name)) { foreach ($application->live->stream as $stream) { if (Live::isAdaptive($stream->name)) { continue; } $lifeStream[] = $stream; } } else { if (Live::isAdaptive($stream->name)) { continue; } $lifeStream[] = $application->live->stream; } } } } $obj->disableGif = $p->getDisableGifThumbs(); foreach ($lifeStream as $value) { if (!empty($value->name)) { $row = LiveTransmition::keyExists($value->name); if (empty($row['users_id'])) { continue; } if (!empty($row) && $value->name === $obj->name) { $obj->msg = "ONLINE"; } $title = $row['title']; $u = new User($row['users_id']); $hiddenName = preg_replace('/^(.{5})/', '*****', $value->name); //_error_log('Live::isLiveFromKey:_getStats '. json_encode($_SERVER)); if (!self::canSeeLiveFromLiveKey($value->name)) { $obj->hidden_applications[] = array( "key" => $value->name, "name" => $row['channelName'], "user" => $row['channelName'], "title" => "{$row['channelName']} ($hiddenName} is a private live", ); if (!User::isAdmin()) { continue; } else { $title .= " (private live)"; } } else if (empty($row) || empty($row['public'])) { $obj->hidden_applications[] = array( "key" => $value->name, "name" => $row['channelName'], "user" => $row['channelName'], "title" => "{$row['channelName']} ($hiddenName} " . __("is set to not be listed") ); if (!User::isAdmin()) { continue; } else { $title .= __(" (set to not be listed)"); } } else if ($u->getStatus() !== 'a') { $obj->hidden_applications[] = array( "key" => $value->name, "name" => $row['channelName'], "user" => $row['channelName'], "title" => "{$row['channelName']} {$hiddenName} " . __("the user is inactive"), ); if (!User::isAdmin()) { continue; } else { $title .= __(" (user is inactive)"); } } $users = false; if ($liveUsersEnabled) { $filename = $global['systemRootPath'] . 'plugin/LiveUsers/Objects/LiveOnlineUsers.php'; if (file_exists($filename)) { require_once $filename; $liveUsers = new LiveOnlineUsers(0); $users = $liveUsers->getUsersFromTransmitionKey($value->name, $live_servers_id); } } $userName = $u->getNameIdentificationBd(); $user = $u->getUser(); $channelName = $u->getChannelName(); $photo = $u->getPhotoDB(); //return array('key'=>$key, 'cleanKey'=>$cleanKey, 'live_index'=>$live_index, 'playlists_id_live'=>$playlists_id_live); $parameters = self::getLiveParametersFromKey($value->name); $playlists_id_live = $parameters['playlists_id_live']; $live_index = $parameters['live_index']; if (!empty($playlists_id_live)) { $_REQUEST['playlists_id_live'] = $playlists_id_live; $playlists_id_live = $_REQUEST['playlists_id_live']; $photo = PlayLists::getImage($_REQUEST['playlists_id_live']); $title = PlayLists::getNameOrSerieTitle($_REQUEST['playlists_id_live']); } $poster = $p->getLivePosterImage($row['users_id'], $live_servers_id, $playlists_id_live, $live_index); if (!empty($live_index)) { $_REQUEST['live_index'] = $live_index; } if (!empty($live_index) || $live_index === 'false') { $title .= " ({$live_index})"; } // this variable is to keep it compatible for Mobile app $UserPhoto = $photo; $key = LiveTransmition::keyNameFix($value->name); $link = Live::getLinkToLiveFromChannelNameAndLiveServer($u->getChannelName(), $live_servers_id, $live_index); $m3u8 = self::getM3U8File($key); $liveUsers = AVideoPlugin::isEnabledByName('LiveUsers'); //$filename = $global['systemRootPath'] . 'plugin/LiveLinks/view/menuItem.html'; $filenameExtra = $global['systemRootPath'] . 'plugin/LiveLinks/view/extraItem.html'; $filenameExtraVideoPage = $global['systemRootPath'] . 'plugin/LiveLinks/view/extraItemVideoPage.html'; $filename = $filenameListItem = $global['systemRootPath'] . 'plugin/LiveLinks/view/videoListItem.html'; $search = array( '_unique_id_', '_user_photo_', '_title_', '_user_identification_', '_description_', '_link_', '_imgJPG_', '_imgGIF_', '_class_', '_total_on_live_links_id_', 'liveLink', 'LiveLink' ); $content = file_get_contents($filename); $contentExtra = file_get_contents($filenameExtra); $contentExtraVideoPage = file_get_contents($filenameExtraVideoPage); $contentListem = file_get_contents($filenameListItem); $uid = "live_{$live_servers_id}_{$value->name}"; $replace = array( $uid, $UserPhoto, $title, $user, str_replace('"', "", ''), $link, '', empty($obj->disableGifThumbs) ? ('') : "", "col-lg-2 col-md-4 col-sm-4 col-xs-6", ($liveUsers ? getLiveUsersLabelLive($value->name, $live_servers_id) : ''), 'liveVideo', 'LiveVideo' ); $newContent = str_replace($search, $replace, $content); $newContentExtra = str_replace($search, $replace, $contentExtra); $newContentExtraVideoPage = str_replace($search, $replace, $contentExtraVideoPage); $newContentVideoListItem = str_replace($search, $replace, $contentListem); $obj->applications[] = array( "html" => $newContent, "htmlExtra" => $newContentExtra, "htmlExtraVideoPage" => $newContentExtraVideoPage, "htmlExtraVideoListItem" => $newContentVideoListItem, "live_index" => $live_index, "live_cleanKey" => $parameters['cleanKey'], "key" => $value->name, "isAdaptive" => self::isAdaptive($value->name), "isPrivate" => self::isAPrivateLiveFromLiveKey($value->name), "users" => $users, "name" => $userName, "user" => $user, "photo" => $photo, "UserPhoto" => $UserPhoto, "title" => $title, 'channelName' => $channelName, 'poster' => $poster, 'imgGif' => $p->getLivePosterImage($row['users_id'], $live_servers_id, $playlists_id_live, $live_index, 'webp'), 'link' => addQueryStringParameter($link, 'embed', 1), 'href' => $link, 'playlists_id_live' => $playlists_id_live, 'm3u8' => $m3u8, 'isURL200' => isURL200($m3u8), 'users_id' => $row['users_id'], 'live_servers_id' => $live_servers_id, 'categories_id' => intval($row['categories_id']), 'className' => $uid ); if ($value->name === $obj->name) { $obj->error = property_exists($value, 'publishing') ? false : true; $obj->msg = (!$obj->error) ? "ONLINE" : "Waiting for Streamer"; $obj->stream = $value; $obj->nclients = intval($value->nclients); break; } } } $obj->countLiveStream = count($obj->applications); $obj->error = false; $_getStats[$live_servers_id][$_REQUEST['name']] = $obj; //_error_log("Live::_getStats NON cached result {$_REQUEST['name']} " . json_encode($obj)); ObjectYPT::setCache($cacheName, json_encode($obj)); return $obj; } static function byPass() { if (preg_match('/socket_notification/', $_SERVER['SCRIPT_FILENAME'])) { return true; } return false; } static function getLiveParametersFromKey($key) { $key = preg_replace('/[^a-z0-9_-]/i', '', $key); $obj = AVideoPlugin::getObjectData('Live'); $playlists_id_live = false; if (preg_match("/.*_([0-9]+)/", $key, $matches)) { if (!empty($matches[1])) { $playlists_id_live = intval($matches[1]); } } $live_index = ''; if (preg_match("/.*-([0-9a-zA-Z]+)/", $key, $matches)) { if (!empty($matches[1])) { $live_index = strip_tags($matches[1]); if ($live_index === 'false') { $live_index = ''; } } } $cleanKey = self::cleanUpKey($key); return array('key' => $key, 'cleanKey' => $cleanKey, 'live_index' => $live_index, 'playlists_id_live' => $playlists_id_live); } static function getLiveIndexFromKey($key) { $parameters = self::getLiveParametersFromKey($key); return $parameters['live_index']; } static function cleanUpKey($key) { if ($adapKey = self::isAdaptiveTransmition($key)) { $key = $adapKey; } if ($plKey = self::isPlayListTransmition($key)) { $key = $plKey; } if ($subKey = self::isSubTransmition($key)) { $key = $subKey; } return $key; } static function isAdaptiveTransmition($key) { // check if is a subtransmition $parts = explode("_", $key); if (!empty($parts[1])) { $adaptive = array('hi', 'low', 'mid'); if (in_array($parts[1], $adaptive)) { return $parts[0]; ; } } return false; } static function isPlayListTransmition($key) { // check if is a subtransmition $parts = explode("_", $key); if (!empty($parts[1])) { return $parts[0]; } else { return false; } } static function isSubTransmition($key) { // check if is a subtransmition $parts = explode("-", $key); if (!empty($parts[1])) { return $parts[0]; } else { return false; } } static function getImage($users_id, $live_servers_id, $playlists_id_live = 0, $live_index = '') { $p = AVideoPlugin::loadPlugin("Live"); if (self::isLive($users_id, $live_servers_id, $live_index)) { $url = $p->getLivePosterImage($users_id, $live_servers_id, $playlists_id_live, $live_index); $url = addQueryStringParameter($url, "playlists_id_live", $playlists_id_live); } else { $url = self::getOfflineImage(false); } return $url; } static function getLatestKeyFromUser($users_id) { if (empty($users_id)) { return false; } $latest = LiveTransmitionHistory::getLatestFromUser($users_id); if (empty($latest)) { return false; } return $latest['key']; } static function isLive($users_id, $live_servers_id = 0, $live_index = '', $force_recreate = false) { global $_live_is_live; if (empty($users_id)) { return false; } if (!isset($_live_is_live)) { $_live_is_live = array(); } $name = "{$users_id}_{$live_servers_id}"; if (!empty($_live_is_live[$name])) { return $_live_is_live[$name]; } $lh = LiveTransmitionHistory::getActiveLiveFromUser($users_id, $live_servers_id, ''); if (empty($lh)) { _error_log("Live::isLive we could not found any active livestream for user $users_id, $live_servers_id"); return false; } $key = $lh['key']; $_live_is_live[$name] = self::isLiveAndIsReadyFromKey($key, $live_servers_id, $live_index, $force_recreate); return $_live_is_live[$name]; } static function isKeyLiveInStats($key, $live_servers_id = 0, $live_index = '', $force_recreate = false) { global $_isLiveFromKey; if (empty($key) || $key == '-1') { _error_log('Live::isKeyLiveInStats key is empty'); return false; } $index = "$key, $live_servers_id,$live_index"; if (!isset($_isLiveFromKey)) { $_isLiveFromKey = array(); } if (empty($force_recreate) && isset($_isLiveFromKey[$index])) { _error_log('Live::isKeyLiveInStats key is already set'); return $_isLiveFromKey[$index]; } //_error_log('getStats execute getStats: ' . __LINE__ . ' ' . __FILE__); //$json = getStatsNotifications($force_recreate); //_error_log('getStats execute getStats: ' . ($force_recreate?'force_recreate':'DO NOT force_recreate')); $json = self::getStats($force_recreate); _error_log('Live::isKeyLiveInStats:self::getStats ' . json_encode($json)); $_isLiveFromKey[$index] = false; if (!empty($json)) { //_error_log("Live::isLiveFromKey {$key} JSON was not empty"); if (!is_array($json)) { $json = array($json); } $namesFound = array(); foreach ($json as $ki => $item) { //_error_log("Live::isLiveFromKey json [$ki] " . json_encode($item)); $applications = array(); if (empty($item->applications) && is_array($item)) { $applications = $item; } else if (is_object($item) && !empty($item->applications)) { $applications = $item->applications; } foreach ($applications as $k => $value) { $value = object_to_array($value); //_error_log("Live::isLiveFromKey applications [$k] ". json_encode($value)); if (!is_array($value) || empty($value) || empty($value['key'])) { continue; } $namesFound[] = "({$value['key']})"; if (preg_match("/{$key}.*/", $value['key'])) { if (empty($live_servers_id)) { $_isLiveFromKey[$index] = true; $_isLiveFromKey[$index] = $_isLiveFromKey[$index]; break 2; } else { if (intval(@$value['live_servers_id']) == $live_servers_id) { $_isLiveFromKey[$index] = true; $_isLiveFromKey[$index] = $_isLiveFromKey[$index]; break 2; } } } } if (!empty($item->hidden_applications)) { $applications = $item->hidden_applications; foreach ($applications as $value) { $value = object_to_array($value); if (!is_array($value) || empty($value) || empty($value['key'])) { continue; } $namesFound[] = "({$value['key']})"; if (preg_match("/{$key}.*/", $value['key'])) { if (empty($live_servers_id)) { $_isLiveFromKey[$index] = true; $_isLiveFromKey[$index] = $_isLiveFromKey[$index]; break 2; } else { if (intval(@$value['live_servers_id']) == $live_servers_id) { $_isLiveFromKey[$index] = true; $_isLiveFromKey[$index] = $_isLiveFromKey[$index]; break 2; } } } } } } _error_log("Live::isLiveFromKey namesFound " . json_encode($namesFound)); } if (empty($_isLiveFromKey[$index])) { _error_log("Live::isLiveFromKey is NOT online [{$key}]"); } else { _error_log("Live::isLiveFromKey is online [{$key}]"); } return $_isLiveFromKey[$index]; } static function isLiveAndIsReadyFromKey($key, $live_servers_id = 0, $live_index = '', $force_recreate = false) { global $_isLiveAndIsReadyFromKey; if (!isset($_isLiveAndIsReadyFromKey)) { $_isLiveAndIsReadyFromKey = array(); } $name = "getStats" . DIRECTORY_SEPARATOR . "isLiveAndIsReadyFromKey{$key}_{$live_servers_id}"; if (empty($force_recreate)) { if (isset($_isLiveAndIsReadyFromKey[$name])) { return $_isLiveAndIsReadyFromKey[$name]; } $cache = ObjectYPT::getCache($name, 60, true); } if (!empty($cache)) { $json = _json_decode($cache); } if (!empty($json) && is_object($json)) { $_isLiveAndIsReadyFromKey[$name] = $json->result; } else { $json = new stdClass(); $key = self::getLiveKeyFromRequest($key, $live_index); //_error_log('getStats execute isKeyLiveInStats: ' . __LINE__ . ' ' . __FILE__); //_error_log("isLiveAndIsReadyFromKey::key: {$key}"); $isLiveFromKey = self::isKeyLiveInStats($key, $live_servers_id, $live_index, $force_recreate); $_isLiveAndIsReadyFromKey[$name] = true; if (empty($isLiveFromKey)) { _error_log("isLiveAndIsReadyFromKey the key {$key} is not present on the stats"); $_isLiveAndIsReadyFromKey[$name] = false; } else { $ls = $_REQUEST['live_servers_id']; $_REQUEST['live_servers_id'] = $live_servers_id; $m3u8 = self::getM3U8File($key); $_REQUEST['live_servers_id'] = $ls; //_error_log('getStats execute isURL200: ' . __LINE__ . ' ' . __FILE__); $is200 = isURL200($m3u8, $force_recreate); if (empty($is200)) { _error_log("isLiveAndIsReadyFromKey the m3u8 file is not present {$m3u8}"); $_isLiveAndIsReadyFromKey[$name] = false; } } $json->result = $_isLiveAndIsReadyFromKey[$name]; ObjectYPT::setCache($name, json_encode($json)); } return $_isLiveAndIsReadyFromKey[$name]; } static function getOnlineLivesFromUser($users_id) { $key = self::getLiveKey($users_id); return self::getOnlineLivesFromKey($key); } static function getOnlineLivesFromKey($key) { $json = getStatsNotifications(); $lives = array(); if (!empty($json) && is_object($json) && !empty($json->applications)) { foreach ($json->applications as $value) { if (preg_match("/{$key}.*/", $value['key'])) { $lives[] = $value; } } } return $lives; } static function keyIsFromPlaylist($key) { $parts = explode("_", $key); if (empty($parts[1])) { return false; } return array('key' => $parts[0], 'playlists_id' => $parts[1]); } static function getLiveKey($users_id) { $lt = new LiveTransmition(0); $lt->loadByUser($users_id); return $lt->getKey(); } static function getLiveKeyFromUser($users_id, $live_index = '', $playlists_id_live = '') { $key = self::getLiveKey($users_id); return self::getLiveKeyFromRequest($key, $live_index, $playlists_id_live); } static function getLiveKeyFromRequest($key, $live_index = '', $playlists_id_live = '') { if (strpos($key, '-') === false) { if (!empty($live_index)) { $key .= '-' . preg_replace('/[^0-9a-z]/i', '', $live_index); } else if (!empty($_REQUEST['live_index'])) { $key .= '-' . preg_replace('/[^0-9a-z]/i', '', $_REQUEST['live_index']); } } if (strpos($key, '_') === false) { if (!empty($playlists_id_live)) { $key .= '_' . preg_replace('/[^0-9]/', '', $_REQUEST['playlists_id_live']); } else if (!empty($_REQUEST['playlists_id_live'])) { $key .= '_' . preg_replace('/[^0-9]/', '', $_REQUEST['playlists_id_live']); } } return $key; } public function getImageGif($users_id, $live_servers_id = 0, $playlists_id_live = 0, $live_index = '') { global $global; if (empty($live_servers_id)) { $live_servers_id = self::getCurrentLiveServersId(); } if ($live_index === 'false') { $live_index = ''; } $u = new User($users_id); $username = $u->getUser(); $file = "plugin/Live/getImage.php"; $url = $global['webSiteRootURL'] . $file; $url = addQueryStringParameter($url, "live_servers_id", $live_servers_id); $url = addQueryStringParameter($url, "playlists_id_live", $playlists_id_live); $url = addQueryStringParameter($url, "live_index", $live_index); $url = addQueryStringParameter($url, "u", $username); $url = addQueryStringParameter($url, "format", 'gif'); return $url; } public static function getPosterImage($users_id, $live_servers_id) { global $global; $file = self::_getPosterImage($users_id, $live_servers_id); if (!file_exists($global['systemRootPath'] . $file)) { $file = self::getOnAirImage(false); } return $file; } public static function getPosterImageOrFalse($users_id, $live_servers_id) { $poster = self::getPosterImage($users_id, $live_servers_id); if (preg_match('/OnAir.jpg$/', $poster)) { return false; } return $poster; } public function getLivePosterImage($users_id, $live_servers_id = 0, $playlists_id_live = 0, $live_index = '', $format = 'jpg') { global $global; return $global['webSiteRootURL'] . self::getLivePosterImageRelativePath($users_id, $live_servers_id, $playlists_id_live, $live_index, $format); } public function getLivePosterImageRelativePath($users_id, $live_servers_id = 0, $playlists_id_live = 0, $live_index = '', $format = 'jpg') { global $global; if (empty($live_servers_id)) { $live_servers_id = self::getCurrentLiveServersId(); } if (self::isLiveThumbsDisabled()) { $file = self::_getPosterImage($users_id, $live_servers_id); if (!file_exists($global['systemRootPath'] . $file)) { $file = self::getOnAirImage(false); } } else { $u = new User($users_id); $username = $u->getUser(); $file = "plugin/Live/getImage.php?live_servers_id={$live_servers_id}&playlists_id_live={$playlists_id_live}&live_index={$live_index}&u={$username}&format={$format}"; } return $file; } public static function isLiveThumbsDisabled() { $obj = AVideoPlugin::getDataObject("Live"); if (!empty($obj->disableLiveThumbs)) { return true; } return false; } public static function getPosterThumbsImage($users_id, $live_servers_id) { global $global; $file = self::_getPosterThumbsImage($users_id, $live_servers_id); if (!file_exists($global['systemRootPath'] . $file)) { $file = self::getOnAirImage(false); } return $file; } public static function getPoster($users_id, $live_servers_id, $key = '') { _error_log("getPoster($users_id, $live_servers_id, $key)"); $lh = LiveTransmitionHistory::getActiveLiveFromUser($users_id, $live_servers_id, $key); $live_index = self::getLiveIndexFromKey($lh['key']); $poster = self::getPosterImageOrFalse($users_id, $live_servers_id, $live_index); if (empty($poster)) { $poster = self::getOfflineImage(false); } if (empty($lh)) { _error_log("getPoster empty activity"); return $poster; } $parameters = self::getLiveParametersFromKey($lh['key']); $live_index = $parameters['live_index']; $playlists_id_live = $parameters['playlists_id_live']; if (self::isLiveAndIsReadyFromKey($lh['key'], $lh['live_servers_id'])) { return self::getLivePosterImageRelativePath($users_id, $live_servers_id, $playlists_id_live, $live_index); _error_log('getImage: ' . ("[{$lh['key']}, {$lh['live_servers_id']}]") . ' is live and ready'); } else { if (self::isKeyLiveInStats($lh['key'], $lh['live_servers_id'])) { _error_log('getImage: ' . ("[{$lh['key']}, {$lh['live_servers_id']}]") . ' key is in the stats'); return self::getPosterImage($users_id, $live_servers_id, $live_index); } else { _error_log('getImage: ' . ("[{$lh['key']}, {$lh['live_servers_id']}]") . ' key is NOT in the stats'); return $poster; } } } public static function getPosterFromKey($key, $live_servers_id, $live_index = '') { $key = self::getLatestKeyFromUser($users_id); } static function getOfflineImage($includeURL = true) { global $global; $img = "plugin/Live/view/Offline.jpg"; if ($includeURL) { $img = "{$global['webSiteRootURL']}{$img}"; } return $img; } static function getOnAirImage($includeURL = true) { global $global; $img = "plugin/Live/view/OnAir.jpg"; if ($includeURL) { $img = "{$global['webSiteRootURL']}{$img}"; } return $img; } public static function _getPosterImage($users_id, $live_servers_id) { $file = "videos/userPhoto/Live/user_{$users_id}_bg_{$live_servers_id}.jpg"; return $file; } public static function _getPosterThumbsImage($users_id, $live_servers_id) { $file = "videos/userPhoto/Live/user_{$users_id}_thumbs_{$live_servers_id}.jpg"; return $file; } public static function on_publish($liveTransmitionHistory_id) { $obj = AVideoPlugin::getDataObject("Live"); if (empty($obj->disableRestream)) { self::restream($liveTransmitionHistory_id); } $lt = new LiveTransmitionHistory($liveTransmitionHistory_id); AVideoPlugin::onLiveStream($lt->getUsers_id(), $lt->getLive_servers_id()); } public static function deleteStatsCache($clearFirstPage = false) { global $getStatsLive, $_getStats, $getStatsObject, $_getStatsNotifications, $__getAVideoCache, $_isLiveFromKey, $_isLiveAndIsReadyFromKey; _error_log_debug("Live::deleteStatsCache"); $tmpDir = ObjectYPT::getCacheDir(); $cacheDir = $tmpDir . "getstats" . DIRECTORY_SEPARATOR; if (isset($live_servers_id)) { $cacheDir .= "live_servers_id_{$live_servers_id}"; $pattern = "/.getStats.{$live_servers_id}.*/i"; ObjectYPT::deleteCachePattern($pattern); } //_error_log("Live::deleteStatsCache [{$cacheDir}]"); rrmdir($cacheDir); exec('rm -R ' . $cacheDir); if (is_dir($cacheDir)) { //_error_log("Live::deleteStatsCache [{$cacheDir}] looks like the cache was not deleted", AVideoLog::$ERROR); exec('rm -R ' . $cacheDir); } else { //_error_log("Live::deleteStatsCache [{$cacheDir}] Success"); } if ($clearFirstPage) { clearCache(true); } isURL200Clear(); unset($__getAVideoCache); unset($getStatsLive); unset($getStatsObject); unset($_getStats); unset($_getStatsNotifications); unset($_isLiveFromKey); unset($_isLiveAndIsReadyFromKey); } public static function getReverseRestreamObject($m3u8, $users_id, $live_servers_id = -1, $forceIndex=false) { if (!isValidURL($m3u8)) { return false; } $obj = new stdClass(); $obj->m3u8 = $m3u8; $obj->restreamerURL = self::getRestreamer($live_servers_id); $obj->restreamsDestinations = array(Live::getRTMPLink($users_id, $forceIndex)); $obj->token = getToken(60); $obj->users_id = $users_id; return $obj; } public static function getRestreamObject($liveTransmitionHistory_id) { if (empty($liveTransmitionHistory_id)) { return false; } $lth = new LiveTransmitionHistory($liveTransmitionHistory_id); if (empty($lth->getKey())) { return false; } $_REQUEST['live_servers_id'] = $lth->getLive_servers_id(); $obj = new stdClass(); $obj->m3u8 = self::getM3U8File($lth->getKey(), true); $obj->restreamerURL = self::getRestreamer($lth->getLive_servers_id()); $obj->restreamsDestinations = array(); $obj->token = getToken(60); $obj->users_id = $lth->getUsers_id(); $rows = Live_restreams::getAllFromUser($lth->getUsers_id()); foreach ($rows as $value) { $value['stream_url'] = rtrim($value['stream_url'], "/") . '/'; $obj->restreamsDestinations[] = "{$value['stream_url']}{$value['stream_key']}"; } return $obj; } public static function reverseRestream($m3u8, $users_id, $live_servers_id = -1, $forceIndex=false) { _error_log("Live:reverseRestream start"); $obj = self::getReverseRestreamObject($m3u8, $users_id, $live_servers_id, $forceIndex); - _error_log("Live:reverseRestream obj " . _json_encode($obj)); + _error_log("Live:reverseRestream obj " . _json_encode($obj)); return self::sendRestream($obj); } public static function restream($liveTransmitionHistory_id) { outputAndContinueInBackground(); $obj = self::getRestreamObject($liveTransmitionHistory_id); return self::sendRestream($obj); } private static function sendRestream($obj) { _error_log("Live:sendRestream start"); try { if (empty($obj)) { _error_log("Live:sendRestream object is empty"); return false; } $data_string = json_encode($obj); _error_log("Live:sendRestream ({$obj->restreamerURL}) {$data_string}"); //open connection $ch = curl_init(); //set the url, number of POST vars, POST data curl_setopt($ch, CURLOPT_URL, $obj->restreamerURL); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_POSTREDIR, 3); curl_setopt($ch, CURLOPT_POST, 1); //curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, array( 'Content-Type: application/json', 'Content-Length: ' . strlen($data_string)) ); $output = curl_exec($ch); curl_close($ch); if (empty($output)) { _error_log('Live:sendRestream ERROR ' . curl_error($ch)); return false; } $json = _json_decode($output); if (empty($output)) { _error_log('Live:sendRestream JSON ERROR ' . $output); return false; } _error_log('Live:sendRestream complete ' . $output); return $json; } catch (Exception $exc) { _error_log("Live:sendRestream " . $exc->getTraceAsString()); return false; } return false; } public static function canStreamWithMeet() { if (!User::canStream()) { return false; } if (!User::canCreateMeet()) { return false; } $mobj = AVideoPlugin::getObjectDataIfEnabled("Meet"); if (empty($mobj)) { return false; } $obj = AVideoPlugin::getObjectDataIfEnabled("Live"); if (!empty($obj->disableMeetCamera)) { return false; } return true; } public function getUploadMenuButton() { global $global; $obj = $this->getDataObject(); if (!empty(!User::canStream())) { return ''; } $buttonTitle = $this->getButtonTitle(); include $global['systemRootPath'] . 'plugin/Live/getUploadMenuButton.php'; } public static function getAllVideos($status = "", $showOnlyLoggedUserVideos = false, $activeUsersOnly = true) { global $global, $config, $advancedCustom; if (AVideoPlugin::isEnabledByName("VideoTags")) { if (!empty($_GET['tags_id']) && empty($videosArrayId)) { TimeLogStart("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})"); $videosArrayId = VideoTags::getAllVideosIdFromTagsId($_GET['tags_id']); TimeLogEnd("video::getAllVideos::getAllVideosIdFromTagsId({$_GET['tags_id']})", __LINE__); } } $status = str_replace("'", "", $status); $sql = "SELECT u.*, v.*, c.iconClass, c.name as category, c.clean_name as clean_category,c.description as category_description, v.created as videoCreation, v.modified as videoModified " . " FROM live_transmitions as v " . " LEFT JOIN categories c ON categories_id = c.id " . " LEFT JOIN users u ON v.users_id = u.id " . " WHERE 1=1 "; if ($showOnlyLoggedUserVideos === true && !Permissions::canModerateVideos()) { $uid = intval(User::getId()); $sql .= " AND v.users_id = '{$uid}'"; } elseif (!empty($showOnlyLoggedUserVideos)) { $uid = intval($showOnlyLoggedUserVideos); $sql .= " AND v.users_id = '{$uid}'"; } elseif (!empty($_GET['channelName'])) { $user = User::getChannelOwner($_GET['channelName']); $uid = intval($user['id']); $sql .= " AND v.users_id = '{$uid}' "; } if ($activeUsersOnly) { $sql .= " AND u.status = 'a' "; } if ($status == "publicOnly") { $sql .= " AND v.public = 1 "; } elseif (!empty($status)) { $sql .= " AND v.`public` = '{$status}'"; } if (!empty($_GET['catName'])) { $catName = $global['mysqli']->real_escape_string($_GET['catName']); $sql .= " AND (c.clean_name = '{$catName}' OR c.parentId IN (SELECT cs.id from categories cs where cs.clean_name = '{$catName}' ))"; } if (!empty($_GET['modified'])) { $_GET['modified'] = str_replace("'", "", $_GET['modified']); $sql .= " AND v.modified >= '{$_GET['modified']}'"; } $sql .= AVideoPlugin::getVideoWhereClause(); if (strpos(strtolower($sql), 'limit') === false) { if (!empty($_GET['limitOnceToOne'])) { $sql .= " LIMIT 1"; unset($_GET['limitOnceToOne']); } else { $_REQUEST['rowCount'] = getRowCount(); if (!empty($_REQUEST['rowCount'])) { $sql .= " LIMIT {$_REQUEST['rowCount']}"; } else { _error_log("getAllVideos without limit " . json_encode(debug_backtrace())); if (empty($global['limitForUnlimitedVideos'])) { $global['limitForUnlimitedVideos'] = 100; } if ($global['limitForUnlimitedVideos'] > 0) { $sql .= " LIMIT {$global['limitForUnlimitedVideos']}"; } } } } //echo $sql;exit; //_error_log("getAllVideos($status, $showOnlyLoggedUserVideos , $ignoreGroup , ". json_encode($videosArrayId).")" . $sql); $res = sqlDAL::readSql($sql); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $videos = array(); if ($res != false) { foreach ($fullData as $row) { $row = cleanUpRowFromDatabase($row); $row['live_servers_id'] = self::getLastServersIdFromUser($row['users_id']); if (empty($otherInfo)) { $otherInfo = array(); $otherInfo['category'] = xss_esc_back($row['category']); $otherInfo['groups'] = UserGroups::getVideoGroups($row['id']); //$otherInfo['title'] = UTF8encode($row['title']); $otherInfo['description'] = UTF8encode($row['description']); $otherInfo['descriptionHTML'] = Video::htmlDescription($otherInfo['description']); $otherInfo['filesize'] = 0; } foreach ($otherInfo as $key => $value) { $row[$key] = $value; } $row['rotation'] = 0; $row['filename'] = ''; $row['type'] = 'live'; $row['duration'] = ''; $row['isWatchLater'] = 0; $row['isFavorite'] = 0; $row['views_count'] = 0; $videos[] = $row; } //$videos = $res->fetch_all(MYSQLI_ASSOC); } else { $videos = false; die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $videos; } static function finishLive($key) { $lh = LiveTransmitionHistory::finish($key); } static function updateVideosUserGroup($videos_id, $key) { $lt = LiveTransmition::keyExists($key); if (!empty($lt)) { $lt = new LiveTransmition($lt['id']); $groups = $lt->getGroups(); if (!empty($groups)) { UserGroups::updateVideoGroups($videos_id, $groups); } } } static function notifySocketStats($callBack = 'socketLiveONCallback', $array = array()) { if (empty($array['stats'])) { $array['stats'] = getStatsNotifications(); } _error_log("NGINX Live::on_publish_socket_notification sendSocketMessageToAll Start"); $socketObj = sendSocketMessageToAll($array, $callBack); _error_log("NGINX Live::on_publish_socket_notification SocketMessageToAll END"); return $socketObj; } static public function getImageType($content) { global $global; if (empty($content)) { return LiveImageType::$UNKNOWN; } $contentLen = strlen($content); if ($contentLen < 255) { // check if it is a file if (file_exists($content)) { $contentLen = strlen(file_get_contents($content)); } } if ($contentLen >= 2095335 && $contentLen <= 2095350) { return LiveImageType::$DEFAULTGIF; } if ($contentLen >= 70805 && $contentLen <= 70810) { return LiveImageType::$ONAIRENCODER; } $filesize = file_get_contents($global['systemRootPath'] . self::getOnAirImage(false)); if ($contentLen === $filesize) { return LiveImageType::$ONAIR; } $filesize = file_get_contents($global['systemRootPath'] . self::getOfflineImage(false)); if ($contentLen === $filesize) { return LiveImageType::$OFFLINE; } //_error_log('getImageType: is not defined yet ('.$contentLen.')'); return LiveImageType::$LIVE; } static function isLiveImage($content) { return self::getImageType($content) === LiveImageType::$LIVE; } static function isDefaultImage($content) { $type = self::getImageType($content); return $type === LiveImageType::$ONAIRENCODER || $type === LiveImageType::$ONAIR || $type === LiveImageType::$OFFLINE || $type === LiveImageType::$DEFAULTGIF; } static function iskeyOnline($key) { $stats = getStatsNotifications(); foreach ($stats["applications"] as $value) { if (empty($value['key'])) { continue; } if (preg_match('/' . $key . '/', $value['key'])) { return true; } } return false; } static function getValidNotOnlineLiveIndex($key, $live_index) { if (empty($live_index)) { return 1; } if (!Live::iskeyOnline("{$key}-{$live_index}")) { return $live_index; } else { if (is_numeric($live_index)) { return self::getValidNotOnlineLiveIndex($key, ++$live_index); } else { return self::getValidNotOnlineLiveIndex($key, $live_index . 'New'); } } } static function getLatestValidNotOnlineLiveIndex($key) { $live_index = LiveTransmitionHistory::getLatestIndexFromKey($key); $live_index = self::getValidNotOnlineLiveIndex($key, $live_index); return $live_index; } static function getLivesOnlineFromKey($key) { global $_getLivesOnlineFromKey; if (!isset($_getLivesOnlineFromKey)) { $_getLivesOnlineFromKey = array(); } if (!isset($_getLivesOnlineFromKey[$key])) { $stats = getStatsNotifications(); $_getLivesOnlineFromKey[$key] = array(); foreach ($stats["applications"] as $value) { if (empty($value['key'])) { continue; } if (preg_match('/' . $key . '/', $value['key'])) { $_getLivesOnlineFromKey[$key][] = $value; } } } return $_getLivesOnlineFromKey[$key]; } static function getFirstLiveOnlineFromKey($key) { $onliveApplications = self::getLivesOnlineFromKey($key); if (!empty($onliveApplications[0])) { return $onliveApplications[0]; } return false; } static function getUserHash($users_id) { return encryptString(_json_encode(array('users_id' => $users_id, 'time' => time()))); } static function decryptHash($hash) { $string = decryptString($hash); $json = _json_decode($string); return object_to_array($json); } } class LiveImageType { static $UNKNOWN = 'unknown'; static $OFFLINE = 'offline'; static $ONAIR = 'onair'; static $ONAIRENCODER = 'onair_encoder'; static $DEFAULTGIF = 'defaultgif'; static $LIVE = 'live'; } class LiveStreamObject { private $key, $live_servers_id, $live_index, $playlists_id_live; function __construct($key, $live_servers_id = 0, $live_index = 0, $playlists_id_live = 0) { $this->key = $key; $this->live_servers_id = intval($live_servers_id); $this->live_index = $live_index; $this->playlists_id_live = intval($playlists_id_live); $parts = Live::getLiveParametersFromKey($this->key); $objLive = AVideoPlugin::getDataObject("Live"); if (empty($live_servers_id) && !empty($objLive->useLiveServers)) { $live_servers_id = Live::getLiveServersIdRequest(); } if (empty($this->live_index)) { // check if the index is on the key already if (!empty($parts['live_index'])) { $this->live_index = $parts['live_index']; } else if (!empty($_REQUEST['live_index'])) { $this->live_index = $_REQUEST['live_index']; } } $this->key = $parts['cleanKey']; $this->live_index = preg_replace('/[^0-9a-z]/i', '', $this->live_index); } function getKey() { return $this->key; } function getKeyWithIndex($forceIndexIfEnabled = false, $allowOnlineIndex = false) { - if ($forceIndexIfEnabled) { - $objLive = AVideoPlugin::getDataObject("Live"); - if (!empty($objLive->allowMultipleLivesPerUser)) { - if (empty($allowOnlineIndex)) { - $this->live_index = Live::getLatestValidNotOnlineLiveIndex($this->key); - } else { - $this->live_index = LiveTransmitionHistory::getLatestIndexFromKey($this->key); + if (!empty($forceIndexIfEnabled)) { + if(is_string($forceIndexIfEnabled)){ + $this->live_index = $forceIndexIfEnabled; + }else{ + $objLive = AVideoPlugin::getDataObject("Live"); + if (!empty($objLive->allowMultipleLivesPerUser)) { + if (empty($allowOnlineIndex)) { + $this->live_index = Live::getLatestValidNotOnlineLiveIndex($this->key); + } else { + $this->live_index = LiveTransmitionHistory::getLatestIndexFromKey($this->key); + } } } + } return Live::getLiveKeyFromRequest($this->key, $this->live_index, $this->playlists_id_live); } function getLive_servers_id() { return $this->live_servers_id; } function getLive_index() { return $this->live_index; } function getPlaylists_id_live() { return $this->playlists_id_live; } function getURL() { global $global; $lt = LiveTransmition::getFromKey($this->key); if (empty($lt)) { return false; } $user = new User($lt['users_id']); $channelName = $user->getChannelName(); if (empty($channelName)) { return false; } $url = "{$global['webSiteRootURL']}live/{$this->live_servers_id}/" . urlencode($channelName); if (!empty($this->live_index)) { $url .= '/' . urlencode($this->live_index); } if (!empty($this->playlists_id_live)) { $url = addQueryStringParameter($url, 'playlists_id_live', $this->playlists_id_live); } return $url; } function getURLEmbed() { $url = $this->getURL(); return addQueryStringParameter($url, 'embed', 1); } function getM3U8($doNotProtect = false, $allowOnlineIndex = false) { global $global; $o = AVideoPlugin::getObjectData("Live"); $playerServer = Live::getPlayerServer(); if (!empty($this->live_servers_id)) { $liveServer = new Live_servers($this->live_servers_id); if ($liveServer->getStats_url()) { $o->protectLive = $liveServer->getProtectLive(); $o->useAadaptiveMode = $liveServer->getUseAadaptiveMode(); } } $uuid = $this->getKeyWithIndex(false, $allowOnlineIndex); $playerServer = addLastSlash($playerServer); if ($o->protectLive && empty($doNotProtect)) { return "{$global['webSiteRootURL']}plugin/Live/m3u8.php?live_servers_id={$this->live_servers_id}&uuid=" . encryptString($uuid); } else if ($o->useAadaptiveMode) { return $playerServer . "{$uuid}.m3u8"; } else { return $playerServer . "{$uuid}/index.m3u8"; } } function getOnlineM3U8($users_id, $doNotProtect = false) { $li = $this->live_index; if (empty($this->live_index)) { $online = Live::getFirstLiveOnlineFromKey($this->key); if (!empty($online)) { $parameters = Live::getLiveParametersFromKey($online['key']); //var_dump($parameters, $this->live_index, $li, $online);exit; } else { $key = Live::getLatestKeyFromUser($users_id); $parameters = Live::getLiveParametersFromKey($key); } $this->live_index = $parameters['live_index']; } $m3u8 = $this->getM3U8($doNotProtect, true); $this->live_index = $li; return $m3u8; } - function getRTMPLink() { - return $this->getRTMPLinkWithOutKey() . $this->getKeyWithIndex(true); + function getRTMPLink($forceIndex=false) { + $key = $this->getKeyWithIndex(true); + if (!empty($forceIndex)) { + // make sure the key is unique + $parts = explode('-', $key); + $key = $parts[0] . "-{$forceIndex}"; + } + $url = $this->getRTMPLinkWithOutKey() . $key; + _error_log("getRTMPLink: {$url}"); + return $url; } function getRTMPLinkWithOutKey() { $lt = LiveTransmition::getFromKey($this->key); $user = new User($lt['users_id']); $obj = new stdClass(); $obj->users_id = $lt['users_id']; $obj->key = $this->key; $encrypt = encryptString($obj); return Live::getServer() . "?e={$encrypt}/"; } } diff --git a/plugin/Live/Objects/LiveTransmitionHistory.php b/plugin/Live/Objects/LiveTransmitionHistory.php index fd96f7a50..b11e3d221 100644 --- a/plugin/Live/Objects/LiveTransmitionHistory.php +++ b/plugin/Live/Objects/LiveTransmitionHistory.php @@ -1,441 +1,453 @@ id; } function getTitle() { return $this->title; } function getDescription() { return $this->description; } function getKey() { return $this->key; } function getCreated() { return $this->created; } function getModified() { return $this->modified; } function getUsers_id() { return $this->users_id; } function setId($id) { $this->id = $id; } function getFinished() { return $this->finished; } function setTitle($title) { global $global; $title = $global['mysqli']->real_escape_string($title); $this->title = $title; } function setDescription($description) { global $global; $description = $global['mysqli']->real_escape_string($description); $this->description = $description; } function setKey($key) { $this->key = $key; } function setCreated($created) { $this->created = $created; } function setModified($modified) { $this->modified = $modified; } function setUsers_id($users_id) { $this->users_id = $users_id; } function getLive_servers_id() { return intval($this->live_servers_id); } function getLive_index() { if(empty($this->key)){ return ''; } $parameters = Live::getLiveParametersFromKey($this->key); return $parameters['live_index']; } function getLive_cleanKey() { if(empty($this->key)){ return ''; } $parameters = Live::getLiveParametersFromKey($this->key); return $parameters['cleanKey']; } static function getApplicationObject($liveTransmitionHistory_id) { global $global; $lth = new LiveTransmitionHistory($liveTransmitionHistory_id); $lt = LiveTransmition::getFromDbByUser($lth->getUsers_id()); $liveUsersEnabled = AVideoPlugin::isEnabledByName("LiveUsers"); $p = AVideoPlugin::loadPlugin("Live"); $obj = new stdClass(); $users_id = $lth->getUsers_id(); $u = new User($users_id); $live_servers_id = $lth->getLive_servers_id(); if(empty($live_servers_id) && !empty($_REQUEST['live_servers_id'])){ $live_servers_id = $_REQUEST['live_servers_id']; } $key = $lth->getKey(); $title = $lth->getTitle(); $photo = $u->getPhotoDB(); $m3u8 = Live::getM3U8File($key); $playlists_id_live = 0; if (preg_match("/.*_([0-9]+)/", $key, $matches)) { if (!empty($matches[1])) { $_REQUEST['playlists_id_live'] = intval($matches[1]); $playlists_id_live = $_REQUEST['playlists_id_live']; $photo = PlayLists::getImage($_REQUEST['playlists_id_live']); $title = PlayLists::getNameOrSerieTitle($_REQUEST['playlists_id_live']); } } $obj->UserPhoto = $u->getPhotoDB(); $obj->isAdaptive = Live::isAdaptive($key); $obj->photo = $photo; $obj->channelName = $u->getChannelName(); $obj->live_index = $lth->getLive_index(); $obj->live_cleanKey = $lth->getLive_cleanKey(); $obj->live_servers_id = $live_servers_id; $obj->href = Live::getLinkToLiveFromUsers_idAndLiveServer($users_id, $live_servers_id, $obj->live_index); $obj->key = $key; $obj->isPrivate = Live::isAPrivateLiveFromLiveKey($obj->key); $obj->link = addQueryStringParameter($obj->href, 'embed', 1); $obj->name = $u->getNameIdentificationBd(); $obj->playlists_id_live = $playlists_id_live; $obj->poster = $p->getLivePosterImage($users_id, $live_servers_id, $playlists_id_live, $lth->getLive_index()); $obj->imgGif = $p->getLivePosterImage($users_id, $live_servers_id, $playlists_id_live, $lth->getLive_index(), 'webp'); $obj->title = $title; $obj->user = $u->getUser(); $obj->categories_id = intval($lt['categories_id']); $obj->className = "live_{$obj->live_servers_id}_{$obj->key}"; $users = false; if ($liveUsersEnabled) { $filename = $global['systemRootPath'] . 'plugin/LiveUsers/Objects/LiveOnlineUsers.php'; if (file_exists($filename)) { require_once $filename; $liveUsers = new LiveOnlineUsers(0); $users = $liveUsers->getUsersFromTransmitionKey($key, $live_servers_id); } } $obj->users = $users; $obj->m3u8 =$m3u8; $obj->isURL200 = isURL200($m3u8); $obj->users_id = $users_id; return $obj; } static function getStatsAndAddApplication($liveTransmitionHistory_id) { $stats = getStatsNotifications(); $lth = new LiveTransmitionHistory($liveTransmitionHistory_id); $key = $lth->getKey(); if(!empty($stats['applications'])){ foreach ($stats['applications'] as $value) { if(empty($value['key'])){ continue; } $value = object_to_array($value); $value['key']= self::getCleankeyName($value['key']); if(!empty($value['key']) && $value['key']==$key){ // application is already in the list return $stats; } } } if(!empty($stats['hidden_applications'])){ foreach ($stats['hidden_applications'] as $value) { if(empty($value['key'])){ continue; } $value = object_to_array($value); $value['key']= self::getCleankeyName($value['key']); if($value['key']==$key){ // application is already in the list return $stats; } } } $application = self::getApplicationObject($liveTransmitionHistory_id); if ($application->isPrivate) { $stats['hidden_applications'][] = $application; } else { $stats['applications'][] = $application; } $stats['countLiveStream']++; $cacheName = "getStats" . DIRECTORY_SEPARATOR . "getStatsNotifications"; $cache = ObjectYPT::setCache($cacheName, $stats); // update the cache //_error_log("NGINX getStatsAndAddApplication ". json_encode($stats)); //_error_log("NGINX getStatsAndAddApplication ". json_encode($cache)); return $stats; } static function getCleankeyName($key){ $parts = explode("_", $key); if(!empty($parts[1])){ $adaptive = array('hi', 'low', 'mid'); if(in_array($parts[1], $adaptive)){ return $parts[0]; } } return $key; } static function getStatsAndRemoveApplication($liveTransmitionHistory_id) { $stats = getStatsNotifications(); $lth = new LiveTransmitionHistory($liveTransmitionHistory_id); $key = $lth->getKey(); foreach ($stats['applications'] as $k => $value) { $value = object_to_array($value); if(!empty($value['key']) && $value['key']==$key){ // application is already in the list unset($stats['applications'][$k]); $stats['countLiveStream']--; } } if(empty($stats['hidden_applications'])){ $stats['hidden_applications'] = array(); }else{ foreach ($stats['hidden_applications'] as $k => $value) { $value = object_to_array($value); if($value['key']==$key){ // application is already in the list unset($stats['hidden_applications'][$k]); } } } $cacheName = "getStats" . DIRECTORY_SEPARATOR . "getStatsNotifications"; $cache = ObjectYPT::setCache($cacheName, $stats); // update the cache return $stats; } function setLive_servers_id($live_servers_id) { $this->live_servers_id = intval($live_servers_id); } static function getAllFromUser($users_id) { global $global; $sql = "SELECT * FROM " . static::getTableName() . " WHERE users_id = ? "; $sql .= self::getSqlFromPost(); $res = sqlDAL::readSql($sql, "i", array($users_id)); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $rows = array(); if ($res != false) { foreach ($fullData as $row) { $log = LiveTransmitionHistoryLog::getAllFromHistory($row['id']); $row['totalUsers'] = count($log); $rows[] = $row; } } else { die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $rows; } static function getLatest($key, $live_servers_id=null) { global $global; - $sql = "SELECT * FROM " . static::getTableName() . " WHERE `key` = ? "; + + $key = $global['mysqli']->real_escape_string($key); + + if(empty($key)){ + return false; + } + + $sql = "SELECT * FROM " . static::getTableName() . " WHERE `key` LIKE '{$key}%' "; if(isset($live_servers_id)){ - $sql .= " AND live_servers_id = ".intval($live_servers_id); + $sql .= " AND (live_servers_id = ".intval($live_servers_id); + + if(empty($live_servers_id)){ + $sql .= " OR live_servers_id IS NULL "; + } + $sql .= " )"; } $sql .= " ORDER BY created DESC LIMIT 1"; - // I had to add this because the about from customize plugin was not loading on the about page http://127.0.0.1/AVideo/about + //var_dump($sql, $key);exit; - $res = sqlDAL::readSql($sql, "s", array($key)); + $res = sqlDAL::readSql($sql); $data = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { $row = $data; } else { $row = false; } return $row; } static function finish($key) { $row = self::getLatest($key); if(empty($row) || empty($row['id']) || !empty($row['finished'])){ return false; } return self::finishFromTransmitionHistoryId($row['id']); } static function finishFromTransmitionHistoryId($live_transmitions_history_id) { $live_transmitions_history_id = intval($live_transmitions_history_id); if(empty($live_transmitions_history_id)){ return false; } $sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE id = {$live_transmitions_history_id} "; $insert_row = sqlDAL::writeSql($sql); return $insert_row; } static function getLatestFromUser($users_id) { $rows = self::getLastsLiveHistoriesFromUser($users_id, 1); return @$rows[0]; } static function getLatestFromKey($key) { global $global; $parts = Live::getLiveParametersFromKey($key); $key = $parts['cleanKey']; $sql = "SELECT * FROM " . static::getTableName() . " WHERE `key` LIKE '{$key}%' "; $sql .= " ORDER BY created DESC LIMIT 1"; $res = sqlDAL::readSql($sql); $data = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { $row = $data; } else { $row = false; } return $row; } static function getLatestIndexFromKey($key) { $row = self::getLatestFromKey($key); return Live::getLiveIndexFromKey(@$row['key']); } static function getLastsLiveHistoriesFromUser($users_id, $count=10) { global $global; $sql = "SELECT * FROM " . static::getTableName() . " WHERE `users_id` = ? ORDER BY created DESC LIMIT ?"; $res = sqlDAL::readSql($sql, "ii", array($users_id, $count)); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $rows = array(); if ($res != false) { foreach ($fullData as $row) { $log = LiveTransmitionHistoryLog::getAllFromHistory($row['id']); $row['totalUsers'] = count($log); $rows[] = $row; } } else { die($sql . '\nError : (' . $global['mysqli']->errno . ') ' . $global['mysqli']->error); } return $rows; } static function getActiveLiveFromUser($users_id, $live_servers_id='', $key='') { global $global; $sql = "SELECT * FROM " . static::getTableName() . " WHERE finished IS NULL "; $formats = ""; $values = array(); if(!empty($users_id)){ $sql .= ' AND `users_id` = ? '; $formats .= "i"; $values[] = $users_id; } if(!empty($live_servers_id)){ $sql .= ' AND `live_servers_id` = ? '; $formats .= "i"; $values[] = $live_servers_id; } if(!empty($key)){ $sql .= ' AND `key` = ? '; $formats .= "s"; $values[] = $key; } $sql .= " ORDER BY created DESC LIMIT 1"; $res = sqlDAL::readSql($sql, $formats, $values); $data = sqlDAL::fetchAssoc($res); sqlDAL::close($res); if ($res) { $row = $data; } else { $row = false; } if(empty($row)){ _error_log('LiveTransmitionHistory::getActiveLiveFromUser: '.$sql); } return $row; } public function save() { if (empty($this->live_servers_id)) { $this->live_servers_id = 'NULL'; } return parent::save(); } static function deleteAllFromLiveServer($live_servers_id) { global $global; $live_servers_id = intval($live_servers_id); if (!empty($live_servers_id)) { global $global; $sql = "SELECT id FROM " . static::getTableName() . " WHERE live_servers_id = ? "; $sql .= self::getSqlFromPost(); $res = sqlDAL::readSql($sql, "i", array($live_servers_id)); $fullData = sqlDAL::fetchAllAssoc($res); sqlDAL::close($res); $rows = array(); if ($res != false) { foreach ($fullData as $row) { $lt = new LiveTransmitionHistory($row['id']); $lt->delete(); } } } } public function delete() { if (!empty($this->id)) { LiveTransmitionHistoryLog::deleteAllFromHistory($this->id); } return parent::delete(); } } \ No newline at end of file diff --git a/plugin/Live/view/liveVideo.php b/plugin/Live/view/liveVideo.php index 6ee90803b..3b1f0eca8 100644 --- a/plugin/Live/view/liveVideo.php +++ b/plugin/Live/view/liveVideo.php @@ -1,27 +1,27 @@ - + '; $htmlMediaTag .= getLiveUsersLabelHTML(); echo PlayerSkins::getMediaTag(false, $htmlMediaTag); ?> diff --git a/plugin/Live/view/videoEmbeded.php b/plugin/Live/view/videoEmbeded.php index 060767e57..8c5c43714 100644 --- a/plugin/Live/view/videoEmbeded.php +++ b/plugin/Live/view/videoEmbeded.php @@ -1,114 +1,115 @@ verifyEmbedSecurity(); } $u = new User(0, $_GET['u'], false); $user_id = $u->getBdId(); $video['users_id'] = $user_id; AVideoPlugin::getModeYouTubeLive($user_id); $_REQUEST['live_servers_id'] = Live::getLiveServersIdRequest(); $poster = Live::getPosterImage($livet['users_id'], $_REQUEST['live_servers_id']); ?> <?php echo $config->getWebSiteTitle(); ?> - +
    - + + diff --git a/plugin/Live/webRTC.css b/plugin/Live/webRTC.css new file mode 100644 index 000000000..054bec590 --- /dev/null +++ b/plugin/Live/webRTC.css @@ -0,0 +1,24 @@ + +#webRTCDisconnect, #webRTCPleaseWait, #liveControls{ + display: none; +} + +body.webRTCPleaseWait #webRTCDisconnect, +body.webRTCPleaseWait #webRTCConnect { + display: none; +} + +body.webRTCPleaseWait #webRTCPleaseWait { + display: block; +} + +body.webRTCisLive #webRTCPleaseWait, +body.webRTCisLive #webRTCConnect{ + display: none; +} + +body.webRTCisLive #webRTCDisconnect, +body.webRTCisLive #liveControls { + display: block; +} + diff --git a/plugin/Live/webRTC.js b/plugin/Live/webRTC.js index bc462ea14..64d25a067 100644 --- a/plugin/Live/webRTC.js +++ b/plugin/Live/webRTC.js @@ -1,59 +1,86 @@ window.addEventListener('message', event => { if (event.data.startLiveRestream) { startLiveRestream(event.data.m3u8, forceIndex); }else if (event.data.showPleaseWait) { modal.showPleaseWait(); }else if (event.data.hidePleaseWait) { modal.hidePleaseWait(); }else if (event.data.webRTCModalConfig) { console.log('event.data.webRTCModalConfig', event.data.webRTCModalConfig, typeof webRTCModalConfigShow); if(event.data.webRTCModalConfig==1){ if(typeof webRTCModalConfigShow =='function'){ webRTCModalConfigShow(); } }else{ if(typeof webRTCModalConfigHide =='function'){ webRTCModalConfigHide(); } } } }); function startLiveRestream(m3u8, forceIndex) { console.log('WebRTCLiveCam: startLiveRestream', m3u8, forceIndex); modal.showPleaseWait(); $.ajax({ url: webSiteRootURL + '/plugin/Live/webRTCToLive.json.php', method: 'POST', data: { 'm3u8': m3u8, 'live_servers_id': live_servers_id, 'forceIndex': forceIndex }, success: function (response) { if (response.error) { webRTCDisconnect(); avideoAlertError(response.msg); } else { avideoToastSuccess(response.msg); //document.querySelector("iframe").contentWindow.postMessage({setLiveStart: 1}, "*"); } modal.hidePleaseWait(); } }); } function webRTCConnect() { modal.showPleaseWait(); document.querySelector("iframe").contentWindow.postMessage({setLiveStart: 1}, "*"); + webRTCPleaseWaitShow(); } function webRTCDisconnect() { document.querySelector("iframe").contentWindow.postMessage({setLiveStop: 1}, "*"); + webRTCPleaseWaitHide(); } function webRTCConfiguration() { document.querySelector("iframe").contentWindow.postMessage({setConfiguration: 1}, "*"); +} + +var _webRTCPleaseWaitShowTimeout; +function webRTCPleaseWaitShow(){ + $('body').addClass('webRTCPleaseWait'); + clearTimeout(_webRTCPleaseWaitShowTimeout); + _webRTCPleaseWaitShowTimeout = setTimeout(function(){ + avideoToastError('Live error') + webRTCPleaseWaitHide(); + },60000); +} + +function webRTCPleaseWaitHide(){ + clearTimeout(_webRTCPleaseWaitShowTimeout); + $('body').removeClass('webRTCPleaseWait'); +} + +function webRTCisLive(){ + $('body').addClass('webRTCisLive'); + webRTCPleaseWaitHide(); +} + +function webRTCisOffline(){ + $('body').removeClass('webRTCisLive'); + webRTCPleaseWaitHide(); } \ No newline at end of file diff --git a/plugin/Live/webRTCToLive.json.php b/plugin/Live/webRTCToLive.json.php index 274cb3e7e..43e0a470b 100644 --- a/plugin/Live/webRTCToLive.json.php +++ b/plugin/Live/webRTCToLive.json.php @@ -1,52 +1,53 @@ error = true; $obj->msg = ""; $obj->response = ""; if (!User::canStream()) { $obj->msg = __("Permition denied"); die(json_encode($obj)); } $live = AVideoPlugin::loadPluginIfEnabled("Live"); require_once './Objects/LiveTransmition.php'; if (empty($live)) { $obj->msg = __("Plugin disabled"); die(json_encode($obj)); } if (!isValidURL($_REQUEST['m3u8'])) { $obj->msg = 'Invalid m3u8'; die(json_encode($obj)); } -_error_log('webRTCToLive: start'); +_error_log('webRTCToLive: start '. json_encode($_REQUEST)); $users_id = User::getId(); $count = 1; + while ($count <= 4) { sleep(10); $count++; if (isURL200($_REQUEST['m3u8'], true)) { break; } else { _error_log('webRTCToLive: wait till 200 ' . $_REQUEST['m3u8']); } -} +} $obj->response = Live::reverseRestream($_REQUEST['m3u8'], $users_id, @$_REQUEST['live_servers_id'], @$_REQUEST['forceIndex']); $obj->error = false; -_error_log('webRTCToLive: complete'); +_error_log('webRTCToLive: complete '. json_encode($obj)); die(json_encode($obj)); diff --git a/plugin/Live/webcamFullscreen.php b/plugin/Live/webcamFullscreen.php index 0fe17fc71..cfbd97cc8 100644 --- a/plugin/Live/webcamFullscreen.php +++ b/plugin/Live/webcamFullscreen.php @@ -1,209 +1,203 @@ webRTC_player; $iframeURL = addQueryStringParameter($iframeURL, 'webSiteRootURL', $global['webSiteRootURL']); $iframeURL = addQueryStringParameter($iframeURL, 'userHash', Live::getUserHash(User::getId())); $chatURL = ''; $chat = AVideoPlugin::loadPluginIfEnabled('Chat2'); if (!empty($chat)) { $chatURL = Chat2::getChatRoomLink(User::getId(), 1, 1, 1, true, 1); if (!empty($_REQUEST['user'])) { $chatURL = addQueryStringParameter($chatURL, 'user', $_REQUEST['user']); } if (!empty($_REQUEST['pass'])) { $chatURL = addQueryStringParameter($chatURL, 'pass', $_REQUEST['pass']); } } $users_id = User::getId(); $trasnmition = LiveTransmition::createTransmitionIfNeed($users_id); $live_servers_id = Live::getCurrentLiveServersId(); -$forceIndex = "Live". date('YmdHis'); +$forceIndex = "Live" . date('YmdHis'); $liveStreamObject = new LiveStreamObject($trasnmition['key'], $live_servers_id, $forceIndex, 0); -$streamName = $liveStreamObject->getKeyWithIndex(true, true); +$streamName = $liveStreamObject->getKeyWithIndex($forceIndex, true); $controls = Live::getAllControlls($streamName); ?> <?php echo $config->getWebSiteTitle(); ?> - + +
    - +
    -