Custom video player

This commit is contained in:
2026-07-26 22:26:37 +02:00
parent 7553b9f895
commit 2e3918def4
13 changed files with 3547 additions and 905 deletions
+72
View File
@@ -0,0 +1,72 @@
// Engagement heatmap tracking
// Samples the user's current time while playing and sends batched segment data to the server.
// Only tracks segment >= 1 (excludes 0-10s).
// Only calls the endpoint when the user is logged in.
let engagementInterval;
let engagementSegments = new Set();
let engagementReportInterval;
const SEGMENT_DURATION = 10; // seconds per segment
const SAMPLE_INTERVAL = 5000; // sample every 5s
const REPORT_INTERVAL = 15000; // send batch every 15s
function isAuthenticated() {
const el = document.getElementById('auth_check');
return el && el.value === '1';
}
function sendEngagement(episodeId, segments) {
if (!isAuthenticated()) return;
window.axios.post('/player/engagement', {
episode_id: episodeId,
segments: segments,
}).catch(() => {
// Fire-and-forget: silently ignore network errors
});
}
export function startEngagementTracking(episodeId) {
engagementSegments.clear();
// Sample current time while playing
engagementInterval = setInterval(() => {
const video = document.querySelector('video');
if (!video || video.paused) return;
const segment = Math.floor(video.currentTime / SEGMENT_DURATION);
// Skip segment 0 (0-10s) — no need to track the very start
if (segment >= 1) {
engagementSegments.add(segment);
}
}, SAMPLE_INTERVAL);
// Batch report to server
engagementReportInterval = setInterval(() => {
if (engagementSegments.size === 0) return;
const segments = Array.from(engagementSegments);
engagementSegments.clear();
sendEngagement(episodeId, segments);
}, REPORT_INTERVAL);
// Flush remaining segments & cleanup on page unload
const cleanup = () => {
clearInterval(engagementInterval);
clearInterval(engagementReportInterval);
if (engagementSegments.size > 0) {
const segments = Array.from(engagementSegments);
engagementSegments.clear();
sendEngagement(episodeId, segments);
}
};
window.addEventListener('beforeunload', cleanup);
}
export function stopEngagementTracking() {
if (engagementInterval) clearInterval(engagementInterval);
if (engagementReportInterval) clearInterval(engagementReportInterval);
}