player element angepasst
This commit is contained in:
+104
@@ -726,6 +726,18 @@ td {
|
||||
audio {
|
||||
width: 280px;
|
||||
max-width: 100%;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
/* Die Positionsleiste der nativen Audio-Steuerung besser bedienbar machen.
|
||||
Chromium/WebKit erlaubt zusätzlich eine direkte Vergrößerung der Timeline. */
|
||||
audio::-webkit-media-controls-timeline {
|
||||
height: 8px;
|
||||
}
|
||||
|
||||
audio::-webkit-media-controls-current-time-display,
|
||||
audio::-webkit-media-controls-time-remaining-display {
|
||||
font-size: 13px;
|
||||
}
|
||||
|
||||
a.button {
|
||||
@@ -1010,6 +1022,98 @@ function applyFilters() {
|
||||
);
|
||||
applyFilters();
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// Wiedergabeposition merken
|
||||
// ------------------------------------------------------------
|
||||
// Die Position wird pro Datei und Browser lokal gespeichert.
|
||||
// Dadurch kann eine Aufnahme später an der zuletzt gehörten Stelle
|
||||
// fortgesetzt werden, ohne dass dafür ein Server-Login oder eine
|
||||
// Datenbank notwendig ist.
|
||||
const PLAYBACK_KEY_PREFIX = 'event-audio-playback:';
|
||||
const PLAYBACK_SAVE_INTERVAL = 5000;
|
||||
|
||||
function playbackKey(audio) {
|
||||
const source = audio.querySelector('source');
|
||||
return source
|
||||
? PLAYBACK_KEY_PREFIX + source.getAttribute('src')
|
||||
: null;
|
||||
}
|
||||
|
||||
function savePlaybackPosition(audio) {
|
||||
const key = playbackKey(audio);
|
||||
if (!key || !Number.isFinite(audio.currentTime) || audio.currentTime <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
localStorage.setItem(key, JSON.stringify({
|
||||
position: audio.currentTime,
|
||||
savedAt: Date.now()
|
||||
}));
|
||||
} catch (error) {
|
||||
console.warn('Wiedergabeposition konnte nicht gespeichert werden:', error);
|
||||
}
|
||||
}
|
||||
|
||||
function restorePlaybackPosition(audio) {
|
||||
const key = playbackKey(audio);
|
||||
if (!key) return;
|
||||
|
||||
try {
|
||||
const saved = JSON.parse(localStorage.getItem(key) || 'null');
|
||||
if (!saved || !Number.isFinite(saved.position) || saved.position <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Erst setzen, wenn die Metadaten/Dauer bekannt sind.
|
||||
if (Number.isFinite(audio.duration) && audio.duration > 0) {
|
||||
const position = Math.min(saved.position, Math.max(0, audio.duration - 0.5));
|
||||
if (position > 0) {
|
||||
audio.currentTime = position;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Wiedergabeposition konnte nicht wiederhergestellt werden:', error);
|
||||
}
|
||||
}
|
||||
|
||||
document.querySelectorAll('.finished-row audio').forEach(audio => {
|
||||
let lastSaved = 0;
|
||||
|
||||
audio.addEventListener('loadedmetadata', () => {
|
||||
restorePlaybackPosition(audio);
|
||||
});
|
||||
|
||||
audio.addEventListener('timeupdate', () => {
|
||||
const now = Date.now();
|
||||
if (now - lastSaved >= PLAYBACK_SAVE_INTERVAL) {
|
||||
savePlaybackPosition(audio);
|
||||
lastSaved = now;
|
||||
}
|
||||
});
|
||||
|
||||
audio.addEventListener('pause', () => {
|
||||
if (!audio.ended) {
|
||||
savePlaybackPosition(audio);
|
||||
lastSaved = Date.now();
|
||||
}
|
||||
});
|
||||
|
||||
audio.addEventListener('ended', () => {
|
||||
const key = playbackKey(audio);
|
||||
if (!key) return;
|
||||
try {
|
||||
localStorage.removeItem(key);
|
||||
} catch (error) {
|
||||
console.warn('Gespeicherte Wiedergabeposition konnte nicht gelöscht werden:', error);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
window.addEventListener('beforeunload', () => {
|
||||
document.querySelectorAll('.finished-row audio').forEach(savePlaybackPosition);
|
||||
});
|
||||
|
||||
async function updateLiveSection() {
|
||||
try {
|
||||
const response = await fetch("/api/live", { cache: "no-store" });
|
||||
|
||||
Reference in New Issue
Block a user