New Filestructure for Docker
This commit is contained in:
@@ -0,0 +1,322 @@
|
||||
<?php
|
||||
|
||||
if (!isset($segments) || !defined('APP_ROUTER')) {
|
||||
http_response_code(403);
|
||||
include $baseDir . "/error-pages/403.php";
|
||||
exit;
|
||||
}
|
||||
|
||||
$type = $segments[1] ?? null;
|
||||
$requested_geraet = htmlspecialchars($segments[2] ?? '');
|
||||
|
||||
$allowed_types = ["audioplayer"];
|
||||
|
||||
if (!in_array($type, $allowed_types)) {
|
||||
http_response_code(400);
|
||||
include $baseDir . "/error-pages/400.html";
|
||||
exit;
|
||||
}
|
||||
|
||||
$baseDir = $_SERVER['DOCUMENT_ROOT'];
|
||||
|
||||
require_once $baseDir . '/../scripts/session_functions.php';
|
||||
|
||||
ini_wkvs_session(true);
|
||||
|
||||
$csrf_token = $_SESSION['csrf_token'] ?? '';
|
||||
|
||||
require $baseDir . '/../scripts/websocket/ws-create-token.php';
|
||||
|
||||
$WSaccesstype = "audio";
|
||||
$WSaccessPermission = "R";
|
||||
|
||||
require_once $baseDir . '/../scripts/db/db-verbindung-script-guest.php';
|
||||
require_once $baseDir . '/../scripts/db/db-functions.php';
|
||||
require_once $baseDir . '/../scripts/db/db-tables.php';
|
||||
|
||||
$stmt = $guest->prepare("SELECT `name`, `id` FROM $db_tabelle_disziplinen WHERE `audiofile` = '1' ORDER BY start_index ASC");
|
||||
|
||||
if (!$stmt->execute()) {
|
||||
http_response_code(500);
|
||||
exit;
|
||||
}
|
||||
|
||||
$result = $stmt->get_result();
|
||||
$disciplines = $result->fetch_all(MYSQLI_ASSOC);
|
||||
|
||||
$lowerDisciplines = array_change_key_case(
|
||||
array_column($disciplines, 'id', 'name'),
|
||||
CASE_LOWER
|
||||
);
|
||||
|
||||
$disciplines_indexed = array_column($disciplines, 'name', 'id');
|
||||
|
||||
|
||||
if (!array_key_exists($requested_geraet, $lowerDisciplines)) {
|
||||
http_response_code(400);
|
||||
$message = 'Das gesuchte Gerät kann nicht gefunden werden';
|
||||
include $baseDir . "/error-pages/400.php";
|
||||
exit;
|
||||
}
|
||||
|
||||
if (!isset($lowerDisciplines[$requested_geraet])) {
|
||||
http_response_code(500);
|
||||
include $baseDir . "/error-pages/500.html";
|
||||
exit;
|
||||
}
|
||||
|
||||
$geraetId = $lowerDisciplines[$requested_geraet];
|
||||
|
||||
$WSaccess = (string) $geraetId;
|
||||
|
||||
$jsonUrl = '/externe-geraete/json/audio-id-' . $geraetId . '.json';
|
||||
|
||||
?>
|
||||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>Remote Audioplayer</title>
|
||||
<meta name="robots" content="noindex">
|
||||
<script src="/intern/js/jquery/jquery-3.7.1.min.js"></script>
|
||||
<script src="/intern/js/custom-msg-display.js"></script>
|
||||
<link rel="stylesheet" href="/intern/css/custom-msg-display.css">
|
||||
<link rel="stylesheet" href="/externe-geraete/css/audio.css">
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<section>
|
||||
<div class="header">
|
||||
<h1 id="title">Audioplayer</h1>
|
||||
<p id="subtitle"><?= $disciplines_indexed[$geraetId] ?></p>
|
||||
</div>
|
||||
|
||||
<button class="startButton">
|
||||
Audioplayer starten
|
||||
</button>
|
||||
|
||||
<div class="currentyPlaying hidden">
|
||||
Aktuell laufendes Audio:
|
||||
<div class="subDivCurrentyPlaying">
|
||||
<span>Dateiname: <span class="spanFilename"></span></span>
|
||||
<span class="spanPersonname">Name der Person:
|
||||
<span class="spanPersonnameName"></span>,
|
||||
<span class="spanPersonnameVorname"></span>
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div class="progressDiv">
|
||||
<div id="progressContainer">
|
||||
<div id="progressBar"></div>
|
||||
</div>
|
||||
|
||||
<span class="progressText"><span id="currentText">0:00</span> / <span id="durationText">0:00</span></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="content">
|
||||
Dies ist der Live Audioplayer. Audio kann über die Kampfrichteransicht gestartet werden.
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<audio id="peep" preload="auto"></audio>
|
||||
<audio id="musicPlayer" preload="auto"></audio>
|
||||
<script>
|
||||
const WSaccesstype = "<?= $WSaccesstype ?>";
|
||||
const WSaccess = "<?= $WSaccess ?>";
|
||||
const csrf_token = "<?= $csrf_token ?>";
|
||||
const WSaccessPermission = "<?= $WSaccessPermission ?>"
|
||||
|
||||
const jsonUrl = "<?php echo $jsonUrl; ?>";
|
||||
|
||||
let ws;
|
||||
|
||||
let firstConnect = true;
|
||||
const RETRY_DELAY = 2000;
|
||||
|
||||
const urlAjaxNewWSToken = '/intern/scripts/ajax-create-ws-token.php';
|
||||
|
||||
async function fetchNewWSToken(accesstype, access, accessPermission) {
|
||||
try {
|
||||
const response = await fetch(urlAjaxNewWSToken, {
|
||||
method: "POST",
|
||||
headers: {
|
||||
'Content-Type': 'application/x-www-form-urlencoded',
|
||||
},
|
||||
body: new URLSearchParams({
|
||||
csrf_token,
|
||||
accesstype,
|
||||
access,
|
||||
accessPermission
|
||||
})
|
||||
});
|
||||
|
||||
if (!response.ok) return null;
|
||||
|
||||
const data = await response.json();
|
||||
return data.success ? data.token : null;
|
||||
} catch (error) {
|
||||
console.error("Token fetch failed:", error);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
async function startWebSocket() {
|
||||
console.log("Attempting WebSocket connection...");
|
||||
|
||||
let token;
|
||||
if (firstConnect) {
|
||||
token = '<?= generateWSReadToken($WSaccesstype, $WSaccess) ?>';
|
||||
} else {
|
||||
token = await fetchNewWSToken(WSaccesstype, WSaccess, WSaccessPermission);
|
||||
}
|
||||
|
||||
if (!token) {
|
||||
console.error("No valid token available. Retrying...");
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
ws = new WebSocket(`wss://${window.location.hostname}/ws/?access=token&token=${token}`);
|
||||
} catch (err) {
|
||||
console.error("Malformed WebSocket URL", err);
|
||||
scheduleRetry();
|
||||
return;
|
||||
}
|
||||
|
||||
ws.onopen = () => {
|
||||
console.log("WebSocket connected!");
|
||||
if (!firstConnect) {
|
||||
displayMsg(1, "Live Syncronisation wieder verfügbar");
|
||||
}
|
||||
firstConnect = true;
|
||||
};
|
||||
|
||||
ws.onerror = (event) => {
|
||||
console.error("WebSocket error observed.");
|
||||
};
|
||||
|
||||
ws.onclose = (event) => {
|
||||
displayMsg(0, "Live Syncronisation verloren");
|
||||
firstConnect = false;
|
||||
|
||||
scheduleRetry();
|
||||
};
|
||||
}
|
||||
|
||||
function scheduleRetry() {
|
||||
console.log(`Retrying in ${RETRY_DELAY}ms...`);
|
||||
setTimeout(startWebSocket, RETRY_DELAY);
|
||||
}
|
||||
|
||||
startWebSocket();
|
||||
|
||||
const spanFilename = $('.spanFilename');
|
||||
const spanPersonname = $('.spanPersonname');
|
||||
const spanPersonnameName = $('.spanPersonnameName');
|
||||
const spanPersonnameVorname = $('.spanPersonnameVorname');
|
||||
|
||||
const currentyPlaying = $('.currentyPlaying');
|
||||
|
||||
const $progressBar = $('#progressBar');
|
||||
const $progressContainer = $('#progressContainer');
|
||||
|
||||
const peep = document.getElementById('peep');
|
||||
const music = document.getElementById('musicPlayer');
|
||||
const $audio = $('#musicPlayer');
|
||||
|
||||
let lastMusicUrl = null;
|
||||
let pollingStarted = false; // ensure we start polling only once
|
||||
|
||||
async function fetchAndHandleMusic() {
|
||||
try {
|
||||
const response = await fetch(jsonUrl + '?t=' + Date.now(), { cache: 'no-store' });
|
||||
const data = await response.json();
|
||||
|
||||
if (!data.audio_path || data.audio_path === 'nan' || data.start == false) {
|
||||
if (!music.paused) {
|
||||
music.pause();
|
||||
music.currentTime = 0;
|
||||
}
|
||||
if (!peep.paused) {
|
||||
peep.pause();
|
||||
peep.currentTime = 0;
|
||||
}
|
||||
lastMusicUrl = null;
|
||||
return;
|
||||
}
|
||||
|
||||
peep.src = '/files/music/piep.mp3';
|
||||
music.src = data.audio_path;
|
||||
music.currentTime = 0;
|
||||
peep.play().then(() => {
|
||||
setTimeout(() => {
|
||||
music.play().catch(err => console.log('Music play error:', err));
|
||||
}, 2000);
|
||||
}).catch(err => console.log('Peep play error:', err));
|
||||
|
||||
spanFilename.text(data.audio_name ?? '');
|
||||
spanPersonnameName.text(data.person.name ?? '');
|
||||
spanPersonnameVorname.text(data.person.vorname ?? '');
|
||||
|
||||
} catch (err) {
|
||||
console.error('Error fetching JSON:', err);
|
||||
}
|
||||
}
|
||||
|
||||
function formatTime(seconds) {
|
||||
if (isNaN(seconds)) return "0:00";
|
||||
const mins = Math.floor(seconds / 60);
|
||||
const secs = Math.floor(seconds % 60);
|
||||
return mins + ":" + (secs < 10 ? '0' : '') + secs;
|
||||
}
|
||||
|
||||
const audioDOM = $audio[0];
|
||||
|
||||
$audio.on('timeupdate', function() {
|
||||
if (audioDOM.duration) {
|
||||
const percentage = (audioDOM.currentTime / audioDOM.duration) * 100;
|
||||
$progressBar.css('width', percentage + '%');
|
||||
$('#currentText').text(formatTime(audioDOM.currentTime));
|
||||
}
|
||||
});
|
||||
|
||||
$audio.on('loadedmetadata', function() {
|
||||
$('#durationText').text(formatTime(audioDOM.duration));
|
||||
});
|
||||
|
||||
let isActive = false;
|
||||
|
||||
$('.startButton').on('click', function() {
|
||||
isActive = !isActive;
|
||||
if (isActive) {
|
||||
$(this).text('Audioplayer stoppen');
|
||||
} else {
|
||||
$(this).text('Audioplayer starten');
|
||||
currentyPlaying.addClass('hidden');
|
||||
if (!music.paused) {
|
||||
music.pause();
|
||||
music.currentTime = 0;
|
||||
}
|
||||
if (!peep.paused) {
|
||||
peep.pause();
|
||||
peep.currentTime = 0;
|
||||
}
|
||||
}
|
||||
$('section').toggleClass('playerActive', isActive);
|
||||
|
||||
|
||||
if (!pollingStarted) {
|
||||
pollingStarted = true;
|
||||
ws.addEventListener("message", () => {
|
||||
if (isActive) {
|
||||
fetchAndHandleMusic();
|
||||
currentyPlaying.removeClass('hidden');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user