1
0
Fork 0
mirror of https://github.com/DanielnetoDotCom/YouPHPTube synced 2025-10-06 03:50:04 +02:00
This commit is contained in:
Daniel Neto 2025-01-11 22:06:50 -03:00
parent 5d53819459
commit 01b32b7efd
14 changed files with 347 additions and 153 deletions

1
.gitignore vendored
View file

@ -109,3 +109,4 @@ CreatePlugin/plugins/
vendor/james-heinrich/getid3/demos/ vendor/james-heinrich/getid3/demos/
AVideoStorage/ AVideoStorage/
plugin/VideoHLSOverlay/ plugin/VideoHLSOverlay/
plugin/Live/WebRTC/WebRTC2RTMP.json

Binary file not shown.

View file

@ -61,6 +61,7 @@ function sendStreamToServer(stream) {
mediaRecorder.ondataavailable = (event) => { mediaRecorder.ondataavailable = (event) => {
if (event.data.size > 0) { if (event.data.size > 0) {
//console.log(`video-chunk`);
socket.emit('video-chunk', { rtmpURLEncrypted, chunk: event.data }); socket.emit('video-chunk', { rtmpURLEncrypted, chunk: event.data });
} }
}; };
@ -87,6 +88,18 @@ function stopStreamToServer() {
} }
function setIsWebcamServerConnected() {
console.log('Connection success');
// Custom logic to handle connection failure
$('body').removeClass('WebcamServerNotConnected').addClass('WebcamServerConnected');
}
function setIsWebcamServerNotConnected() {
console.log('Connection error');
$('body').removeClass('WebcamServerConnected').addClass('WebcamServerNotConnected');
setIsNotLive();
}
function setIsLive() { function setIsLive() {
document.body.classList.remove('isNotLive'); document.body.classList.remove('isNotLive');
document.body.classList.add('isLive'); document.body.classList.add('isLive');
@ -199,6 +212,16 @@ async function startWebRTC({ videoDeviceId = null, audioDeviceId = null, useScre
} }
} }
function toggleMediaSelector() {
if (!$('#mediaSelector').is(':visible')) {
$('#mediaSelector').fadeIn(); // Fade in #mediaSelector if not visible
$('#webrtcChat').hide(); // Hide #webrtcChat
} else {
$('#webrtcChat').show(); // Show #webrtcChat
$('#mediaSelector').fadeOut(); // Fade out #mediaSelector
}
}
window.addEventListener('orientationchange', () => { window.addEventListener('orientationchange', () => {
console.log('Orientation changed.'); console.log('Orientation changed.');
if (isLive) { if (isLive) {

View file

@ -8,86 +8,93 @@ let isLive = false; // Track live status
// Handle connection errors // Handle connection errors
socket.on('connect_error', (error) => { socket.on('connect_error', (error) => {
$('body').removeClass('WebRTCReady'); setIsWebcamServerNotConnected();
console.error('Connection error:', error.message); console.error('Connection error:', error.message);
// Custom logic to handle connection failure //avideoToastError('Unable to connect to the webcam server. Please check your connection and try again.');
}); });
// Handle connection errors // Handle successful connection
socket.on('connect', () => { socket.on('connect', () => {
avideoToastSuccess('Webcam server is ready'); setIsWebcamServerConnected();
console.log('Connection success'); avideoToastSuccess('Successfully connected to the webcam server.');
// Custom logic to handle connection failure
$('body').addClass('WebRTCReady');
}); });
// Handle disconnection // Handle disconnection
socket.on('disconnect', (reason) => { socket.on('disconnect', (reason) => {
avideoToastError('Webcam server disconnected'); setIsWebcamServerNotConnected();
avideoToastError(`Disconnected from the webcam server. Reason: ${reason}`);
console.log('Disconnected from the server:', reason); console.log('Disconnected from the server:', reason);
$('body').removeClass('WebRTCReady');
if (reason === 'io server disconnect') { if (reason === 'io server disconnect') {
// The server disconnected the client manually
socket.connect(); // Optionally reconnect socket.connect(); // Optionally reconnect
avideoToastWarning('Reconnecting to the server...');
} }
setIsNotLive();
}); });
// Handle reconnection attempts if enabled // Handle reconnection attempts
socket.on('reconnect_attempt', () => { socket.on('reconnect_attempt', () => {
console.log('Attempting to reconnect...'); console.log('Attempting to reconnect...');
avideoToastInfo('Attempting to reconnect to the webcam server...');
}); });
// Handle live-start
// Handle response
socket.on('live-start', ({ rtmpURL }) => { socket.on('live-start', ({ rtmpURL }) => {
console.log('live-start', rtmpURL); console.log('live-start', rtmpURL);
avideoToastSuccess('Live start'); avideoToastSuccess(`Live streaming started successfully.`);
setIsLive(); setIsLive();
requestNotifications(); requestNotifications();
}); });
// Handle response // Handle live-resumed
socket.on('live-resumed', ({ rtmpURL }) => { socket.on('live-resumed', ({ rtmpURL }) => {
console.log('live-resumed', rtmpURL); console.log('live-resumed', rtmpURL);
avideoToastSuccess('Live Resumed'); avideoToastSuccess(`Live streaming resumed.`);
setIsLive(); setIsLive();
requestNotifications(); requestNotifications();
}); });
// Handle live-stopped
socket.on('live-stopped', ({ rtmpURL, message }) => { socket.on('live-stopped', ({ rtmpURL, message }) => {
console.log('live-stopped', rtmpURL, message); console.log('live-stopped', rtmpURL, message);
avideoToastWarning('Live stop'); avideoToastWarning(`Live streaming stopped. Reason: ${message}`);
setIsNotLive(); setIsNotLive();
requestNotifications(); requestNotifications();
}); });
// Handle general errors
socket.on('error', ({ message }) => { socket.on('error', ({ message }) => {
console.error(`Error: ${message}`); console.error(`Error: ${message}`);
avideoToastError(message); avideoToastError(`An error occurred: ${message}`);
requestNotifications(); requestNotifications();
}); });
// Handle FFMPEG errors
socket.on('ffmpeg-error', ({ code }) => { socket.on('ffmpeg-error', ({ code }) => {
console.error(`FFMPEG Error: ${code}`); console.error(`FFMPEG Error: ${code}`);
//avideoToastError(message); avideoToastError(`FFMPEG encountered an error. Error code: ${code}`);
requestNotifications(); requestNotifications();
}); });
// Handle active connections
socket.on('connections', ({ current, max }) => { socket.on('connections', ({ current, max }) => {
console.log(`Current number of active connections: ${current}/${max}`); console.log(`Current number of active connections: ${current}/${max}`);
//avideoToastInfo(`Active connections: ${current}/${max}`);
}); });
// Handle live-time
socket.on('live-time', ({ startTime, elapsedSeconds, remainingSeconds }) => { socket.on('live-time', ({ startTime, elapsedSeconds, remainingSeconds }) => {
console.log(`Time remaining is: ${remainingSeconds} seconds `); console.log(`Time remaining is: ${remainingSeconds} seconds`);
//avideoToastInfo(`Live stream time remaining: ${remainingSeconds} seconds.`);
}); });
// Handle RTMP status
socket.on('rtmp-status', ({ rtmpURL, isRunning }) => { socket.on('rtmp-status', ({ rtmpURL, isRunning }) => {
if (isRunning) { if (isRunning) {
console.log(`This live is running with RTMP URL: ${rtmpURL}`); console.log(`This live is running with RTMP URL: ${rtmpURL}`);
//avideoToastSuccess(`Live stream is running. RTMP URL: ${rtmpURL}`);
setIsLive(); setIsLive();
} else { } else {
console.log(`This live is not running`); console.log(`This live is not running`);
//avideoToastWarning('Live stream is not running.');
setIsNotLive(); setIsNotLive();
} }
@ -95,7 +102,9 @@ socket.on('rtmp-status', ({ rtmpURL, isRunning }) => {
clearTimeout(liveStatusTimeout); clearTimeout(liveStatusTimeout);
}); });
// Handle stream-stopped
socket.on('stream-stopped', ({ rtmpURL, reason }) => { socket.on('stream-stopped', ({ rtmpURL, reason }) => {
console.log(`Stream for ${rtmpURL} stopped: ${reason}`); console.log(`Stream for ${rtmpURL} stopped: ${reason}`);
avideoToastWarning(`Stream stopped. Reason: ${reason}`);
requestNotifications(); requestNotifications();
}); });

View file

@ -55,3 +55,28 @@ function decrypt_data($ciphertextB64, $salt)
return $plaintext; return $plaintext;
} }
function getWebRTCInfo(){
global $global;
$file = "{$global['systemRootPath']}plugin/Live/WebRTC/WebRTC2RTMP.json";
if(!file_exists($file)){
return false;
}
$content = file_get_contents("{$global['systemRootPath']}plugin/Live/WebRTC/WebRTC2RTMP.json");
if(empty($content)){
return false;
}
$json = json_decode($content);
if(empty($json)){
return false;
}
return $json;
}
function getWebRTC2RTMPURL(){
$json = getWebRTCInfo();
if(empty($json)){
return '';
}
return "https://{$json->domain}:{$json->serverPort}";
}

View file

@ -19,12 +19,20 @@ if (empty($_REQUEST['avideoIframe'])) {
<?php <?php
?> ?>
</div> </div>
<div id="webcamMediaControls" class="showWhenWebRTCIsReady"> <div id="webcamMediaControls" class="showWhenWebRTCIsConnected">
<?php <?php
include __DIR__ . '/panel.medias.php'; include __DIR__ . '/panel.medias.php';
include __DIR__ . '/panel.buttons.php'; include __DIR__ . '/panel.buttons.php';
?> ?>
</div> </div>
<div id="webcamMediaControlsMessage" class="alert alert-danger showWhenWebRTCIsNotConnected text-center">
<div class="fa-3x">
<i class="fa-solid fa-triangle-exclamation fa-fade"></i>
</div>
<strong>Error:</strong> Unable to connect to the Webcam server.<br>
<span>Please verify the server status and resolve any issues.</span>
</div>
<script> <script>
$(document).ready(function() { $(document).ready(function() {
startWebRTC(); startWebRTC();

View file

@ -2,7 +2,7 @@
<button type="button" id="startLive" class="btn btn-success oval-menu animate__animated animate__bounceIn" onclick="startWebcamLive(rtmpURLEncrypted);"> <button type="button" id="startLive" class="btn btn-success oval-menu animate__animated animate__bounceIn" onclick="startWebcamLive(rtmpURLEncrypted);">
<i class="fa fa-play"></i> Go Live <i class="fa fa-play"></i> Go Live
</button> </button>
<button type="button" class="btn btn-default oval-menu animate__animated animate__bounceIn" onclick="$('#mediaSelector').fadeToggle()" style=" -webkit-animation-delay: .2s; animation-delay: .2s;"> <button type="button" class="btn btn-default oval-menu animate__animated animate__bounceIn" onclick="toggleMediaSelector();" style=" -webkit-animation-delay: .2s; animation-delay: .2s;">
<i class="fa-solid fa-ellipsis-vertical"></i> <i class="fa-solid fa-ellipsis-vertical"></i>
</button> </button>
</div> </div>

View file

@ -7,7 +7,7 @@
include __DIR__ . '/video.php'; include __DIR__ . '/video.php';
?> ?>
</div> </div>
<div class="panel-footer showWhenWebRTCIsReady"> <div class="panel-footer showWhenWebRTCIsConnected">
<?php <?php
include __DIR__ . '/panel.medias.php'; include __DIR__ . '/panel.medias.php';
include __DIR__ . '/panel.buttons.php'; include __DIR__ . '/panel.buttons.php';

View file

@ -1,91 +1,135 @@
body{ body {
background-color: #000;; background-color: #000;
;
} }
/* Make the video cover the entire page */ /* Make the video cover the entire page */
video { video {
width: 100%; width: 100%;
height: 100%; height: 100%;
object-fit: contain; /* Fill the container, even if it means cropping */ object-fit: contain;
/* Fill the container, even if it means cropping */
background: black; background: black;
} }
.indicator{ .indicator {
font-family: Arial, Helvetica, sans-serif; font-family: Arial, Helvetica, sans-serif;
position: absolute; position: absolute;
top: 30px; top: 40px;
left: 30px; left: 20px;
color: white; color: white;
font-size: 12px; font-size: 12px;
font-weight: bold; font-weight: bold;
padding: 2px 4px; padding: 2px 4px;
border-radius: 5px; border-radius: 5px;
border: 1px solid #DDD;
border-radius: 50%;
}
#offLineIndicator {
background: #FF000033;
color: #CCC;
border-color: #FAA;
} }
/* Live indicator */ /* Live indicator */
#onLineIndicator {
background: #00000055;
color: #DDD;
}
/* Live indicator (Green) */
#liveIndicator { #liveIndicator {
background: #FF0000AA; background: #00FF00AA;
box-shadow: 0 0 5px #FF0000; /* Initial glow */ box-shadow: 0 0 5px #00FF00;
animation: glowPulse 1.5s infinite; /* Apply the glow animation */ /* Initial glow */
animation: greenGlowPulse 1.5s infinite;
/* Apply the glow animation */
border-color: 2px solid #55FF55;
} }
#offLineIndicator{ /* Keyframes for green glowing pulse animation */
background: #CCCCCCAA; @keyframes greenGlowPulse {
}
/* Keyframes for glowing pulse animation */
@keyframes glowPulse {
0% { 0% {
box-shadow: 0 0 5px #FF0000; /* Starting soft glow */ box-shadow: 0 0 5px #00FF00;
/* Starting soft glow */
} }
50% { 50% {
box-shadow: 0 0 15px #FF0000; /* Intense glow */ box-shadow: 0 0 15px #00FF00;
/* Intense glow */
} }
100% { 100% {
box-shadow: 0 0 5px #FF0000; /* Back to soft glow */ box-shadow: 0 0 5px #00FF00;
/* Back to soft glow */
} }
} }
.showWhenIsLive{ .showWhenIsLive {
display: none !important; display: none !important;
} }
.showWhenIsNotLive{ .showWhenIsNotLive {
display: block !important; display: block !important;
} }
.isLive .showWhenIsLive{ .isLive .showWhenIsLive {
display: block !important; display: block !important;
} }
.isLive .showWhenIsNotLive{ .isLive .showWhenIsNotLive {
display: none !important; display: none !important;
} }
.showWhenWebRTCIsReady{ .showWhenWebRTCIsConnected,
.showWhenWebRTCIsNotConnected {
display: none !important; display: none !important;
} }
.WebRTCReady .showWhenWebRTCIsReady{ .WebcamServerConnected .showWhenWebRTCIsConnected {
display: block !important; display: block !important;
} }
#webcamMediaControls{
.WebcamServerNotConnected .showWhenWebRTCIsNotConnected {
display: block !important;
}
#webcamMediaControls, #webcamMediaControlsMessage {
position: fixed; position: fixed;
bottom: 10px; bottom: 10px;
width: 100%; width: 100%;
} }
.oval-menu { .oval-menu {
height: 50px; height: 30px;
min-width: 50px; min-width: 30px;
border-radius: 25px; border-radius: 15px;
box-shadow: 0 0 15px 1px black; box-shadow: 0 0 15px 1px black;
font-size: 15px; font-size: 12px;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
margin: 10px; margin: 10px;
} }
.oval-menu i{ .oval-menu i {
margin: 0 10px; margin: 0 10px;
} }
.transparent-iframe {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: calc(100% - 50px);
/* Occupies full height minus 100px at the bottom */
border: none;
/* Removes the border */
background: transparent;
/* Ensures transparency if supported by the content */
z-index: 1;
/* Ensure proper stacking order */
pointer-events: auto;
/* Allows interaction with iframe content */
}

View file

@ -1,22 +1,27 @@
<?php <?php
require_once __DIR__.'/functions.php'; require_once __DIR__ . '/functions.php';
global $global;
// Use parse_url to extract components of the URL $global['doNotLoadPlayer'] = 1;
$parsedUrl = parse_url($global['webSiteRootURL']); $forceIndex = 'Webcam';
$rtmpURL = Live::getRTMPLink(User::getId(), $forceIndex);
// Get the domain (host) from the parsed URL $key = Live::getKeyFromUser(User::getId());
$domain = $parsedUrl['host'] ?? null;
?> ?>
<script class="doNotSepareteTag"> <script class="doNotSepareteTag">
// Send streamKey to the server when joining // Send streamKey to the server when joining
var rtmpURLEncrypted = '<?php echo encrypt_data(Live::getRTMPLink(User::getId(), 'Webcam'), $global['saltV2']); ?>'; var rtmpURLEncrypted = '<?php echo encrypt_data($rtmpURL, $global['saltV2']); ?>';
var WebRTC2RTMPURL = 'https://<?php echo $domain; ?>:3000'; var WebRTC2RTMPURL = '<?php echo getWebRTC2RTMPURL(); ?>';
</script> </script>
<link href="<?php echo getURL('plugin/Live/WebRTC/style.css'); ?>" rel="stylesheet" type="text/css" /> <link href="<?php echo getURL('plugin/Live/WebRTC/style.css'); ?>" rel="stylesheet" type="text/css" />
<div id="liveIndicator" class="showWhenIsLive indicator" style="display: none;">LIVE</div> <div id="offLineIndicator" class="showWhenWebRTCIsNotConnected indicator" style="display: none;">
<div id="offLineIndicator" class="showWhenIsNotLive indicator" style="display: none;">OFFLINE</div> <div>
<i class="fa-solid fa-wifi"></i>
<i class="fa-solid fa-slash" style="position: absolute;left: 4px;top: 3px;"></i>
</div>
</div>
<div id="onLineIndicator" class="showWhenWebRTCIsConnected showWhenIsNotLive indicator" style="display: none;"><i class="fa-solid fa-wifi"></i></div>
<div id="liveIndicator" class="showWhenIsLive indicator" style="display: none;"><i class="fa-solid fa-wifi"></i></div>
<video id="localVideo" autoplay muted playsinline></video> <video id="localVideo" autoplay muted playsinline></video>
<iframe id="webrtcChat" class="transparent-iframe" src="<?php echo $global['webSiteRootURL']; ?>plugin/MobileYPT/index.php?key=<?php echo $key; ?>&live_index=<?php echo $forceIndex; ?>"></iframe>
<script src="<?php echo getURL('node_modules/socket.io-client/dist/socket.io.min.js'); ?>" type="text/javascript"></script> <script src="<?php echo getURL('node_modules/socket.io-client/dist/socket.io.min.js'); ?>" type="text/javascript"></script>
<script src="<?php echo getURL('plugin/Live/WebRTC/api.js'); ?>" type="text/javascript"></script> <script src="<?php echo getURL('plugin/Live/WebRTC/api.js'); ?>" type="text/javascript"></script>
<script src="<?php echo getURL('plugin/Live/WebRTC/events.js'); ?>" type="text/javascript"></script> <script src="<?php echo getURL('plugin/Live/WebRTC/events.js'); ?>" type="text/javascript"></script>

View file

@ -12,6 +12,9 @@ function isInLive(json) {
var prerollPosterAlreadyPlayed = false; var prerollPosterAlreadyPlayed = false;
async function showImage(type, key) { async function showImage(type, key) {
if (typeof player === 'undefined') {
return false;
}
if (typeof closeLiveImageRoll == 'function') { if (typeof closeLiveImageRoll == 'function') {
closeLiveImageRoll(); closeLiveImageRoll();
} }

View file

@ -1,17 +1,35 @@
function socketLiveONCallback(json) { document.addEventListener('socketLiveONCallback', function(event) {
let json = event.detail;
if(json === null){
console.error('socketLiveONCallback socket EventListener error', event);
return false;
}
console.log('socketLiveONCallback socket EventListener', json);
if (typeof json === 'string') { if (typeof json === 'string') {
try { try {
json = JSON.parse(json); json = JSON.parse(json);
} catch (error) { } catch (error) {
console.error("Invalid JSON string:", error); console.error("Invalid JSON string:", error);
return null; // or return the original string if you prefer return; // Exit the listener if JSON parsing fails
} }
} }
if(typeof json.key == 'undefined'){
if(typeof json.json !== 'undefined' && typeof json.json.key !== 'undefined' ){
json = json.json;
}else{
console.error("socketLiveONCallback Invalid JSON key not found:", json);
return; // Exit the listener if JSON parsing fails
}
}
console.log('socketLiveONCallback live plugin', json); console.log('socketLiveONCallback live plugin', json);
if (typeof processLiveStats == 'function') { if (typeof processLiveStats == 'function') {
processLiveStats(json.stats); processLiveStats(json.stats);
} }
var selector = '.live_' + json.live_servers_id + "_" + json.key;
let selector = '.live_' + json.live_servers_id + "_" + json.key;
$(selector).slideDown(); $(selector).slideDown();
if (typeof onlineLabelOnline == 'function') { if (typeof onlineLabelOnline == 'function') {
@ -23,38 +41,58 @@ function socketLiveONCallback(json) {
onlineLabelOnline(selector); onlineLabelOnline(selector);
} }
// update the chat if the history changes let IframeClass = ".yptchat2IframeClass_" + json.key + "_" + json.live_servers_id;
var IframeClass = ".yptchat2IframeClass_" + json.key + "_" + json.live_servers_id;
if ($(IframeClass).length) { if ($(IframeClass).length) {
var src = $(IframeClass).attr('src'); let src = $(IframeClass).attr('src');
if (src) { if (src) {
avideoToast('Loading new chat'); avideoToast('Loading new chat');
var newSRC = addGetParam(src, 'live_transmitions_history_id', json.live_transmitions_history_id); let newSRC = addGetParam(src, 'live_transmitions_history_id', json.live_transmitions_history_id);
$(IframeClass).attr('src', newSRC); $(IframeClass).attr('src', newSRC);
} }
} }
if (isInLive(json)) { if (isInLive(json)) {
playerPlay(); playerPlay();
showImage('prerollPoster', json.cleanKey); showImage('prerollPoster', json.cleanKey);
} }
} });
function socketLiveOFFCallback(json) {
document.addEventListener('socketLiveOFFCallback', function(event) {
let json = event.detail;
if(json === null){
console.error('socketLiveOFFCallback socket EventListener error', event);
console.trace();
return false;
}
console.log('socketLiveOFFCallback socket EventListener', json);
if (typeof json === 'string') { if (typeof json === 'string') {
try { try {
json = JSON.parse(json); json = JSON.parse(json);
} catch (error) { } catch (error) {
console.error("Invalid JSON string:", error); console.error("Invalid JSON string:", error);
return null; // or return the original string if you prefer return; // Exit the listener if JSON parsing fails
} }
} }
if(typeof json.key == 'undefined'){
if(typeof json.json !== 'undefined' && typeof json.json.key !== 'undefined' ){
json = json.json;
}else{
console.error("socketLiveOFFCallback Invalid JSON key not found:", json);
return; // Exit the listener if JSON parsing fails
}
}
console.log('socketLiveOFFCallback live socket', json); console.log('socketLiveOFFCallback live socket', json);
var selector = '.live_' + json.live_servers_id + "_" + json.key;
let 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;
////console.log('socketLiveOFFCallback 1', selector);
$(selector).slideUp("fast", function () { $(selector).slideUp("fast", function () {
$(this).remove(); $(this).remove();
}); });
if (typeof onlineLabelOffline == 'function') { if (typeof onlineLabelOffline == 'function') {
selector = '#liveViewStatusID_' + json.key + '_' + json.live_servers_id; selector = '#liveViewStatusID_' + json.key + '_' + json.live_servers_id;
selector += ', .liveViewStatusClass_' + json.key + '_' + json.live_servers_id; selector += ', .liveViewStatusClass_' + json.key + '_' + json.live_servers_id;
@ -63,8 +101,8 @@ function socketLiveOFFCallback(json) {
console.log('socketLiveOFFCallback', selector); console.log('socketLiveOFFCallback', selector);
onlineLabelOffline(selector); onlineLabelOffline(selector);
} }
setTimeout(function () { setTimeout(function () {
//console.log('socketLiveOFFCallback processLiveStats');
if (typeof processLiveStats == 'function') { if (typeof processLiveStats == 'function') {
processLiveStats(json.stats); processLiveStats(json.stats);
} }
@ -78,10 +116,12 @@ function socketLiveOFFCallback(json) {
if (isInLive(json)) { if (isInLive(json)) {
showImage('postrollPoster', json.cleanKey); showImage('postrollPoster', json.cleanKey);
} }
if (typeof updateUserNotificationCount == 'function') { if (typeof updateUserNotificationCount == 'function') {
updateUserNotificationCount(); updateUserNotificationCount();
} }
} });
function redirectLive(json, countdown = 15) { function redirectLive(json, countdown = 15) {
if (typeof json === 'string') { if (typeof json === 'string') {

View file

@ -1,6 +1,7 @@
<?php <?php
global $global, $config; global $global, $config;
$global['isIframe'] = 1; $global['isIframe'] = 1;
$global['isNotAPlayer'] = 1;
// is online // is online
// recorder // recorder
// live users // live users
@ -17,7 +18,7 @@ $global['skippPlugins'][] = 'TheaterButton';
//$global['doNotLoadPlayer'] = 1; //$global['doNotLoadPlayer'] = 1;
$bodyClass = ''; $bodyClass = '';
$key = ''; $key = '';
$live_servers_id = ''; $live_servers_id = 0;
$live_index = ''; $live_index = '';
$users_id = User::getId(); $users_id = User::getId();
if (!empty($_REQUEST['logoff'])) { if (!empty($_REQUEST['logoff'])) {
@ -28,12 +29,12 @@ User::loginFromRequestIfNotLogged();
if (User::isLogged()) { if (User::isLogged()) {
if (!empty($_REQUEST['key'])) { if (!empty($_REQUEST['key'])) {
$key = $_REQUEST['key']; $key = $_REQUEST['key'];
$live_servers_id = @$_REQUEST['live_servers_id']; $live_servers_id = intval(@$_REQUEST['live_servers_id']);
$live_index = @$_REQUEST['live_index']; $live_index = @$_REQUEST['live_index'];
} else if (User::isLogged()) { } else if (User::isLogged()) {
$lth = LiveTransmitionHistory::getLatestFromUser($users_id); $lth = LiveTransmitionHistory::getLatestFromUser($users_id);
$key = $lth['key']; $key = $lth['key'];
$live_servers_id = $lth['live_servers_id']; $live_servers_id = intval($lth['live_servers_id']);
$live_index = @$lth['live_index']; $live_index = @$lth['live_index'];
} }
@ -59,9 +60,11 @@ if (User::isLogged()) {
$chat->set_doNotAllowUsersSendMessagesToEachOther(1); $chat->set_doNotAllowUsersSendMessagesToEachOther(1);
$chat->set_hideBubbleButtons(1); $chat->set_hideBubbleButtons(1);
$iframeURL = $chat->getURL(true); $iframeURL = $chat->getURL(true);
$iframeClass = "yptchat2IframeClass_{$key}-{$live_index}_{$live_servers_id}";
$html = '<iframe $html = '<iframe
id="yptchat2Iframe" id="yptchat2Iframe"
class="' . $iframeClass . '"
src="' . $iframeURL . '" src="' . $iframeURL . '"
frameborder="0" scrolling="no" title="chat widget" frameborder="0" scrolling="no" title="chat widget"
allowtransparency="true" allowtransparency="true"
@ -112,7 +115,8 @@ if (User::isLogged()) {
?> ?>
<!DOCTYPE html> <!DOCTYPE html>
<html lang=""> <html lang="">
<head>
<head>
<style> <style>
body { body {
padding: 100px 0; padding: 100px 0;
@ -122,41 +126,50 @@ if (User::isLogged()) {
include $global['systemRootPath'] . 'view/include/head.php'; include $global['systemRootPath'] . 'view/include/head.php';
?> ?>
<style> <style>
#accessibility-toolbar, footer, #socket_info_container{ #accessibility-toolbar,
footer,
#socket_info_container {
display: none !important; display: none !important;
} }
body { body {
padding: 0; padding: 0;
} }
.liveUsersLabel{ .liveUsersLabel {
position: fixed; position: fixed;
top: 10px !important; top: 10px !important;
} }
.liveUsersLabel{
.liveUsersLabel {
left: 20px !important; left: 20px !important;
} }
#recorderToEncoderActionButtons{
#recorderToEncoderActionButtons {
position: absolute; position: absolute;
top: 40px; top: 40px;
left: 0; left: 0;
width: 100%; width: 100%;
} }
.showWhenClosed, #closeRecorderButtons{
.showWhenClosed,
#closeRecorderButtons {
display: none; display: none;
} }
#recorderToEncoderActionButtons.closed .recordLiveControlsDiv, #recorderToEncoderActionButtons.closed .recordLiveControlsDiv,
#recorderToEncoderActionButtons.closed .hideWhenClosed{ #recorderToEncoderActionButtons.closed .hideWhenClosed {
display: none !important; display: none !important;
} }
#recorderToEncoderActionButtons.closed .showWhenClosed, #recorderToEncoderActionButtons.closed .showWhenClosed,
.isLiveOnline #closeRecorderButtons{ .isLiveOnline #closeRecorderButtons {
display: inline-block !important; display: inline-block !important;
} }
</style> </style>
</head> </head>
<body style="background-color: transparent; <?php echo @$bodyClass; ?>"> <body style="background-color: transparent; <?php echo @$bodyClass; ?>">
<?php <?php
echo $html; echo $html;
?> ?>
@ -164,18 +177,27 @@ if (User::isLogged()) {
include $global['systemRootPath'] . 'view/include/footer.php'; include $global['systemRootPath'] . 'view/include/footer.php';
?> ?>
<script> <script>
function socketLiveONCallback(json) { document.addEventListener('socketLiveONCallback', function(event) {
console.log('socketLiveONCallback MobileYPT', json); const json = event.detail; // Extract the JSON data from the event's detail property
if ((json.users_id == '<?php echo User::getId(); ?>' && json.live_transmitions_history_id) || (!empty(json.key) && json.key == '<?php echo @$_REQUEST['key']; ?>')) { console.log('socketLiveONCallback EventListener', json);
if(json == null){
console.trace();
return false;
}
if (
(json.users_id == '<?php echo User::getId(); ?>' && json.live_transmitions_history_id) ||
(json.key && json.key == '<?php echo @$_REQUEST['key']; ?>')
) {
modal.showPleaseWait(); modal.showPleaseWait();
var url = addGetParam(window.location.href, 'live_transmitions_history_id', json.live_transmitions_history_id); let url = addGetParam(window.location.href, 'live_transmitions_history_id', json.live_transmitions_history_id);
url = addGetParam(url, 'key', json.key); url = addGetParam(url, 'key', json.key);
url = addGetParam(url, 'live_servers_id', json.live_servers_id); url = addGetParam(url, 'live_servers_id', json.live_servers_id);
url = addGetParam(url, 'live_schedule', json.live_schedule); url = addGetParam(url, 'live_schedule', json.live_schedule);
url = addGetParam(url, 'live_index', json.live_index); url = addGetParam(url, 'live_index', json.live_index);
document.location = url; document.location = url;
} }
} });
</script> </script>
</body> </body>
</html> </html>

View file

@ -41,17 +41,31 @@ function processSocketJson(json) {
} }
} else { } else {
var myfunc; var myfunc;
var _details = json;
if(typeof json.msg != 'undefined'){
_details = json.msg;
}
if(typeof _details === 'string'){
_details = JSON.parse(_details);
console.log('processSocketJson: details after', _details);
}
if (json.callback) { if (json.callback) {
//console.log("processSocketJson json.callback ", json.resourceId, json.callback); // Check if a function exists with the name in 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('processSocketJson: code=' + code); console.log('processSocketJson: code=' + code, _details);
eval(code); eval(code);
// Trigger the event with the same name as json.callback and pass the JSON object
const event = new CustomEvent(json.callback, { detail: _details }); // Pass the JSON as `detail`
document.dispatchEvent(event);
} else { } else {
//console.log("processSocketJson: callback not found", json); console.log("processSocketJson: callback not found", json);
myfunc = defaultCallback; myfunc = defaultCallback;
} }
//console.log("onmessage: callback ", myfunc, json.msg);
myfunc(json.msg); // Call the function and pass the JSON object
myfunc(_details);
} }
} }