Spaces:
Running
Running
Update index.html
Browse files- index.html +50 -12
index.html
CHANGED
|
@@ -61,6 +61,8 @@ body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--text);marg
|
|
| 61 |
.ln-video-clip-info{font-size:10px;color:rgba(255,255,255,0.6);margin-top:2px;font-family:'JetBrains Mono',monospace;}
|
| 62 |
.ln-video-live-badge{position:absolute;top:10px;left:10px;display:flex;align-items:center;gap:5px;background:rgba(255,0,0,0.9);padding:3px 10px;border-radius:4px;font-size:10px;font-weight:900;color:#fff;letter-spacing:1px;animation:breakPulse 2s infinite;}
|
| 63 |
.ln-video-live-badge .dot{width:6px;height:6px;border-radius:50%;background:#fff;animation:pulse 1.5s infinite;}
|
|
|
|
|
|
|
| 64 |
.ln-video-progress{position:absolute;bottom:0;left:0;height:3px;background:#ff0000;transition:width 0.3s linear;z-index:2;}
|
| 65 |
.ln-video-meta{padding:10px 12px;background:#0a0a18;border-top:1px solid rgba(255,255,255,0.06);flex:1;display:flex;flex-direction:column;gap:6px;overflow-y:auto;}
|
| 66 |
.ln-video-indicator{display:flex;gap:6px;justify-content:center;padding:4px 0;}
|
|
@@ -802,12 +804,13 @@ body{font-family:'Outfit',sans-serif;background:var(--bg);color:var(--text);marg
|
|
| 802 |
<!-- ===== LEFT: ANCHOR VIDEO ===== -->
|
| 803 |
<div class="ln-video-col">
|
| 804 |
<div class="ln-video-wrap">
|
| 805 |
-
<video id="lnVideo" playsinline autoplay
|
| 806 |
<div class="ln-video-live-badge"><span class="dot"></span>ON AIR</div>
|
|
|
|
| 807 |
<div class="ln-video-progress" id="lnVideoProgress"></div>
|
| 808 |
<div class="ln-video-overlay">
|
| 809 |
<div class="ln-video-anchor-name" id="lnVideoAnchorName">P&D LIVE ANCHOR</div>
|
| 810 |
-
<div class="ln-video-clip-info" id="lnVideoClipInfo">
|
| 811 |
</div>
|
| 812 |
</div>
|
| 813 |
<div class="ln-video-meta">
|
|
@@ -2774,34 +2777,36 @@ async function fetchNpcProfile(agentId){
|
|
| 2774 |
|
| 2775 |
/* ====== 🔴 P&D LIVE NEWS ====== */
|
| 2776 |
|
| 2777 |
-
/* ── Video Player: V4
|
| 2778 |
const LN_VIDEO_CLIPS = [
|
| 2779 |
{src:'/videos/V4.mp4', label:'Newsroom Command', anchor:'NEWSROOM'},
|
|
|
|
| 2780 |
];
|
| 2781 |
let lnVideoIdx = 0, lnVideoRotateTimer = null, lnVideoProgressTimer = null, lnVideoReady = false;
|
| 2782 |
|
| 2783 |
function initVideoPlayer(){
|
| 2784 |
const vid = document.getElementById('lnVideo');
|
| 2785 |
if(!vid) return;
|
| 2786 |
-
// Load
|
| 2787 |
vid.src = LN_VIDEO_CLIPS[0].src;
|
| 2788 |
vid.muted = false; // Sound ON
|
| 2789 |
-
vid.loop =
|
| 2790 |
vid.playsInline = true;
|
| 2791 |
vid.load();
|
| 2792 |
// On canplay, start playback with sound
|
| 2793 |
vid.addEventListener('canplay', function onFirstPlay(){
|
| 2794 |
vid.muted = false;
|
|
|
|
| 2795 |
vid.play().catch(()=>{
|
| 2796 |
-
// Browser may block unmuted autoplay; try muted first then unmute
|
| 2797 |
vid.muted = true;
|
|
|
|
| 2798 |
vid.play().then(()=>{
|
| 2799 |
-
// Unmute after a short delay or on user interaction
|
| 2800 |
vid.muted = false;
|
|
|
|
| 2801 |
}).catch(()=>{});
|
| 2802 |
-
// Also try unmuting on first user interaction
|
| 2803 |
const unmuteOnClick = ()=>{
|
| 2804 |
vid.muted = false;
|
|
|
|
| 2805 |
vid.play().catch(()=>{});
|
| 2806 |
document.removeEventListener('click', unmuteOnClick);
|
| 2807 |
document.removeEventListener('touchstart', unmuteOnClick);
|
|
@@ -2812,17 +2817,36 @@ function initVideoPlayer(){
|
|
| 2812 |
lnVideoReady = true;
|
| 2813 |
vid.removeEventListener('canplay', onFirstPlay);
|
| 2814 |
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2815 |
// Progress bar
|
| 2816 |
vid.addEventListener('timeupdate', updateVideoProgress);
|
| 2817 |
updateVideoLabel(0);
|
| 2818 |
}
|
| 2819 |
|
| 2820 |
function startVideoRotation(){
|
| 2821 |
-
//
|
| 2822 |
}
|
| 2823 |
|
| 2824 |
function switchVideoClip(idx){
|
| 2825 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2826 |
}
|
| 2827 |
|
| 2828 |
function updateVideoIndicator(idx){
|
|
@@ -2830,11 +2854,25 @@ function updateVideoIndicator(idx){
|
|
| 2830 |
}
|
| 2831 |
|
| 2832 |
function updateVideoLabel(idx){
|
| 2833 |
-
const clip = LN_VIDEO_CLIPS[
|
| 2834 |
const nameEl = document.getElementById('lnVideoAnchorName');
|
| 2835 |
const infoEl = document.getElementById('lnVideoClipInfo');
|
| 2836 |
if(nameEl) nameEl.textContent = clip.anchor;
|
| 2837 |
-
if(infoEl) infoEl.textContent =
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2838 |
}
|
| 2839 |
|
| 2840 |
function updateVideoProgress(){
|
|
|
|
| 61 |
.ln-video-clip-info{font-size:10px;color:rgba(255,255,255,0.6);margin-top:2px;font-family:'JetBrains Mono',monospace;}
|
| 62 |
.ln-video-live-badge{position:absolute;top:10px;left:10px;display:flex;align-items:center;gap:5px;background:rgba(255,0,0,0.9);padding:3px 10px;border-radius:4px;font-size:10px;font-weight:900;color:#fff;letter-spacing:1px;animation:breakPulse 2s infinite;}
|
| 63 |
.ln-video-live-badge .dot{width:6px;height:6px;border-radius:50%;background:#fff;animation:pulse 1.5s infinite;}
|
| 64 |
+
.ln-mute-btn{position:absolute;top:10px;right:10px;z-index:3;width:36px;height:36px;border-radius:50%;border:none;background:rgba(0,0,0,0.65);color:#fff;font-size:16px;cursor:pointer;display:flex;align-items:center;justify-content:center;backdrop-filter:blur(4px);transition:all 0.2s;line-height:1;}
|
| 65 |
+
.ln-mute-btn:hover{background:rgba(255,255,255,0.2);transform:scale(1.1);}
|
| 66 |
.ln-video-progress{position:absolute;bottom:0;left:0;height:3px;background:#ff0000;transition:width 0.3s linear;z-index:2;}
|
| 67 |
.ln-video-meta{padding:10px 12px;background:#0a0a18;border-top:1px solid rgba(255,255,255,0.06);flex:1;display:flex;flex-direction:column;gap:6px;overflow-y:auto;}
|
| 68 |
.ln-video-indicator{display:flex;gap:6px;justify-content:center;padding:4px 0;}
|
|
|
|
| 804 |
<!-- ===== LEFT: ANCHOR VIDEO ===== -->
|
| 805 |
<div class="ln-video-col">
|
| 806 |
<div class="ln-video-wrap">
|
| 807 |
+
<video id="lnVideo" playsinline autoplay></video>
|
| 808 |
<div class="ln-video-live-badge"><span class="dot"></span>ON AIR</div>
|
| 809 |
+
<button id="lnMuteBtn" class="ln-mute-btn" onclick="toggleVideoMute()" title="Toggle Sound">🔊</button>
|
| 810 |
<div class="ln-video-progress" id="lnVideoProgress"></div>
|
| 811 |
<div class="ln-video-overlay">
|
| 812 |
<div class="ln-video-anchor-name" id="lnVideoAnchorName">P&D LIVE ANCHOR</div>
|
| 813 |
+
<div class="ln-video-clip-info" id="lnVideoClipInfo">Newsroom Command · Live Broadcast</div>
|
| 814 |
</div>
|
| 815 |
</div>
|
| 816 |
<div class="ln-video-meta">
|
|
|
|
| 2777 |
|
| 2778 |
/* ====== 🔴 P&D LIVE NEWS ====== */
|
| 2779 |
|
| 2780 |
+
/* ── Video Player: V4 ↔ V5 Continuous Loop with Sound ── */
|
| 2781 |
const LN_VIDEO_CLIPS = [
|
| 2782 |
{src:'/videos/V4.mp4', label:'Newsroom Command', anchor:'NEWSROOM'},
|
| 2783 |
+
{src:'/videos/V5.mp4', label:'Live Studio', anchor:'LIVE STUDIO'},
|
| 2784 |
];
|
| 2785 |
let lnVideoIdx = 0, lnVideoRotateTimer = null, lnVideoProgressTimer = null, lnVideoReady = false;
|
| 2786 |
|
| 2787 |
function initVideoPlayer(){
|
| 2788 |
const vid = document.getElementById('lnVideo');
|
| 2789 |
if(!vid) return;
|
| 2790 |
+
// Load first clip (V4)
|
| 2791 |
vid.src = LN_VIDEO_CLIPS[0].src;
|
| 2792 |
vid.muted = false; // Sound ON
|
| 2793 |
+
vid.loop = false; // No loop — we handle rotation manually
|
| 2794 |
vid.playsInline = true;
|
| 2795 |
vid.load();
|
| 2796 |
// On canplay, start playback with sound
|
| 2797 |
vid.addEventListener('canplay', function onFirstPlay(){
|
| 2798 |
vid.muted = false;
|
| 2799 |
+
syncMuteBtn();
|
| 2800 |
vid.play().catch(()=>{
|
|
|
|
| 2801 |
vid.muted = true;
|
| 2802 |
+
syncMuteBtn();
|
| 2803 |
vid.play().then(()=>{
|
|
|
|
| 2804 |
vid.muted = false;
|
| 2805 |
+
syncMuteBtn();
|
| 2806 |
}).catch(()=>{});
|
|
|
|
| 2807 |
const unmuteOnClick = ()=>{
|
| 2808 |
vid.muted = false;
|
| 2809 |
+
syncMuteBtn();
|
| 2810 |
vid.play().catch(()=>{});
|
| 2811 |
document.removeEventListener('click', unmuteOnClick);
|
| 2812 |
document.removeEventListener('touchstart', unmuteOnClick);
|
|
|
|
| 2817 |
lnVideoReady = true;
|
| 2818 |
vid.removeEventListener('canplay', onFirstPlay);
|
| 2819 |
});
|
| 2820 |
+
// On ended → switch to next clip (V4→V5→V4→...)
|
| 2821 |
+
vid.addEventListener('ended', ()=>{
|
| 2822 |
+
const nextIdx = (lnVideoIdx + 1) % LN_VIDEO_CLIPS.length;
|
| 2823 |
+
switchVideoClip(nextIdx);
|
| 2824 |
+
});
|
| 2825 |
// Progress bar
|
| 2826 |
vid.addEventListener('timeupdate', updateVideoProgress);
|
| 2827 |
updateVideoLabel(0);
|
| 2828 |
}
|
| 2829 |
|
| 2830 |
function startVideoRotation(){
|
| 2831 |
+
// Rotation handled by 'ended' event — no timer needed
|
| 2832 |
}
|
| 2833 |
|
| 2834 |
function switchVideoClip(idx){
|
| 2835 |
+
const vid = document.getElementById('lnVideo');
|
| 2836 |
+
if(!vid) return;
|
| 2837 |
+
const wasMuted = vid.muted; // preserve mute state across clips
|
| 2838 |
+
lnVideoIdx = idx;
|
| 2839 |
+
vid.classList.add('fade-out');
|
| 2840 |
+
setTimeout(()=>{
|
| 2841 |
+
vid.src = LN_VIDEO_CLIPS[idx].src;
|
| 2842 |
+
vid.muted = wasMuted;
|
| 2843 |
+
vid.load();
|
| 2844 |
+
vid.play().then(()=>{
|
| 2845 |
+
vid.classList.remove('fade-out');
|
| 2846 |
+
syncMuteBtn();
|
| 2847 |
+
}).catch(()=> vid.classList.remove('fade-out'));
|
| 2848 |
+
}, 400);
|
| 2849 |
+
updateVideoLabel(idx);
|
| 2850 |
}
|
| 2851 |
|
| 2852 |
function updateVideoIndicator(idx){
|
|
|
|
| 2854 |
}
|
| 2855 |
|
| 2856 |
function updateVideoLabel(idx){
|
| 2857 |
+
const clip = LN_VIDEO_CLIPS[idx];
|
| 2858 |
const nameEl = document.getElementById('lnVideoAnchorName');
|
| 2859 |
const infoEl = document.getElementById('lnVideoClipInfo');
|
| 2860 |
if(nameEl) nameEl.textContent = clip.anchor;
|
| 2861 |
+
if(infoEl) infoEl.textContent = `${clip.label} · Live Broadcast`;
|
| 2862 |
+
}
|
| 2863 |
+
|
| 2864 |
+
function toggleVideoMute(){
|
| 2865 |
+
const vid = document.getElementById('lnVideo');
|
| 2866 |
+
const btn = document.getElementById('lnMuteBtn');
|
| 2867 |
+
if(!vid || !btn) return;
|
| 2868 |
+
vid.muted = !vid.muted;
|
| 2869 |
+
btn.textContent = vid.muted ? '🔇' : '🔊';
|
| 2870 |
+
}
|
| 2871 |
+
|
| 2872 |
+
function syncMuteBtn(){
|
| 2873 |
+
const vid = document.getElementById('lnVideo');
|
| 2874 |
+
const btn = document.getElementById('lnMuteBtn');
|
| 2875 |
+
if(vid && btn) btn.textContent = vid.muted ? '🔇' : '🔊';
|
| 2876 |
}
|
| 2877 |
|
| 2878 |
function updateVideoProgress(){
|