switched to yt source
This commit is contained in:
committed by
GitHub
parent
ddf9d71386
commit
5d52b6bb11
+92
-3
@@ -2175,6 +2175,7 @@
|
||||
<button class="stocks-collapse-btn" onclick="toggleStocks()" id="stocksCollapseBtn">▲ STOCKS</button>
|
||||
<button class="stocks-collapse-btn" id="chatCollapseBtn" onclick="toggleChat()" title="Hide chat panel">💬 CHAT</button>
|
||||
<button class="stocks-collapse-btn" id="notifLogBtn" onclick="toggleNotifLog()" title="Notification log" style="position:relative;">🔔 NOTIFS<span class="notif-log-badge" id="notifLogBadge">0</span></button>
|
||||
<button class="stocks-collapse-btn" id="ytToggleBtn" onclick="toggleYtSource()" title="Switch between fishtank.rip and YouTube" style="border-color:var(--muted);color:var(--muted);">▶ YT SOURCE</button>
|
||||
</div>
|
||||
|
||||
<div id="apiControl" style="display:flex;align-items:center;gap:8px;">
|
||||
@@ -2873,8 +2874,9 @@
|
||||
["West Wing", "hwup-5"],
|
||||
["Jungle Room", "br4j-5"],
|
||||
["Computer Lab", "bbcl-5"],
|
||||
["Cameraman", "cameraman2-5"],
|
||||
["Job Board", "jobb-5"],
|
||||
["Arena", "bare-5"],
|
||||
["Cameraman", "cameraman2-5"],
|
||||
];
|
||||
|
||||
// Navigation polygons per camera slug
|
||||
@@ -2988,6 +2990,8 @@
|
||||
const DEFAULT_IDX = 1; // Director Mode
|
||||
const hlsInstances = {};
|
||||
let featuredIdx = DEFAULT_IDX;
|
||||
let ytSourceActive = true;
|
||||
let ytReadyCount = 0;
|
||||
// directorCell = which grid index currently shows the Director stream (null = director is in featured)
|
||||
let directorCell = null;
|
||||
|
||||
@@ -3019,7 +3023,15 @@
|
||||
fragLoadingMaxRetry: 3,
|
||||
manifestLoadingMaxRetry: 3,
|
||||
});
|
||||
hls.loadSource('http://localhost:3000/cam/' + slug + '/index.m3u8');
|
||||
const isYt = ytSourceActive && slug !== '__epyc__';
|
||||
if (isYt) {
|
||||
hls.config.startPosition = -1;
|
||||
hls.config.liveSyncDurationCount = 2;
|
||||
}
|
||||
const hlsSource = isYt
|
||||
? 'http://localhost:3000/yt-stream/' + slug
|
||||
: 'http://localhost:3000/cam/' + slug + '/index.m3u8';
|
||||
hls.loadSource(hlsSource);
|
||||
hls.attachMedia(video);
|
||||
|
||||
let reconnectOverlayTimer = null;
|
||||
@@ -3878,7 +3890,14 @@
|
||||
};
|
||||
|
||||
const hls = new Hls({ maxBufferLength: 2, maxMaxBufferLength: 4 });
|
||||
hls.loadSource('http://localhost:3000/cam/' + slug + '/index.m3u8');
|
||||
const ytSlugsSet = new Set(['dirc-5','foyr-5','gsrm-5','mrke-5','mrke2-5','hwdn-5',
|
||||
'dmrm-5','dmrm2-5','dmcl-5','jckz-5','brrr-5','brrr2-5','brpz-5','ktch-5',
|
||||
'dnrm-5','hwup-5','bbcl-5','br4j-5','bkny-5','codr-5','cfsl-5','jobb-5','bare-5']);
|
||||
if (ytSourceActive && !ytSlugsSet.has(slug)) { hls.destroy(); resolve(); return; }
|
||||
const thumbUrl = ytSourceActive
|
||||
? 'http://localhost:3000/yt-stream/' + slug
|
||||
: 'http://localhost:3000/cam/' + slug + '/index.m3u8';
|
||||
hls.loadSource(thumbUrl);
|
||||
hls.attachMedia(video);
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, () => video.play().catch(() => {}));
|
||||
video.addEventListener('timeupdate', capture, { once: true });
|
||||
@@ -3924,6 +3943,7 @@
|
||||
const featVideo = document.createElement('video');
|
||||
featVideo.playsInline = true;
|
||||
featVideo.autoplay = true;
|
||||
featVideo.crossOrigin = 'anonymous';
|
||||
const featLabel = document.createElement('div');
|
||||
featLabel.className = 'cam-label';
|
||||
featLabel.textContent = CAMERAS[DEFAULT_IDX][0].toUpperCase();
|
||||
@@ -3962,6 +3982,7 @@
|
||||
cell.className = 'cam-cell';
|
||||
cell.id = 'cam-' + i;
|
||||
cell.dataset.slug = slug;
|
||||
cell.dataset.idx = i;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.style.cssText = 'width:100%;height:100%;display:block;object-fit:cover;';
|
||||
canvas.id = 'canvas-' + i;
|
||||
@@ -4228,6 +4249,12 @@
|
||||
}
|
||||
}
|
||||
|
||||
if (msg._ft === 'yt_status') {
|
||||
ytReadyCount = msg.ready || 0;
|
||||
updateYtBtn();
|
||||
return;
|
||||
}
|
||||
|
||||
if (msg._ft === 'raw') {
|
||||
console.log('[FT-WS RAW]', msg.data);
|
||||
}
|
||||
@@ -4400,6 +4427,67 @@
|
||||
if (inlineChatAutoScroll) inlineFeed.scrollTop = inlineFeed.scrollHeight;
|
||||
}
|
||||
|
||||
// ── YouTube source toggle ────────────────────────────────────
|
||||
fetch('http://localhost:3000/yt-status').then(r => r.json()).then(d => {
|
||||
ytReadyCount = d.ready || 0;
|
||||
updateYtBtn();
|
||||
}).catch(() => {});
|
||||
|
||||
function updateYtBtn() {
|
||||
const btn = document.getElementById('ytToggleBtn');
|
||||
if (!btn) return;
|
||||
if (ytSourceActive) {
|
||||
btn.style.borderColor = '#e74c3c';
|
||||
btn.style.color = '#e74c3c';
|
||||
btn.textContent = '▶ YT LIVE';
|
||||
} else if (ytReadyCount > 0) {
|
||||
btn.style.borderColor = 'var(--green)';
|
||||
btn.style.color = 'var(--green)';
|
||||
btn.textContent = '▶ YT (' + ytReadyCount + ')';
|
||||
} else {
|
||||
btn.style.borderColor = 'var(--muted)';
|
||||
btn.style.color = 'var(--muted)';
|
||||
btn.textContent = '▶ YT SOURCE';
|
||||
}
|
||||
}
|
||||
|
||||
window.toggleYtSource = function() {
|
||||
ytSourceActive = !ytSourceActive;
|
||||
updateYtBtn();
|
||||
|
||||
// Switch featured cam — makeHls now reads ytSourceActive
|
||||
const wrap = document.getElementById('camFeaturedWrap');
|
||||
const featVideo = wrap && wrap.querySelector('video');
|
||||
const featSlug = CAMERAS[featuredIdx] && CAMERAS[featuredIdx][1];
|
||||
if (featVideo && featSlug) {
|
||||
if (hlsInstances['featured']) hlsInstances['featured'].destroy();
|
||||
hlsInstances['featured'] = makeHls(featSlug, featVideo, false);
|
||||
}
|
||||
|
||||
// Dim grid cells that have no YT source
|
||||
const NO_YT = new Set(['cameraman2-5','br3g-5']);
|
||||
const ytSlugs = new Set(['dirc-5','foyr-5','gsrm-5','mrke-5','mrke2-5','hwdn-5',
|
||||
'dmrm-5','dmrm2-5','dmcl-5','jckz-5','brrr-5','brrr2-5','brpz-5','ktch-5',
|
||||
'dnrm-5','hwup-5','bbcl-5','br4j-5','bkny-5','codr-5','cfsl-5','bare-5','jobb-5']);
|
||||
const grid = document.getElementById('cameraGrid');
|
||||
if (grid) {
|
||||
grid.querySelectorAll('.cam-cell').forEach(cell => {
|
||||
const slug = cell.dataset.slug;
|
||||
if (ytSourceActive && slug && !ytSlugs.has(slug)) {
|
||||
cell.style.opacity = '0.25';
|
||||
cell.style.pointerEvents = 'none';
|
||||
} else {
|
||||
cell.style.opacity = '';
|
||||
cell.style.pointerEvents = '';
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Thumbnails are canvas-based — just refresh them from new source
|
||||
refreshAllThumbnails();
|
||||
};
|
||||
// ── End YouTube source toggle ─────────────────────────────────
|
||||
|
||||
// ── Floor plan ───────────────────────────────────────────────
|
||||
const FLOOR_ROOMS = {
|
||||
down: [
|
||||
@@ -4553,6 +4641,7 @@
|
||||
cell.className = 'cam-cell';
|
||||
cell.id = 'cam-' + i;
|
||||
cell.dataset.slug = slug;
|
||||
cell.dataset.idx = i;
|
||||
const canvas = document.createElement('canvas');
|
||||
canvas.style.cssText = 'width:100%;height:100%;display:block;object-fit:cover;';
|
||||
canvas.id = 'canvas-' + i;
|
||||
|
||||
Reference in New Issue
Block a user