1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-03 09:49:28 +02:00

Redirect live stream viewers

This commit is contained in:
Daniel Neto 2024-10-01 10:35:28 -03:00
parent 286d3acdf5
commit ec6a7aed46
21 changed files with 630 additions and 133 deletions

View file

@ -7265,7 +7265,7 @@ function calculateCenterCrop($originalWidth, $originalHeight, $aspectRatio)
return ['newWidth' => intval($newWidth), 'newHeight' => intval($newHeight), 'x' => intval($x), 'y' => intval($y)]; 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 "<button class=\"startTourBtn {$class}\" onclick=\"startTour('{$stepsFileRelativePath}')\"><i class=\"fa-solid fa-circle-question\"></i> " . __('Help') . "</button>"; $label = '';
if($showLabel){
$label = __('Help');
}
return "<button class=\"startTourBtn {$class}\" onclick=\"startTour('{$stepsFileRelativePath}')\"><i class=\"fa-solid fa-circle-question\"></i> {$label}</button>";
} }
function getInfoButton($info) function getInfoButton($info)

View file

@ -140,7 +140,7 @@ class LiveTransmition extends ObjectYPT {
return true; return true;
} }
public static function getFromDbByUser($user_id, $refreshCache = false) { public static function getFromDbByUser($user_id, $refreshCache = false, $allowOnlineIndex = false) {
global $global; global $global;
if (!self::isTableInstalled(static::getTableName())) { if (!self::isTableInstalled(static::getTableName())) {
_error_log("Save error, table " . static::getTableName() . " does not exists", AVideoLog::$ERROR); _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(); $data['live_servers_id'] = Live::getLiveServersIdRequest();
$liveStreamObject = new LiveStreamObject($data['key'], $data['live_servers_id']); $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(); $data['live_index'] = $liveStreamObject->getIndex();
$user = $data; $user = $data;
@ -223,7 +223,7 @@ class LiveTransmition extends ObjectYPT {
return LiveTransmition::getFromDbByUserName($_REQUEST['u']); return LiveTransmition::getFromDbByUserName($_REQUEST['u']);
} elseif (!empty($_REQUEST['c'])) { } elseif (!empty($_REQUEST['c'])) {
//_error_log('LiveTransmition::getFromRequest line'.__LINE__); //_error_log('LiveTransmition::getFromRequest line'.__LINE__);
return LiveTransmition::getFromDbByChannelName($_REQUEST['c']); return LiveTransmition::getFromDbByChannelName($_REQUEST['c'], true);
} }
//_error_log('LiveTransmition::getFromRequest line'.__LINE__); //_error_log('LiveTransmition::getFromRequest line'.__LINE__);
return false; return false;
@ -249,7 +249,7 @@ class LiveTransmition extends ObjectYPT {
} }
} }
public static function getFromDbByChannelName($channelName) { public static function getFromDbByChannelName($channelName, $allowOnlineIndex = false) {
global $global; global $global;
_mysql_connect(); _mysql_connect();
$sql = "SELECT * FROM users WHERE channelName = ? LIMIT 1"; $sql = "SELECT * FROM users WHERE channelName = ? LIMIT 1";
@ -261,7 +261,7 @@ class LiveTransmition extends ObjectYPT {
if (empty($user)) { if (empty($user)) {
return false; return false;
} }
return static::getFromDbByUser($user['id']); return static::getFromDbByUser($user['id'], false, $allowOnlineIndex);
} else { } else {
return false; return false;
} }

View file

@ -211,7 +211,7 @@ class LiveTransmitionHistory extends ObjectYPT
$users_id = $lth->getUsers_id(); $users_id = $lth->getUsers_id();
$key = $lth->getKey(); $key = $lth->getKey();
$title = $lth->getTitle(); $title = $lth->getTitle();
$live_servers_id = $lth->getLive_servers_id(); $live_servers_id = intval($lth->getLive_servers_id());
$playlists_id_live = 0; $playlists_id_live = 0;
$type = 'LiveObject'; $type = 'LiveObject';
@ -252,6 +252,7 @@ class LiveTransmitionHistory extends ObjectYPT
$obj = Live::getLiveApplicationModelArray($array); $obj = Live::getLiveApplicationModelArray($array);
$obj['key'] = $key; $obj['key'] = $key;
$obj['live_servers_id'] = $live_servers_id;
$obj['live_transmitions_history_id'] = $liveTransmitionHistory_id; $obj['live_transmitions_history_id'] = $liveTransmitionHistory_id;
$obj['isPrivate'] = self::isPrivate($liveTransmitionHistory_id); $obj['isPrivate'] = self::isPrivate($liveTransmitionHistory_id);
$obj['isPasswordProtected'] = self::isPasswordProtected($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) "; $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); $limit = intval($limit);
if(!empty($limit)){ if (!empty($limit)) {
$sql .= "ORDER BY $sql .= "ORDER BY
CASE CASE
WHEN finished IS NULL THEN 0 WHEN finished IS NULL THEN 0
@ -410,7 +411,7 @@ class LiveTransmitionHistory extends ObjectYPT
END, END,
modified DESC modified DESC
LIMIT {$limit}"; LIMIT {$limit}";
}else{ } else {
$sql .= self::getSqlFromPost(); $sql .= self::getSqlFromPost();
} }
//echo $sql;exit; //echo $sql;exit;
@ -419,8 +420,8 @@ class LiveTransmitionHistory extends ObjectYPT
sqlDAL::close($res); sqlDAL::close($res);
$rows = []; $rows = [];
if ($res != false) { if ($res != false) {
foreach ($fullData as $row) { foreach ($fullData as $row) {
$row['activeStatus'] = empty($row['finished'])?__('Active'):__('Inactive'); $row['activeStatus'] = empty($row['finished']) ? __('Active') : __('Inactive');
if (empty($row['total_viewers'])) { if (empty($row['total_viewers'])) {
$row['total_viewers'] = $row['total_viewers_from_history']; $row['total_viewers'] = $row['total_viewers_from_history'];
} }
@ -497,7 +498,7 @@ class LiveTransmitionHistory extends ObjectYPT
$row = $data; $row = $data;
} else { } else {
if (is_int($active)) { 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; $row = false;
} }
@ -516,7 +517,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function finishFromTransmitionHistoryId($live_transmitions_history_id) public static function finishFromTransmitionHistoryId($live_transmitions_history_id)
{ {
if(isBot(false)){ if (isBot(false)) {
return false; return false;
} }
global $global; global $global;
@ -529,7 +530,7 @@ class LiveTransmitionHistory extends ObjectYPT
$sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE id = {$live_transmitions_history_id} "; $sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE id = {$live_transmitions_history_id} ";
$insert_row = sqlDAL::writeSql($sql); $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(); _mysql_commit();
@ -557,7 +558,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function unfinishFromTransmitionHistoryId($live_transmitions_history_id) public static function unfinishFromTransmitionHistoryId($live_transmitions_history_id)
{ {
if(isBot(false)){ if (isBot(false)) {
//_error_log("LiveTransmitionHistory::unfinishFromTransmitionHistoryId: isBot "); //_error_log("LiveTransmitionHistory::unfinishFromTransmitionHistoryId: isBot ");
return false; return false;
} }
@ -576,7 +577,7 @@ class LiveTransmitionHistory extends ObjectYPT
public static function finishALL($olderThan = '') public static function finishALL($olderThan = '')
{ {
if(isBot(false)){ if (isBot(false)) {
return false; return false;
} }
$sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE finished IS NULL "; $sql = "UPDATE " . static::getTableName() . " SET finished = now() WHERE finished IS NULL ";
@ -833,7 +834,7 @@ class LiveTransmitionHistory extends ObjectYPT
if (empty($this->id)) { if (empty($this->id)) {
$activeLive = self::getLatest($this->key, $this->live_servers_id, LiveTransmitionHistory::$reconnectionTimeoutInMinutes); $activeLive = self::getLatest($this->key, $this->live_servers_id, LiveTransmitionHistory::$reconnectionTimeoutInMinutes);
if (!empty($activeLive)) { 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)); //_error_log("LiveTransmitionHistory::save: active live found $this->key, $this->live_servers_id " . json_encode($activeLive));
foreach ($activeLive as $key => $value) { foreach ($activeLive as $key => $value) {
if (empty($this->$key)) { if (empty($this->$key)) {
@ -843,8 +844,8 @@ class LiveTransmitionHistory extends ObjectYPT
} }
self::unfinishFromTransmitionHistoryId($activeLive['id']); self::unfinishFromTransmitionHistoryId($activeLive['id']);
$this->finished = null; $this->finished = null;
}else{ } 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))); // _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 { } 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))); //_error_log("LiveTransmitionHistory::save: active live NOT found $this->key, $this->live_servers_id " . _json_encode(array($this->key, $this->live_servers_id, $activeLive)));

View file

@ -39,7 +39,7 @@ if (!empty($_GET['u'])) {
$link = addQueryStringParameter($link, 'return_line', $info['return_line']); $link = addQueryStringParameter($link, 'return_line', $info['return_line']);
//var_dump($link, $info['otherLivesSameUser'][0]);exit; //var_dump($link, $info['otherLivesSameUser'][0]);exit;
//var_dump($link,$info['users_id'], $info['otherLivesSameUser']);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}"); header("Location: {$link}");
exit; exit;
/* /*
@ -84,6 +84,7 @@ if (!empty($_GET['users_id']) && User::isAdmin()) {
// if user already have a key // if user already have a key
$trasnmition = LiveTransmition::createTransmitionIfNeed($users_id); $trasnmition = LiveTransmition::createTransmitionIfNeed($users_id);
//var_dump($trasnmition);exit;
$getLiveKey = ['key' => $trasnmition['key'], 'live_servers_id' => Live::getLiveServersIdRequest()]; $getLiveKey = ['key' => $trasnmition['key'], 'live_servers_id' => Live::getLiveServersIdRequest()];
setLiveKey($trasnmition['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']); setLiveKey($trasnmition['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']);
if (!empty($_GET['resetKey'])) { if (!empty($_GET['resetKey'])) {
@ -165,11 +166,11 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
if (User::isAdmin()) { if (User::isAdmin()) {
?> ?>
<button onclick="avideoModalIframeFullScreen(webSiteRootURL + 'plugin/Live/view/editor.php');" class="btn btn-primary pull-right"><i class="fa fa-edit"></i> Edit Live Servers</button> <button onclick="avideoModalIframeFullScreen(webSiteRootURL + 'plugin/Live/view/editor.php');" class="btn btn-primary pull-right"><i class="fa fa-edit"></i> Edit Live Servers</button>
<?php <?php
} }
} }
if (Live::canStreamWithMeet()) { if (Live::canStreamWithMeet()) {
?> ?>
<button onclick="avideoModalIframeFullScreen(webSiteRootURL + 'plugin/Meet/');" class="btn btn-default pull-right"> <button onclick="avideoModalIframeFullScreen(webSiteRootURL + 'plugin/Meet/');" class="btn btn-default pull-right">
<i class="fas fa-comments"></i> <span class="hidden-md hidden-sm hidden-xs"><?php echo __("Start a Live Stream Meeting"); ?></span><span class="hidden-lg"><?php echo __("Meeting"); ?></span> <i class="fas fa-comments"></i> <span class="hidden-md hidden-sm hidden-xs"><?php echo __("Start a Live Stream Meeting"); ?></span><span class="hidden-lg"><?php echo __("Meeting"); ?></span>
</button> </button>
@ -199,6 +200,9 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
$getLiveKey['live_servers_id'] = $_REQUEST['live_servers_id']; $getLiveKey['live_servers_id'] = $_REQUEST['live_servers_id'];
$getLiveKey['live_index'] = @$_REQUEST['live_index']; $getLiveKey['live_index'] = @$_REQUEST['live_index'];
$poster = Live::getPosterImage(User::getId(), $_REQUEST['live_servers_id']); $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']);
?> ?>
</ul> </ul>
</div> </div>
@ -243,7 +247,7 @@ include $global['systemRootPath'] . 'view/bootstrap/fileinput.php';
}); });
$.ajax({ $.ajax({
url: webSiteRootURL+'plugin/Live/saveLive.php', url: webSiteRootURL + 'plugin/Live/saveLive.php',
data: { data: {
"title": $('#title').val(), "title": $('#title').val(),
"description": $('#description').val(), "description": $('#description').val(),

View file

@ -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."
}
]

View file

@ -0,0 +1,242 @@
<?php
$class = '';
if (!empty($live_key)) {
$bodyClass = "body_live_{$live_servers_id}_{$live_key}";
$class = "ShowIf_{$live_servers_id}_{$live_key}";
$hideClass = "HideIf_{$live_servers_id}_{$live_key}";
echo "<style>.{$class} {display: none;}body.{$bodyClass} .{$class} {display: block !important;}body.{$bodyClass} .{$hideClass} {display: none !important;}</style>";
}
$row = LiveTransmition::keyExists($live_key);
if(empty($row)){
echo '<!-- Live key not found myLiveControls.php -->';
return;
}
if(User::getId() != $row['users_id'] && !User::isAdmin()){
echo '<!-- This live does not belong to you myLiveControls.php -->';
return;
}
?>
<style>
.currentUrlTextContainer{
position: absolute;
right: 5px;
bottom: 1px;
font-size: 0.7em;
}
.currentUrlTextTopContainer{
margin-top: -6px;
margin-bottom: 6px;
}
#sendViewersControls button{
position: relative;
}
</style>
<div class="pull-right" id="sendViewersControls">
<div class="btn-group pull-right " role="group">
<?php
echo getTourHelpButton('plugin/Live/myLiveControls.json', 'btn btn-default', false);
?>
<button id="promptForUrlBtn" onclick="promptForViewerUrl()" class="btn btn-primary">
<i class="fa-solid fa-ellipsis-vertical"></i>
</button>
<div id="sendViewersButtons" style="display: inline-block; ;">
<button id="sendViewersBtn"
onclick="confirmSendViewers()"
class="btn btn-success <?php echo $class; ?> " disabled
style="overflow: hidden;"
data-toggle="tooltip"
title="<?php echo __('Send all viewers from your livestream to the specified URL'); ?>">
<div class="currentUrlTextTopContainer">
<?php echo __("Redirect Viewers"); ?>
<i class="fa-solid fa-diamond-turn-right"></i>
</div>
<!-- Display the current URL -->
<div class="currentUrlTextContainer">
<span class="currentUrlText"><?php echo __("No URL set"); ?></span>
</div>
</button>
<!-- Placeholder content for when the user is not online -->
<button class="btn btn-primary <?php echo $hideClass; ?> " disabled data-toggle="tooltip" title="<?php echo __("Start a live stream to use the controls"); ?>">
<div class="currentUrlTextTopContainer">
<?php echo __("You are not live right now"); ?>
</div>
<!-- Display the current URL -->
<div class="currentUrlTextContainer">
<span class="currentUrlText"><?php echo __("No URL set"); ?></span>
</div>
</button>
</div>
</div>
</div>
<!-- URL Selection Modal -->
<div class="modal fade" id="urlModal" tabindex="-1" role="dialog" aria-labelledby="urlModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-body">
<div class="list-group" id="urlList">
</div>
<hr>
<div class="form-group">
<input type="text" class="form-control" id="customUrl" placeholder="https://example.com/custom">
</div>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-success btn-block" id="saveUrlBtn">
<i class="fas fa-save"></i> <?php echo __('Save'); ?>
</button>
</div>
</div>
</div>
</div>
<script>
var viewerUrl = '';
$(document).ready(function() {
// Disable Send Viewers button initially// Load viewerUrl from the cookie if it exists
if (Cookies.get('viewerUrl')) {
viewerUrl = Cookies.get('viewerUrl');
$('#customUrl').val(viewerUrl); // Update the displayed URL
$('.currentUrlText').text(viewerUrl); // Update the displayed URL
$('#sendViewersBtn').prop('disabled', false); // Enable Send Viewers button if URL is present
}
});
// Function to prompt for the viewer URL and store it
function promptForViewerUrl() {
// Clear previous list
$('#urlList').empty();
// Get all .stats_app elements and populate the modal
$('.stats_app').each(function() {
var url = $(this).find('a').attr('href'); // Get the URL from the anchor tag
var imgSrc = $(this).find('img').attr('src'); // Get the image source
var title = $(this).find('.media-heading').text().trim(); // Get the media heading text
// Create a new list item for each URL
var listItem = `
<button type="button" class="list-group-item list-group-item-action">
<div class="media">
<div class="media-left">
<img src="${imgSrc}" class="media-object" style="width: 50px; height: auto;">
</div>
<div class="media-body">
<strong class="media-heading">${title}</strong>
<p class="media-url">${url}</p>
</div>
</div>
</button>
`;
$('#urlList').append(listItem);
});
// Show the modal
$('#urlModal').modal('show');
// Handle URL list selection
$('#urlList .list-group-item').click(function() {
$('#urlList .list-group-item').removeClass('active');
$(this).addClass('active');
// Get the selected URL and set it to the custom URL input field
var selectedUrl = $(this).find('.media-url').text().trim();
$('#customUrl').val(selectedUrl); // Fill the custom URL input with the selected URL
});
// Handle custom URL input focus
$('#customUrl').on('focus', function() {
$('#urlList .list-group-item').removeClass('active'); // Deselect all list items
});
// Handle Save URL button click
$('#saveUrlBtn').click(function() {
var selectedUrl = $('#urlList .list-group-item.active').find('.media-url').text().trim();
var customUrl = $('#customUrl').val().trim();
// Determine which URL to use
if (customUrl !== '') {
if (!validURL(customUrl)) {
avideoAlertError(__("You need to enter a valid URL!"));
return;
}
viewerUrl = customUrl;
} else if (selectedUrl !== '') {
viewerUrl = selectedUrl;
} else {
avideoAlertError(__("Please select or enter a URL."));
return;
}
// Save viewerUrl to cookie with expiration of 365 days
Cookies.set('viewerUrl', viewerUrl, {
path: '/',
expires: 365
});
// Save and update the UI
console.log("Viewer URL saved:", viewerUrl);
$('#sendViewersBtn').prop('disabled', false); // Enable Send Viewers button
avideoToastSuccess(__("URL saved! Now you can redirect viewers to the specified URL."));
$('.currentUrlText').text(viewerUrl); // Update the displayed URL
// Close the modal
$('#urlModal').modal('hide');
});
}
// Function to confirm before sending viewers
async function confirmSendViewers() {
if (!validURL(viewerUrl)) {
avideoAlertError(__("Invalid URL"));
return;
}
var confirmed = await avideoConfirm(__("Are you sure you want to redirect all viewers to the specified URL? This action will also stop the live stream."));
if (confirmed) {
sendViewers();
}
}
// Function to send viewers to the stored URL
function sendViewers() {
if (empty(my_current_live_key)) {
avideoAlertError(__("Live key not found. It seems your livestream may not be active anymore. Please make sure to redirect viewers before ending the live stream."));
return;
}
if (!validURL(viewerUrl)) {
avideoAlertError(__("Invalid URL"));
return;
}
console.log("Sending viewers to:", viewerUrl);
$.ajax({
url: webSiteRootURL + 'plugin/Live/sendViewers.json.php',
type: 'POST',
data: {
'viewerUrl': viewerUrl,
'live_key': '<?php echo $live_key; ?>',
'live_servers_id': '<?php echo $live_servers_id;?>'
},
success: function(response) {
console.log("Send viewers response:", response);
if (response.error) {
avideoAlertError(response.msg);
} else {
avideoAlertSuccess(__("Viewers sent successfully!"));
// Optionally, disable the button after sending
$('#sendViewersBtn').prop('disabled', true);
}
},
error: function() {
avideoAlertError(__("An error occurred while sending viewers."));
}
});
}
</script>

View file

@ -0,0 +1,36 @@
<?php
require_once dirname(__FILE__) . '/../../videos/configuration.php';
header('Content-Type: application/json');
if(empty($_REQUEST['viewerUrl']) || !isValidURL($_REQUEST['viewerUrl'])){
forbiddenPage('Invalid redirect URL');
}
if(empty($_REQUEST['live_key'])){
forbiddenPage('Invalid live key');
}
$row = LiveTransmition::keyExists($_REQUEST['live_key']);
if(empty($row)){
forbiddenPage('Live key not found');
}
if(User::getId() != $row['users_id'] && !User::isAdmin()){
forbiddenPage('This live does not belong to you');
}
$obj = new stdClass();
$obj->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));

View file

@ -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 " $FFMPEGComplement = " -max_muxing_queue_size 1024 "
. '{audioConfig}' . '{audioConfig}'
. "-c:v libx264 " . "-c:v libx264 "

View file

@ -1,82 +1,4 @@
<?php <?php
// 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);
}
// this file MUST be on the same directory as getRecordedFile.php // this file MUST be on the same directory as getRecordedFile.php
$hls_path = "/HLS/live/"; //update this URL $hls_path = "/HLS/live/"; //update this URL
@ -250,3 +172,81 @@ if ($return_var !== 0) {
} else { } else {
error_log("saveDVR: Temporary directory removed successfully"); 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);
}

View file

@ -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 */
}

View file

@ -79,8 +79,49 @@ if (User::canStream()) {
}, 1000); // give some time to load the new images }, 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 _processLiveStats_processingNow = 0;
var lastProcessLiveStats = [];
async function processLiveStats(response) { async function processLiveStats(response) {
lastProcessLiveStats = response;
if (_processLiveStats_processingNow) { if (_processLiveStats_processingNow) {
return false; return false;
} }
@ -89,6 +130,8 @@ if (User::canStream()) {
_processLiveStats_processingNow = 0; _processLiveStats_processingNow = 0;
}, 200); }, 200);
if (typeof response !== 'undefined') { if (typeof response !== 'undefined') {
console.trace('processApplication add notificationLiveItemRemoveThis');
$('.stats_app').addClass('notificationLiveItemRemoveThis');
if (isArray(response)) { if (isArray(response)) {
for (var i in response) { for (var i in response) {
if (typeof response[i] !== 'object') { if (typeof response[i] !== 'object') {
@ -101,6 +144,7 @@ if (User::canStream()) {
//console.log('processLiveStats not array', response); //console.log('processLiveStats not array', response);
processApplicationLive(response); processApplicationLive(response);
} }
$('.notificationLiveItemRemoveThis').remove();
if (!response.countLiveStream) { if (!response.countLiveStream) {
availableLiveStreamNotFound(); availableLiveStreamNotFound();
} else { } else {
@ -109,6 +153,7 @@ if (User::canStream()) {
$('.onlineApplications').text($('#availableLiveStream > div').length); $('.onlineApplications').text($('#availableLiveStream > div').length);
} }
setTimeout(function() { setTimeout(function() {
<?php <?php
if (!empty($obj->playLiveInFullScreenOnIframe)) { if (!empty($obj->playLiveInFullScreenOnIframe)) {
@ -154,6 +199,7 @@ if (User::canStream()) {
} }
} }
amILive(response.applications);
if (typeof onlineLabelOnline == 'function' && response.applications.length) { if (typeof onlineLabelOnline == 'function' && response.applications.length) {
//console.log('processApplicationLive 1', response.applications, response.applications.length); //console.log('processApplicationLive 1', response.applications, response.applications.length);
for (i = 0; i < response.applications.length; i++) { for (i = 0; i < response.applications.length; i++) {
@ -162,7 +208,9 @@ if (User::canStream()) {
return false; return false;
} }
processApplication(response.applications[i]); processApplication(response.applications[i]);
$('#' + response.applications[i].className).removeClass('notificationLiveItemRemoveThis');
if (!response.applications[i].comingsoon) { if (!response.applications[i].comingsoon) {
console.log('processApplicationLive', response.applications[i]);
if (typeof response.applications[i].live_cleanKey !== 'undefined') { if (typeof response.applications[i].live_cleanKey !== 'undefined') {
selector = '.liveViewStatusClass_' + response.applications[i].live_cleanKey; selector = '.liveViewStatusClass_' + response.applications[i].live_cleanKey;
onlineLabelOnline(selector); onlineLabelOnline(selector);
@ -262,7 +310,10 @@ if (User::canStream()) {
////console.log('processApplication remove class .live_' + key); ////console.log('processApplication remove class .live_' + key);
$('.live_' + key).remove(); $('.live_' + key).remove();
} }
if (!$('#' + notificatioID).length) { var selector = '#' + notificatioID;
$(selector).removeClass('notificationLiveItemRemoveThis');
console.log('processApplication notificatioID ', selector);
if (!$(selector).length) {
notificationHTML.attr('id', notificatioID); notificationHTML.attr('id', notificatioID);
if (application.comingsoon) { if (application.comingsoon) {
//console.log('application.comingsoon 1', application.comingsoon, application.method); //console.log('application.comingsoon 1', application.comingsoon, application.method);
@ -292,7 +343,10 @@ if (User::canStream()) {
?> ?>
var id = $(html).attr('id').replace(/[&=]/g, ''); 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); //console.log('processApplication key found', id);
return false; return false;
} }
@ -341,7 +395,7 @@ if (User::canStream()) {
itemsArray.image = application.poster; itemsArray.image = application.poster;
itemsArray.title = application.title; itemsArray.title = application.title;
itemsArray.href = application.href; 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.element_id = application.className;
itemsArray.icon = 'fas fa-video'; itemsArray.icon = 'fas fa-video';
itemsArray.type = 'info'; itemsArray.type = 'info';

View file

@ -21,7 +21,7 @@ if (!empty($_GET['c'])) {
} }
$livet = LiveTransmition::getFromRequest(); $livet = LiveTransmition::getFromRequest();
//var_dump($livet);exit; //var_dump($livet, $_REQUEST);exit;
setLiveKey($livet['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']); setLiveKey($livet['key'], Live::getLiveServersIdRequest(), @$_REQUEST['live_index']);
Live::checkIfPasswordIsGood($livet['key']); Live::checkIfPasswordIsGood($livet['key']);
@ -212,7 +212,10 @@ $_page->setExtraStyles(
}); });
}); });
</script> </script>
<?php echo AVideoPlugin::getWatchActionButton(0); ?> <?php
echo AVideoPlugin::getWatchActionButton(0);
Live::getLiveControls($livet['key_with_index'], $livet['live_servers_id']);
?>
</div> </div>
</div> </div>
<?php <?php
@ -243,7 +246,5 @@ $_page->setExtraStyles(
<?php <?php
include $global['systemRootPath'] . 'view/include/video.min.js.php'; include $global['systemRootPath'] . 'view/include/video.min.js.php';
echo AVideoPlugin::afterVideoJS(); echo AVideoPlugin::afterVideoJS();
?>
<?php
$_page->print(); $_page->print();
?> ?>

View file

@ -1,6 +1,14 @@
function socketLiveONCallback(json) { function socketLiveONCallback(json) {
console.log('socketLiveONCallback', json); if (typeof json === 'string') {
if(typeof processLiveStats == 'undefined'){ 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); processLiveStats(json.stats);
} }
var selector = '.live_' + json.live_servers_id + "_" + json.key; var selector = '.live_' + json.live_servers_id + "_" + json.key;
@ -31,7 +39,15 @@ function socketLiveONCallback(json) {
} }
} }
function socketLiveOFFCallback(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; var selector = '.live_' + json.live_servers_id + "_" + json.key;
selector += ', .liveVideo_live_' + json.live_servers_id + "_" + json.key; selector += ', .liveVideo_live_' + json.live_servers_id + "_" + json.key;
selector += ', .live_' + json.key; selector += ', .live_' + json.key;
@ -49,11 +65,13 @@ function socketLiveOFFCallback(json) {
} }
setTimeout(function () { setTimeout(function () {
//console.log('socketLiveOFFCallback processLiveStats'); //console.log('socketLiveOFFCallback processLiveStats');
if(typeof processLiveStats == 'undefined'){ if (typeof processLiveStats == 'function') {
processLiveStats(json.stats); processLiveStats(json.stats);
} }
setTimeout(function () { setTimeout(function () {
hideExtraVideosIfEmpty(); if (typeof hideExtraVideosIfEmpty == 'function') {
hideExtraVideosIfEmpty();
}
}, 500); }, 500);
}, 500); }, 500);
@ -63,4 +81,64 @@ function socketLiveOFFCallback(json) {
if (typeof updateUserNotificationCount == 'function') { if (typeof updateUserNotificationCount == 'function') {
updateUserNotificationCount(); updateUserNotificationCount();
} }
} }
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:") + "<br><strong>" + viewerUrl + "</strong><br><div class='progress' style='height: 10px;'><div id='countdownProgressBar' class='progress-bar progress-bar-striped progress-bar-animated' role='progressbar' style='width: 0%;' aria-valuenow='0' aria-valuemin='0' aria-valuemax='100'></div></div>").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();
}

View file

@ -69,8 +69,10 @@ function secureAVideoFolder($folderPath = '/var/www/html/AVideo/videos')
$htaccessVersion = '5.7'; $htaccessVersion = '5.7';
// Define the .htaccess content with updated security rules // Define the .htaccess content with updated security rules
$htaccessContent = "# version $htaccessVersion $htaccessContent = "# version $htaccessVersion". PHP_EOL;
# SQL was required for the clone plugin" . 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'); $htaccessContent .= file_get_contents(__DIR__.'/htaccess.sample.txt');
// Path to .htaccess file // Path to .htaccess file
$htaccessFile = $folderPath . '/.htaccess'; $htaccessFile = $folderPath . '/.htaccess';
@ -81,9 +83,10 @@ function secureAVideoFolder($folderPath = '/var/www/html/AVideo/videos')
// Read the current .htaccess file content // Read the current .htaccess file content
$currentContent = file_get_contents($htaccessFile); $currentContent = file_get_contents($htaccessFile);
// Check if the version in the file matches the current version // 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; $updateHtaccess = true;
_error_log(".htaccess version mismatch. Updating to version $htaccessVersion.\n"); _error_log(".htaccess version mismatch $version. Updating to version $htaccessVersion.\n");
} else { } else {
_error_log(".htaccess file is already up-to-date.\n"); _error_log(".htaccess file is already up-to-date.\n");
} }

View file

@ -37,7 +37,10 @@ function addTemplateFromArray(itemsArray, prepend) {
return false; return false;
} }
//console.log('addTemplateFromArray', itemsArray); //console.log('addTemplateFromArray', itemsArray);
console.trace('processApplication addTemplateFromArray ', itemsArray);
if (!empty(itemsArray.element_id) && $('#' + (itemsArray.element_id)).length) { if (!empty(itemsArray.element_id) && $('#' + (itemsArray.element_id)).length) {
var selector = '#' + (itemsArray.element_id);
$(selector).removeClass('notificationLiveItemRemoveThis');
return false; return false;
} }
var template = getTemplateFromArray(itemsArray); var template = getTemplateFromArray(itemsArray);

View file

@ -289,6 +289,9 @@ class Message implements MessageComponentInterface {
$this->msgToResourceId($json, $json['resourceId']); $this->msgToResourceId($json, $json['resourceId']);
} else if (!empty($json['to_users_id'])) { } else if (!empty($json['to_users_id'])) {
$this->msgToUsers_id($json, $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 { } else {
$this->msgToAll($json); $this->msgToAll($json);
} }
@ -350,6 +353,7 @@ class Message implements MessageComponentInterface {
unset($msg['webSocketToken']); unset($msg['webSocketToken']);
} }
if (empty($type)) { if (empty($type)) {
_log_message("msgToResourceId: empty message type ");
$type = \SocketMessageType::DEFAULT_MESSAGE; $type = \SocketMessageType::DEFAULT_MESSAGE;
} }
@ -404,7 +408,7 @@ class Message implements MessageComponentInterface {
$obj['mem'] = Message::$mem; $obj['mem'] = Message::$mem;
$msgToSend = json_encode($obj); $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); $this->clients[$resourceId]->send($msgToSend);
return true; return true;
} }
@ -542,13 +546,17 @@ class Message implements MessageComponentInterface {
$this->msgToArray($msg); $this->msgToArray($msg);
} }
$live_servers_id = intval($live_servers_id);
$rows = dbGetAllResourcesIdFromLive($live_key, $live_servers_id); $rows = dbGetAllResourcesIdFromLive($live_key, $live_servers_id);
$totals = $this->getTotals(); $totals = $this->getTotals();
_log_message("msgToAllSameLive: {$live_key}_{$live_servers_id} total=".count($rows).' '.json_encode($msg));
foreach ($rows as $value) { foreach ($rows as $value) {
if($value['isCommandLine']){ if(!empty($value['isCommandLine'])){
continue; continue;
} }
_log_message("msgToAllSameLive: {$value['resourceId']} ");
$this->msgToResourceId($msg, $value['resourceId'], \SocketMessageType::ON_LIVE_MSG, $totals); $this->msgToResourceId($msg, $value['resourceId'], \SocketMessageType::ON_LIVE_MSG, $totals);
} }
} }

View file

@ -47,7 +47,7 @@ class YPTSocket extends PluginAbstract
public static function getServerVersion() public static function getServerVersion()
{ {
return "6.2"; return "7.0";
} }
public function updateScript() public function updateScript()

View file

@ -9,12 +9,19 @@ var users_id_online = undefined;
var socketConnectRetryTimeout = 15000; var socketConnectRetryTimeout = 15000;
function processSocketJson(json){ 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) { 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); $('.videoUsersOnline, .videoUsersOnline_' + json.videos_id).text(json.total);
} }
if (json.type == webSocketTypes.ON_LIVE_MSG && typeof json.is_live !== 'undefined') { 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; var selector = '#liveViewStatusID_' + json.live_key.key + '_' + json.live_key.live_servers_id;
if (json.is_live) { if (json.is_live) {
onlineLabelOnline(selector); onlineLabelOnline(selector);
@ -23,27 +30,27 @@ function processSocketJson(json){
} }
} }
if (json.type == webSocketTypes.NEW_CONNECTION) { if (json.type == webSocketTypes.NEW_CONNECTION) {
//console.log("Socket onmessage NEW_CONNECTION", json); //console.log("processSocketJson NEW_CONNECTION", json);
if (typeof onUserSocketConnect === 'function') { if (typeof onUserSocketConnect === 'function') {
onUserSocketConnect(json); onUserSocketConnect(json);
} }
} else if (json.type == webSocketTypes.NEW_DISCONNECTION) { } else if (json.type == webSocketTypes.NEW_DISCONNECTION) {
//console.log("Socket onmessage NEW_DISCONNECTION", json); //console.log("processSocketJson NEW_DISCONNECTION", json);
if (typeof onUserSocketDisconnect === 'function') { if (typeof onUserSocketDisconnect === 'function') {
onUserSocketDisconnect(json); onUserSocketDisconnect(json);
} }
} else { } else {
var myfunc; var myfunc;
if (json.callback) { 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;}"; var code = "if(typeof " + json.callback + " == 'function'){myfunc = " + json.callback + ";}else{myfunc = defaultCallback;}";
//console.log(code); console.log('processSocketJson: code='+code);
eval(code); eval(code);
} else { } else {
//console.log("onmessage: callback not found", json); //console.log("processSocketJson: callback not found", json);
myfunc = defaultCallback; myfunc = defaultCallback;
} }
//console.log("onmessage: callback ", myfunc, json); //console.log("onmessage: callback ", myfunc, json.msg);
myfunc(json.msg); myfunc(json.msg);
} }
} }

View file

@ -112,7 +112,7 @@ ul.social-network li {
/* Define a base class for common styles */ /* Define a base class for common styles */
.social-network a, .social-network button{ .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 */ color: var(--hover-color); /* Change text color on hover */
box-shadow: 0 0 1px 1px var(--hover-color); /* Outer glow effect */ box-shadow: 0 0 1px 1px var(--hover-color); /* Outer glow effect */
transition: box-shadow 0.3s ease; /* Smooth transition for the glow effect */ transition: box-shadow 0.3s ease; /* Smooth transition for the glow effect */

View file

@ -2,6 +2,7 @@
global $socialAdded, $global; global $socialAdded, $global;
$titleSocial = @$title; $titleSocial = @$title;
$urlShort = @$url; $urlShort = @$url;
if (empty($video['id']) && !empty(getVideos_id())) { if (empty($video['id']) && !empty(getVideos_id())) {
$video['id'] = 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 '<!-- could not create social URL -->';
return;
}
if (empty($advancedCustom)) { if (empty($advancedCustom)) {
$advancedCustom = AVideoPlugin::getObjectData("CustomizeAdvanced"); $advancedCustom = AVideoPlugin::getObjectData("CustomizeAdvanced");
} }
@ -25,6 +39,7 @@ $titleSocial = getSEOTitle($titleSocial);
$urlSocial = urlencode($url); $urlSocial = urlencode($url);
//set the $urlSocial and the $titleSocial before include this //set the $urlSocial and the $titleSocial before include this
if(!isset($global)){ if(!isset($global)){
$global = []; $global = [];
} }

View file

@ -1307,7 +1307,7 @@ async function avideoConfirmCallBack(msg, confirmCallBackFunction, cancelCallBac
async function avideoConfirm(msg) { async function avideoConfirm(msg) {
var span = document.createElement("span"); var span = document.createElement("span");
span.innerHTML = __(msg); span.innerHTML = __(msg, true);
var response = await swal({ var response = await swal({
title: 'Confrim', title: 'Confrim',
content: span, content: span,
@ -4332,6 +4332,10 @@ function startTour(stepsFileRelativePath) {
// Load Intro.js CSS // Load Intro.js CSS
$('head').append('<link rel="stylesheet" href="' + webSiteRootURL + 'node_modules/intro.js/minified/introjs.min.css" type="text/css" />'); $('head').append('<link rel="stylesheet" href="' + webSiteRootURL + 'node_modules/intro.js/minified/introjs.min.css" type="text/css" />');
if (isCurrentThemeDark) {
$('head').append('<link rel="stylesheet" href="' + webSiteRootURL + 'node_modules/intro.js/themes/introjs-modern.css" type="text/css" />');
}
// Load Intro.js JavaScript // Load Intro.js JavaScript
$.getScript(webSiteRootURL + 'node_modules/intro.js/minified/intro.min.js', function () { $.getScript(webSiteRootURL + 'node_modules/intro.js/minified/intro.min.js', function () {
loadAndStartTour(stepsFileRelativePath); loadAndStartTour(stepsFileRelativePath);