diff --git a/objects/functions.php b/objects/functions.php
index 90f3d74696..703c8a02f3 100644
--- a/objects/functions.php
+++ b/objects/functions.php
@@ -7265,7 +7265,7 @@ function calculateCenterCrop($originalWidth, $originalHeight, $aspectRatio)
return ['newWidth' => intval($newWidth), 'newHeight' => intval($newHeight), 'x' => intval($x), 'y' => intval($y)];
}
-function getTourHelpButton($stepsFileRelativePath, $class = 'btn btn-default')
+function getTourHelpButton($stepsFileRelativePath, $class = 'btn btn-default', $showLabel = true)
{
/*
[
@@ -7279,7 +7279,11 @@ function getTourHelpButton($stepsFileRelativePath, $class = 'btn btn-default')
}
]
*/
- return "";
+ $label = '';
+ if($showLabel){
+ $label = __('Help');
+ }
+ return "";
}
function getInfoButton($info)
diff --git a/plugin/Live/Objects/LiveTransmition.php b/plugin/Live/Objects/LiveTransmition.php
index 7ce54bb871..dce11a3952 100644
--- a/plugin/Live/Objects/LiveTransmition.php
+++ b/plugin/Live/Objects/LiveTransmition.php
@@ -140,7 +140,7 @@ class LiveTransmition extends ObjectYPT {
return true;
}
- public static function getFromDbByUser($user_id, $refreshCache = false) {
+ public static function getFromDbByUser($user_id, $refreshCache = false, $allowOnlineIndex = false) {
global $global;
if (!self::isTableInstalled(static::getTableName())) {
_error_log("Save error, table " . static::getTableName() . " does not exists", AVideoLog::$ERROR);
@@ -162,7 +162,7 @@ class LiveTransmition extends ObjectYPT {
$data['live_servers_id'] = Live::getLiveServersIdRequest();
$liveStreamObject = new LiveStreamObject($data['key'], $data['live_servers_id']);
}
- $data['key_with_index'] = $liveStreamObject->getKeyWithIndex(true);
+ $data['key_with_index'] = $liveStreamObject->getKeyWithIndex(true, $allowOnlineIndex);
$data['live_index'] = $liveStreamObject->getIndex();
$user = $data;
@@ -223,7 +223,7 @@ class LiveTransmition extends ObjectYPT {
return LiveTransmition::getFromDbByUserName($_REQUEST['u']);
} elseif (!empty($_REQUEST['c'])) {
//_error_log('LiveTransmition::getFromRequest line'.__LINE__);
- return LiveTransmition::getFromDbByChannelName($_REQUEST['c']);
+ return LiveTransmition::getFromDbByChannelName($_REQUEST['c'], true);
}
//_error_log('LiveTransmition::getFromRequest line'.__LINE__);
return false;
@@ -249,7 +249,7 @@ class LiveTransmition extends ObjectYPT {
}
}
- public static function getFromDbByChannelName($channelName) {
+ public static function getFromDbByChannelName($channelName, $allowOnlineIndex = false) {
global $global;
_mysql_connect();
$sql = "SELECT * FROM users WHERE channelName = ? LIMIT 1";
@@ -261,7 +261,7 @@ class LiveTransmition extends ObjectYPT {
if (empty($user)) {
return false;
}
- return static::getFromDbByUser($user['id']);
+ return static::getFromDbByUser($user['id'], false, $allowOnlineIndex);
} else {
return false;
}
diff --git a/plugin/Live/Objects/LiveTransmitionHistory.php b/plugin/Live/Objects/LiveTransmitionHistory.php
index 15fc85705a..031b1bbe94 100644
--- a/plugin/Live/Objects/LiveTransmitionHistory.php
+++ b/plugin/Live/Objects/LiveTransmitionHistory.php
@@ -211,7 +211,7 @@ class LiveTransmitionHistory extends ObjectYPT
$users_id = $lth->getUsers_id();
$key = $lth->getKey();
$title = $lth->getTitle();
- $live_servers_id = $lth->getLive_servers_id();
+ $live_servers_id = intval($lth->getLive_servers_id());
$playlists_id_live = 0;
$type = 'LiveObject';
@@ -252,6 +252,7 @@ class LiveTransmitionHistory extends ObjectYPT
$obj = Live::getLiveApplicationModelArray($array);
$obj['key'] = $key;
+ $obj['live_servers_id'] = $live_servers_id;
$obj['live_transmitions_history_id'] = $liveTransmitionHistory_id;
$obj['isPrivate'] = self::isPrivate($liveTransmitionHistory_id);
$obj['isPasswordProtected'] = self::isPasswordProtected($liveTransmitionHistory_id);
@@ -402,7 +403,7 @@ class LiveTransmitionHistory extends ObjectYPT
$sql .= " AND (total_viewers>0 OR (SELECT count(id) FROM live_transmition_history_log WHERE live_transmitions_history_id=lth.id )>0) ";
}
$limit = intval($limit);
- if(!empty($limit)){
+ if (!empty($limit)) {
$sql .= "ORDER BY
CASE
WHEN finished IS NULL THEN 0
@@ -410,7 +411,7 @@ class LiveTransmitionHistory extends ObjectYPT
END,
modified DESC
LIMIT {$limit}";
- }else{
+ } else {
$sql .= self::getSqlFromPost();
}
//echo $sql;exit;
@@ -419,8 +420,8 @@ class LiveTransmitionHistory extends ObjectYPT
sqlDAL::close($res);
$rows = [];
if ($res != false) {
- foreach ($fullData as $row) {
- $row['activeStatus'] = empty($row['finished'])?__('Active'):__('Inactive');
+ foreach ($fullData as $row) {
+ $row['activeStatus'] = empty($row['finished']) ? __('Active') : __('Inactive');
if (empty($row['total_viewers'])) {
$row['total_viewers'] = $row['total_viewers_from_history'];
}
@@ -497,7 +498,7 @@ class LiveTransmitionHistory extends ObjectYPT
$row = $data;
} else {
if (is_int($active)) {
- _error_log("LiveTransmitionHistory::getLatest not found ($key, $live_servers_id, $active, $users_id, $categories_id) ".$sql);
+ _error_log("LiveTransmitionHistory::getLatest not found ($key, $live_servers_id, $active, $users_id, $categories_id) " . $sql);
}
$row = false;
}
@@ -516,7 +517,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function finishFromTransmitionHistoryId($live_transmitions_history_id)
{
- if(isBot(false)){
+ if (isBot(false)) {
return false;
}
global $global;
@@ -529,7 +530,7 @@ class LiveTransmitionHistory extends ObjectYPT
$sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE id = {$live_transmitions_history_id} ";
$insert_row = sqlDAL::writeSql($sql);
- _error_log("LiveTransmitionHistory::finishFromTransmitionHistoryId: live_transmitions_history_id=$live_transmitions_history_id users_id=". User::getId() .' IP='. getRealIpAddr(). ' ' . $_SERVER['HTTP_USER_AGENT'] . ' '. json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
+ _error_log("LiveTransmitionHistory::finishFromTransmitionHistoryId: live_transmitions_history_id=$live_transmitions_history_id users_id=" . User::getId() . ' IP=' . getRealIpAddr() . ' ' . $_SERVER['HTTP_USER_AGENT'] . ' ' . json_encode(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS)));
_mysql_commit();
@@ -557,7 +558,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function unfinishFromTransmitionHistoryId($live_transmitions_history_id)
{
- if(isBot(false)){
+ if (isBot(false)) {
//_error_log("LiveTransmitionHistory::unfinishFromTransmitionHistoryId: isBot ");
return false;
}
@@ -576,7 +577,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function finishALL($olderThan = '')
{
- if(isBot(false)){
+ if (isBot(false)) {
return false;
}
$sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE finished IS NULL ";
@@ -833,7 +834,7 @@ class LiveTransmitionHistory extends ObjectYPT
if (empty($this->id)) {
$activeLive = self::getLatest($this->key, $this->live_servers_id, LiveTransmitionHistory::$reconnectionTimeoutInMinutes);
if (!empty($activeLive)) {
- if($activeLive['key'] == $this->key){
+ if ($activeLive['key'] == $this->key) {
//_error_log("LiveTransmitionHistory::save: active live found $this->key, $this->live_servers_id " . json_encode($activeLive));
foreach ($activeLive as $key => $value) {
if (empty($this->$key)) {
@@ -843,8 +844,8 @@ class LiveTransmitionHistory extends ObjectYPT
}
self::unfinishFromTransmitionHistoryId($activeLive['id']);
$this->finished = null;
- }else{
- // _error_log("LiveTransmitionHistory::save: active live NOT match $this->key, $this->live_servers_id " . _json_encode(array($this->key, $this->live_servers_id, $activeLive)));
+ } else {
+ // _error_log("LiveTransmitionHistory::save: active live NOT match $this->key, $this->live_servers_id " . _json_encode(array($this->key, $this->live_servers_id, $activeLive)));
}
} else {
//_error_log("LiveTransmitionHistory::save: active live NOT found $this->key, $this->live_servers_id " . _json_encode(array($this->key, $this->live_servers_id, $activeLive)));
diff --git a/plugin/Live/index.php b/plugin/Live/index.php
index 30895cf06e..f653adf5a7 100644
--- a/plugin/Live/index.php
+++ b/plugin/Live/index.php
@@ -39,7 +39,7 @@ if (!empty($_GET['u'])) {
$link = addQueryStringParameter($link, 'return_line', $info['return_line']);
//var_dump($link, $info['otherLivesSameUser'][0]);exit;
//var_dump($link,$info['users_id'], $info['otherLivesSameUser']);exit;
- _error_log("Redirecting to {$link} info=".json_encode($info).' $_REQUEST='.json_encode($_REQUEST));
+ _error_log("Redirecting to {$link} info=" . json_encode($info) . ' $_REQUEST=' . json_encode($_REQUEST));
header("Location: {$link}");
exit;
/*
@@ -84,6 +84,7 @@ if (!empty($_GET['users_id']) && User::isAdmin()) {
// if user already have a key
$trasnmition = LiveTransmition::createTransmitionIfNeed($users_id);
+//var_dump($trasnmition);exit;
$getLiveKey = ['key' => $trasnmition['key'], 'live_servers_id' => Live::getLiveServersIdRequest()];
setLiveKey($trasnmition['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']);
if (!empty($_GET['resetKey'])) {
@@ -165,11 +166,11 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
if (User::isAdmin()) {
?>
-
+ ?>
@@ -199,6 +200,9 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
$getLiveKey['live_servers_id'] = $_REQUEST['live_servers_id'];
$getLiveKey['live_index'] = @$_REQUEST['live_index'];
$poster = Live::getPosterImage(User::getId(), $_REQUEST['live_servers_id']);
+
+ $liveStreamObject = new LiveStreamObject($trasnmition['key'], $trasnmition['live_servers_id']);
+ Live::getLiveControls($liveStreamObject->getKeyWithIndex(true,true), $trasnmition['live_servers_id']);
?>
@@ -243,7 +247,7 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
});
$.ajax({
- url: webSiteRootURL+'plugin/Live/saveLive.php',
+ url: webSiteRootURL + 'plugin/Live/saveLive.php',
data: {
"title": $('#title').val(),
"description": $('#description').val(),
diff --git a/plugin/Live/myLiveControls.json b/plugin/Live/myLiveControls.json
new file mode 100644
index 0000000000..32fabdb08f
--- /dev/null
+++ b/plugin/Live/myLiveControls.json
@@ -0,0 +1,14 @@
+[
+ {
+ "element": "#sendViewersControls",
+ "intro": "Welcome to the Viewer Redirect feature! This allows you to send your live viewers to another stream or page when you're ending your broadcast."
+ },
+ {
+ "element": "#promptForUrlBtn",
+ "intro": "First, click this button to select or enter a URL where you want to redirect your viewers. You can choose from a list of active streams or enter a custom URL."
+ },
+ {
+ "element": "#sendViewersButtons",
+ "intro": "When you're ready to redirect your viewers, click this button. Note: This will also stop your live stream."
+ }
+]
diff --git a/plugin/Live/myLiveControls.php b/plugin/Live/myLiveControls.php
new file mode 100644
index 0000000000..5dbb9dfa49
--- /dev/null
+++ b/plugin/Live/myLiveControls.php
@@ -0,0 +1,242 @@
+.{$class} {display: none;}body.{$bodyClass} .{$class} {display: block !important;}body.{$bodyClass} .{$hideClass} {display: none !important;}";
+}
+
+$row = LiveTransmition::keyExists($live_key);
+if(empty($row)){
+ echo '';
+ return;
+}
+if(User::getId() != $row['users_id'] && !User::isAdmin()){
+ echo '';
+ return;
+}
+?>
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugin/Live/sendViewers.json.php b/plugin/Live/sendViewers.json.php
new file mode 100644
index 0000000000..c64a7a0ef6
--- /dev/null
+++ b/plugin/Live/sendViewers.json.php
@@ -0,0 +1,36 @@
+row = $row;
+$obj->viewerUrl = $_REQUEST['viewerUrl'];
+$obj->live_key = $_REQUEST['live_key'];
+$obj->live_servers_id = intval(@$_REQUEST['live_servers_id']);
+
+$obj->sendSocketMessage = sendSocketMessage(array('redirectLive'=>$obj), 'redirectLive', 0);
+
+$obj->msg = '';
+$obj->error = false;
+$obj->dropURL = Live::getDropURL($obj->live_key, $obj->live_servers_id);
+$obj->dropURLResponse = _json_decode(url_get_contents($obj->dropURL));
+
+die(_json_encode($obj));
diff --git a/plugin/Live/standAloneFiles/restreamer.json.php b/plugin/Live/standAloneFiles/restreamer.json.php
index f29d2da87d..f28ebbf7a6 100644
--- a/plugin/Live/standAloneFiles/restreamer.json.php
+++ b/plugin/Live/standAloneFiles/restreamer.json.php
@@ -567,7 +567,7 @@ function startRestream($m3u8, $restreamsDestinations, $logFile, $robj, $tries =
*/
- $FFMPEGcommand = "{$ffmpegBinary} -re -rw_timeout 30000000 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 30 -y -i \"{$m3u8}\" -preset veryfast ";
+ $FFMPEGcommand = "{$ffmpegBinary} -re -rw_timeout 30000000 -reconnect 1 -reconnect_streamed 1 -reconnect_delay_max 30 -y -i \"{$m3u8}\" -preset veryfast ";
$FFMPEGComplement = " -max_muxing_queue_size 1024 "
. '{audioConfig}'
. "-c:v libx264 "
diff --git a/plugin/Live/standAloneFiles/saveDVR.json.php b/plugin/Live/standAloneFiles/saveDVR.json.php
index 3b0ef214e1..27e514115f 100644
--- a/plugin/Live/standAloneFiles/saveDVR.json.php
+++ b/plugin/Live/standAloneFiles/saveDVR.json.php
@@ -1,82 +1,4 @@
= 0; $i--) {
- if (preg_match('/[0-9]+.ts$/', $array[$i])) {
- if ($total) {
- $total--;
- } else {
- unset($array[$i]);
- unset($array[$i - 1]);
- }
- $i--;
- }
- }
-
- $newcontent = implode(PHP_EOL, $array);
- error_log("setLastSegments 2 " . json_encode($newcontent));
- $bytes = file_put_contents($DVRFile, $newcontent);
- error_log("setLastSegments 3 " . $bytes);
-}
-
// this file MUST be on the same directory as getRecordedFile.php
$hls_path = "/HLS/live/"; //update this URL
@@ -250,3 +172,81 @@ if ($return_var !== 0) {
} else {
error_log("saveDVR: Temporary directory removed successfully");
}
+
+
+// Define the copyDirectory function
+function copyDirectory($src, $dst) {
+ if (!file_exists($src)) {
+ error_log("copyDirectory: Source file or directory does not exist: $src");
+ return false;
+ }
+ if (is_dir($src)) {
+ @mkdir($dst, 0777, true);
+ $dir = opendir($src);
+ if (!$dir) {
+ error_log("copyDirectory: Failed to open directory: $src");
+ return false;
+ }
+ while (false !== ($file = readdir($dir))) {
+ if ($file != '.' && $file != '..') {
+ $srcPath = $src . DIRECTORY_SEPARATOR . $file;
+ $dstPath = $dst . DIRECTORY_SEPARATOR . $file;
+ if (is_dir($srcPath)) {
+ if (!copyDirectory($srcPath, $dstPath)) {
+ return false;
+ }
+ } else {
+ if (!copy($srcPath, $dstPath)) {
+ error_log("copyDirectory: Failed to copy file $srcPath to $dstPath");
+ return false;
+ }
+ chmod($dstPath, 0777);
+ }
+ }
+ }
+ closedir($dir);
+ return true;
+ } else {
+ // $src is a file
+ @mkdir(dirname($dst), 0777, true);
+ if (copy($src, $dst)) {
+ chmod($dst, 0777);
+ return true;
+ } else {
+ error_log("copyDirectory: Failed to copy file $src to $dst");
+ return false;
+ }
+ }
+}
+
+function setLastSegments($DVRFile, $total)
+{
+ $parts = explode(DIRECTORY_SEPARATOR, $DVRFile);
+ array_pop($parts);
+ $dir = implode(DIRECTORY_SEPARATOR, $parts) . DIRECTORY_SEPARATOR;
+
+ $text = file_get_contents($DVRFile);
+
+ error_log("setLastSegments 1 $dir $DVRFile, $total " . json_encode($text));
+ if (empty($total)) {
+ return $text;
+ }
+
+ $array = preg_split('/$\R?^/m', $text);
+ for ($i = count($array) - 1; $i >= 0; $i--) {
+ if (preg_match('/[0-9]+.ts$/', $array[$i])) {
+ if ($total) {
+ $total--;
+ } else {
+ unset($array[$i]);
+ unset($array[$i - 1]);
+ }
+ $i--;
+ }
+ }
+
+ $newcontent = implode(PHP_EOL, $array);
+ error_log("setLastSegments 2 " . json_encode($newcontent));
+ $bytes = file_put_contents($DVRFile, $newcontent);
+ error_log("setLastSegments 3 " . $bytes);
+}
diff --git a/plugin/Live/view/live.css b/plugin/Live/view/live.css
index e69de29bb2..402482352f 100644
--- a/plugin/Live/view/live.css
+++ b/plugin/Live/view/live.css
@@ -0,0 +1,23 @@
+
+/* Default state when body does not have IAmOnline or IAmNOTOnline classes */
+.ShowIfIAmOnline, .ShowIfIAmNOTOnline {
+ display: none; /* Hide elements by default */
+}
+
+/* Show elements only if the body has class 'IAmOnline' */
+body.IAmOnline .ShowIfIAmOnline {
+ display: block !important; /* Show the element */
+}
+
+body.IAmOnline .HideIfIAmOnline {
+ display: none !important; /* Hide the element */
+}
+
+/* Show elements only if the body has class 'IAmNOTOnline' */
+body.IAmNOTOnline .ShowIfIAmNOTOnline {
+ display: block !important; /* Show the element */
+}
+
+body.IAmNOTOnline .HideIfIAmNOTOnline {
+ display: none !important; /* Hide the element */
+}
diff --git a/plugin/Live/view/menuRight.php b/plugin/Live/view/menuRight.php
index 63eca55d0d..8f17ed5d9f 100644
--- a/plugin/Live/view/menuRight.php
+++ b/plugin/Live/view/menuRight.php
@@ -79,8 +79,49 @@ if (User::canStream()) {
}, 1000); // give some time to load the new images
}
+ var IAmOnline = false;
+ var my_current_live_key = 0;
+ var my_current_live_servers_id = 0;
+ async function amILive(stats) {
+ IAmOnline = false;
+ for (var i in stats) {
+ if (typeof stats[i] !== 'object') {
+ continue;
+ }
+ var stat = stats[i];
+ console.log('amILive', stat);
+ if (stat.type == 'live' || stat.type == "LiveObject") {
+ if (stat.users_id == my_users_id) {
+ my_current_live_key = stat.key;
+ my_current_live_servers_id = stat.live_servers_id;
+ IAmOnline = true;
+ break;
+ }
+ }
+ }
+ console.log('amILive', IAmOnline, stats);
+ $('body').each(function() {
+ var classes = $(this).attr('class').split(' ').filter(function(c) {
+ return !c.startsWith('body_live_');
+ });
+ $(this).attr('class', classes.join(' '));
+ });
+
+ if (IAmOnline) {
+ $('body').addClass('IAmOnline');
+ $('body').removeClass('IAmNOTOnline');
+ $('body').addClass('body_live_' + my_current_live_servers_id + '_' + my_current_live_key);
+ } else {
+ $('body').removeClass('IAmOnline');
+ $('body').addClass('IAmNOTOnline');
+ live_transmitions_history_id = 0;
+ }
+ }
+
var _processLiveStats_processingNow = 0;
+ var lastProcessLiveStats = [];
async function processLiveStats(response) {
+ lastProcessLiveStats = response;
if (_processLiveStats_processingNow) {
return false;
}
@@ -89,6 +130,8 @@ if (User::canStream()) {
_processLiveStats_processingNow = 0;
}, 200);
if (typeof response !== 'undefined') {
+ console.trace('processApplication add notificationLiveItemRemoveThis');
+ $('.stats_app').addClass('notificationLiveItemRemoveThis');
if (isArray(response)) {
for (var i in response) {
if (typeof response[i] !== 'object') {
@@ -101,6 +144,7 @@ if (User::canStream()) {
//console.log('processLiveStats not array', response);
processApplicationLive(response);
}
+ $('.notificationLiveItemRemoveThis').remove();
if (!response.countLiveStream) {
availableLiveStreamNotFound();
} else {
@@ -109,6 +153,7 @@ if (User::canStream()) {
$('.onlineApplications').text($('#availableLiveStream > div').length);
}
+
setTimeout(function() {
playLiveInFullScreenOnIframe)) {
@@ -154,6 +199,7 @@ if (User::canStream()) {
}
}
+ amILive(response.applications);
if (typeof onlineLabelOnline == 'function' && response.applications.length) {
//console.log('processApplicationLive 1', response.applications, response.applications.length);
for (i = 0; i < response.applications.length; i++) {
@@ -162,7 +208,9 @@ if (User::canStream()) {
return false;
}
processApplication(response.applications[i]);
+ $('#' + response.applications[i].className).removeClass('notificationLiveItemRemoveThis');
if (!response.applications[i].comingsoon) {
+ console.log('processApplicationLive', response.applications[i]);
if (typeof response.applications[i].live_cleanKey !== 'undefined') {
selector = '.liveViewStatusClass_' + response.applications[i].live_cleanKey;
onlineLabelOnline(selector);
@@ -262,7 +310,10 @@ if (User::canStream()) {
////console.log('processApplication remove class .live_' + key);
$('.live_' + key).remove();
}
- if (!$('#' + notificatioID).length) {
+ var selector = '#' + notificatioID;
+ $(selector).removeClass('notificationLiveItemRemoveThis');
+ console.log('processApplication notificatioID ', selector);
+ if (!$(selector).length) {
notificationHTML.attr('id', notificatioID);
if (application.comingsoon) {
//console.log('application.comingsoon 1', application.comingsoon, application.method);
@@ -292,7 +343,10 @@ if (User::canStream()) {
?>
var id = $(html).attr('id').replace(/[&=]/g, '');
- if ($('#' + id).length) {
+ var selector = '#' + id;
+ $(selector).removeClass('notificationLiveItemRemoveThis');
+ console.log('processApplication key ', selector);
+ if ($(selector).length) {
//console.log('processApplication key found', id);
return false;
}
@@ -341,7 +395,7 @@ if (User::canStream()) {
itemsArray.image = application.poster;
itemsArray.title = application.title;
itemsArray.href = application.href;
- itemsArray.element_class = application.className + ' ' + application.type + '_app';
+ itemsArray.element_class = application.className + ' ' + application.type + '_app' + ' stats_app';
itemsArray.element_id = application.className;
itemsArray.icon = 'fas fa-video';
itemsArray.type = 'info';
diff --git a/plugin/Live/view/modeYoutubeLive.php b/plugin/Live/view/modeYoutubeLive.php
index 37d3c2449f..7fb71f70ff 100644
--- a/plugin/Live/view/modeYoutubeLive.php
+++ b/plugin/Live/view/modeYoutubeLive.php
@@ -21,7 +21,7 @@ if (!empty($_GET['c'])) {
}
$livet = LiveTransmition::getFromRequest();
-//var_dump($livet);exit;
+//var_dump($livet, $_REQUEST);exit;
setLiveKey($livet['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']);
Live::checkIfPasswordIsGood($livet['key']);
@@ -212,7 +212,10 @@ $_page->setExtraStyles(
});
});
-
+
setExtraStyles(
-print();
?>
\ No newline at end of file
diff --git a/plugin/Live/view/socket.js b/plugin/Live/view/socket.js
index 155a5e648a..e38dedec22 100644
--- a/plugin/Live/view/socket.js
+++ b/plugin/Live/view/socket.js
@@ -1,6 +1,14 @@
function socketLiveONCallback(json) {
- console.log('socketLiveONCallback', json);
- if(typeof processLiveStats == 'undefined'){
+ if (typeof json === 'string') {
+ try {
+ json = JSON.parse(json);
+ } catch (error) {
+ console.error("Invalid JSON string:", error);
+ return null; // or return the original string if you prefer
+ }
+ }
+ console.log('socketLiveONCallback live plugin', json);
+ if (typeof processLiveStats == 'function') {
processLiveStats(json.stats);
}
var selector = '.live_' + json.live_servers_id + "_" + json.key;
@@ -31,7 +39,15 @@ function socketLiveONCallback(json) {
}
}
function socketLiveOFFCallback(json) {
- console.log('socketLiveOFFCallback', json);
+ if (typeof json === 'string') {
+ try {
+ json = JSON.parse(json);
+ } catch (error) {
+ console.error("Invalid JSON string:", error);
+ return null; // or return the original string if you prefer
+ }
+ }
+ console.log('socketLiveOFFCallback live socket', json);
var selector = '.live_' + json.live_servers_id + "_" + json.key;
selector += ', .liveVideo_live_' + json.live_servers_id + "_" + json.key;
selector += ', .live_' + json.key;
@@ -49,11 +65,13 @@ function socketLiveOFFCallback(json) {
}
setTimeout(function () {
//console.log('socketLiveOFFCallback processLiveStats');
- if(typeof processLiveStats == 'undefined'){
+ if (typeof processLiveStats == 'function') {
processLiveStats(json.stats);
}
setTimeout(function () {
- hideExtraVideosIfEmpty();
+ if (typeof hideExtraVideosIfEmpty == 'function') {
+ hideExtraVideosIfEmpty();
+ }
}, 500);
}, 500);
@@ -63,4 +81,64 @@ function socketLiveOFFCallback(json) {
if (typeof updateUserNotificationCount == 'function') {
updateUserNotificationCount();
}
-}
\ No newline at end of file
+}
+
+function redirectLive(json, countdown = 15) {
+ if (typeof json === 'string') {
+ try {
+ json = JSON.parse(json);
+ } catch (error) {
+ console.error("Invalid JSON string:", error);
+ return null;
+ }
+ }
+
+ var viewerUrl = json.redirectLive && json.redirectLive.viewerUrl;
+ if (!viewerUrl) {
+ console.error("Viewer URL not found.");
+ return;
+ }
+
+ var countdownInterval;
+ var initialCountdown = countdown;
+
+ // Function to handle the redirection
+ function redirectToUrl(url) {
+ window.location.href = url;
+ }
+
+ // Function to update the progress bar and auto-redirect
+ function startCountdown() {
+ countdownInterval = setInterval(function () {
+ countdown--;
+
+ // Calculate the progress percentage
+ var progressPercent = ((initialCountdown - countdown) / initialCountdown) * 100;
+
+ // Update the progress bar in the avideoConfirm modal with smooth transition
+ $('#countdownProgressBar').css({
+ 'width': progressPercent + '%',
+ 'transition': 'width 1s linear'
+ });
+
+ if (countdown <= 0) {
+ clearInterval(countdownInterval);
+ redirectToUrl(viewerUrl);
+ }
+ }, 1000);
+ }
+
+ // Use avideoConfirm to ask for user confirmation and include a progress bar
+ avideoConfirm(__("You will be redirected to the following URL:") + "
" + viewerUrl + "
").then(function (confirmed) {
+ if (confirmed) {
+ clearInterval(countdownInterval); // Stop countdown if user confirms
+ redirectToUrl(viewerUrl);
+ } else {
+ clearInterval(countdownInterval); // Stop countdown if user cancels
+ }
+ });
+
+ // Start countdown
+ startCountdown();
+}
+
diff --git a/plugin/Scheduler/watchDog.php b/plugin/Scheduler/watchDog.php
index 9378b673ef..2ffa5d9c28 100644
--- a/plugin/Scheduler/watchDog.php
+++ b/plugin/Scheduler/watchDog.php
@@ -69,8 +69,10 @@ function secureAVideoFolder($folderPath = '/var/www/html/AVideo/videos')
$htaccessVersion = '5.7';
// Define the .htaccess content with updated security rules
- $htaccessContent = "# version $htaccessVersion
-# SQL was required for the clone plugin" . PHP_EOL;
+ $htaccessContent = "# version $htaccessVersion". PHP_EOL;
+ $htaccessContent .= "# SQL was required for the clone plugin" . PHP_EOL;
+ $htaccessContent .= "# generated in ".date('Y-m-d H:i:s') . PHP_EOL;
+
$htaccessContent .= file_get_contents(__DIR__.'/htaccess.sample.txt');
// Path to .htaccess file
$htaccessFile = $folderPath . '/.htaccess';
@@ -81,9 +83,10 @@ function secureAVideoFolder($folderPath = '/var/www/html/AVideo/videos')
// Read the current .htaccess file content
$currentContent = file_get_contents($htaccessFile);
// Check if the version in the file matches the current version
- if (!strpos($currentContent, "# version $htaccessVersion")) {
+ $version = "# version $htaccessVersion";
+ if (strpos($currentContent, $version) === false) {
$updateHtaccess = true;
- _error_log(".htaccess version mismatch. Updating to version $htaccessVersion.\n");
+ _error_log(".htaccess version mismatch $version. Updating to version $htaccessVersion.\n");
} else {
_error_log(".htaccess file is already up-to-date.\n");
}
diff --git a/plugin/UserNotifications/script.js b/plugin/UserNotifications/script.js
index 0736f93917..0a6094ec5d 100644
--- a/plugin/UserNotifications/script.js
+++ b/plugin/UserNotifications/script.js
@@ -37,7 +37,10 @@ function addTemplateFromArray(itemsArray, prepend) {
return false;
}
//console.log('addTemplateFromArray', itemsArray);
+ console.trace('processApplication addTemplateFromArray ', itemsArray);
if (!empty(itemsArray.element_id) && $('#' + (itemsArray.element_id)).length) {
+ var selector = '#' + (itemsArray.element_id);
+ $(selector).removeClass('notificationLiveItemRemoveThis');
return false;
}
var template = getTemplateFromArray(itemsArray);
diff --git a/plugin/YPTSocket/MessageSQLiteV2.php b/plugin/YPTSocket/MessageSQLiteV2.php
index e89890fd2c..833c9ae5ea 100644
--- a/plugin/YPTSocket/MessageSQLiteV2.php
+++ b/plugin/YPTSocket/MessageSQLiteV2.php
@@ -289,6 +289,9 @@ class Message implements MessageComponentInterface {
$this->msgToResourceId($json, $json['resourceId']);
} else if (!empty($json['to_users_id'])) {
$this->msgToUsers_id($json, $json['to_users_id']);
+ } else if (!empty($json['json']['redirectLive'])) {
+ _log_message("onMessage:msgToAllSameLive: " . json_encode($json));
+ $this->msgToAllSameLive($json['json']['redirectLive']['live_key'], $json['json']['redirectLive']['live_servers_id'], $json);
} else {
$this->msgToAll($json);
}
@@ -350,6 +353,7 @@ class Message implements MessageComponentInterface {
unset($msg['webSocketToken']);
}
if (empty($type)) {
+ _log_message("msgToResourceId: empty message type ");
$type = \SocketMessageType::DEFAULT_MESSAGE;
}
@@ -404,7 +408,7 @@ class Message implements MessageComponentInterface {
$obj['mem'] = Message::$mem;
$msgToSend = json_encode($obj);
- //_log_message("msgToResourceId: resourceId=({$resourceId}) {$type} users_id={$obj['users_id']}");
+ _log_message("msgToResourceId: resourceId=({$resourceId}) {$type} users_id={$obj['users_id']}");
$this->clients[$resourceId]->send($msgToSend);
return true;
}
@@ -542,13 +546,17 @@ class Message implements MessageComponentInterface {
$this->msgToArray($msg);
}
+ $live_servers_id = intval($live_servers_id);
+
$rows = dbGetAllResourcesIdFromLive($live_key, $live_servers_id);
$totals = $this->getTotals();
+ _log_message("msgToAllSameLive: {$live_key}_{$live_servers_id} total=".count($rows).' '.json_encode($msg));
foreach ($rows as $value) {
- if($value['isCommandLine']){
+ if(!empty($value['isCommandLine'])){
continue;
}
+ _log_message("msgToAllSameLive: {$value['resourceId']} ");
$this->msgToResourceId($msg, $value['resourceId'], \SocketMessageType::ON_LIVE_MSG, $totals);
}
}
diff --git a/plugin/YPTSocket/YPTSocket.php b/plugin/YPTSocket/YPTSocket.php
index 143b98a878..1cb2391c94 100644
--- a/plugin/YPTSocket/YPTSocket.php
+++ b/plugin/YPTSocket/YPTSocket.php
@@ -47,7 +47,7 @@ class YPTSocket extends PluginAbstract
public static function getServerVersion()
{
- return "6.2";
+ return "7.0";
}
public function updateScript()
diff --git a/plugin/YPTSocket/script.js b/plugin/YPTSocket/script.js
index 2d1a74b6d4..16fafb6219 100644
--- a/plugin/YPTSocket/script.js
+++ b/plugin/YPTSocket/script.js
@@ -9,12 +9,19 @@ var users_id_online = undefined;
var socketConnectRetryTimeout = 15000;
function processSocketJson(json){
+ if (json.type == webSocketTypes.UNDEFINED) {
+ console.log("processSocketJson UNDEFINED", json);
+ if(typeof json.msg === 'object' && typeof json.msg.callback === 'string'){
+ console.log("Socket onmessage UNDEFINED process subobject", json.msg);
+ return processSocketJson(json.msg)
+ }
+ }
if (json.type == webSocketTypes.ON_VIDEO_MSG) {
- console.log("Socket onmessage ON_VIDEO_MSG", json);
+ console.log("processSocketJson ON_VIDEO_MSG", json);
$('.videoUsersOnline, .videoUsersOnline_' + json.videos_id).text(json.total);
}
if (json.type == webSocketTypes.ON_LIVE_MSG && typeof json.is_live !== 'undefined') {
- console.log("Socket onmessage ON_LIVE_MSG", json);
+ console.log("processSocketJson ON_LIVE_MSG", json);
var selector = '#liveViewStatusID_' + json.live_key.key + '_' + json.live_key.live_servers_id;
if (json.is_live) {
onlineLabelOnline(selector);
@@ -23,27 +30,27 @@ function processSocketJson(json){
}
}
if (json.type == webSocketTypes.NEW_CONNECTION) {
- //console.log("Socket onmessage NEW_CONNECTION", json);
+ //console.log("processSocketJson NEW_CONNECTION", json);
if (typeof onUserSocketConnect === 'function') {
onUserSocketConnect(json);
}
} else if (json.type == webSocketTypes.NEW_DISCONNECTION) {
- //console.log("Socket onmessage NEW_DISCONNECTION", json);
+ //console.log("processSocketJson NEW_DISCONNECTION", json);
if (typeof onUserSocketDisconnect === 'function') {
onUserSocketDisconnect(json);
}
} else {
var myfunc;
if (json.callback) {
- //console.log("Socket onmessage json.callback ", json.resourceId, json.callback);
+ //console.log("processSocketJson json.callback ", json.resourceId, json.callback);
var code = "if(typeof " + json.callback + " == 'function'){myfunc = " + json.callback + ";}else{myfunc = defaultCallback;}";
- //console.log(code);
+ console.log('processSocketJson: code='+code);
eval(code);
} else {
- //console.log("onmessage: callback not found", json);
+ //console.log("processSocketJson: callback not found", json);
myfunc = defaultCallback;
}
- //console.log("onmessage: callback ", myfunc, json);
+ //console.log("onmessage: callback ", myfunc, json.msg);
myfunc(json.msg);
}
}
diff --git a/view/css/social.css b/view/css/social.css
index a9ad53298a..2bf8ea8c38 100644
--- a/view/css/social.css
+++ b/view/css/social.css
@@ -112,7 +112,7 @@ ul.social-network li {
/* Define a base class for common styles */
.social-network a, .social-network button{
- border-color: var(--hover-color) !important;
+ border: #FFFFFF55 1px solid;
color: var(--hover-color); /* Change text color on hover */
box-shadow: 0 0 1px 1px var(--hover-color); /* Outer glow effect */
transition: box-shadow 0.3s ease; /* Smooth transition for the glow effect */
diff --git a/view/include/social.php b/view/include/social.php
index ca09dfe4b2..2cefca3d7d 100644
--- a/view/include/social.php
+++ b/view/include/social.php
@@ -2,6 +2,7 @@
global $socialAdded, $global;
$titleSocial = @$title;
$urlShort = @$url;
+
if (empty($video['id']) && !empty(getVideos_id())) {
$video['id'] = getVideos_id();
}
@@ -16,6 +17,19 @@ if (!empty($video['id'])) {
}
}
+if(empty($urlShort)){
+ $live = isLive();
+ if(!empty($live)){
+ $livet = LiveTransmition::getFromRequest();
+ $titleSocial = $livet['title'];
+ $urlShort = Live::getLinkToLiveFromUsers_idAndLiveServer($livet['users_id'], $livet['live_servers_id'], $livet['live_index'], $live['live_schedule'] );
+ }
+ //var_dump($livet['users_id'], $livet['live_servers_id'], $livet['live_index'], $live['live_schedule'] , $urlShort, $titleSocial, $live, $livet, debug_backtrace());exit;
+}
+if(empty($urlShort)){
+ echo '';
+ return;
+}
if (empty($advancedCustom)) {
$advancedCustom = AVideoPlugin::getObjectData("CustomizeAdvanced");
}
@@ -25,6 +39,7 @@ $titleSocial = getSEOTitle($titleSocial);
$urlSocial = urlencode($url);
//set the $urlSocial and the $titleSocial before include this
+
if(!isset($global)){
$global = [];
}
diff --git a/view/js/script.js b/view/js/script.js
index e8e51982ef..ecfa8025b5 100644
--- a/view/js/script.js
+++ b/view/js/script.js
@@ -1307,7 +1307,7 @@ async function avideoConfirmCallBack(msg, confirmCallBackFunction, cancelCallBac
async function avideoConfirm(msg) {
var span = document.createElement("span");
- span.innerHTML = __(msg);
+ span.innerHTML = __(msg, true);
var response = await swal({
title: 'Confrim',
content: span,
@@ -4332,6 +4332,10 @@ function startTour(stepsFileRelativePath) {
// Load Intro.js CSS
$('head').append('');
+ if (isCurrentThemeDark) {
+ $('head').append('');
+ }
+
// Load Intro.js JavaScript
$.getScript(webSiteRootURL + 'node_modules/intro.js/minified/intro.min.js', function () {
loadAndStartTour(stepsFileRelativePath);