diff --git a/public/style.css b/public/style.css index b6841ea..b7c0b8a 100644 --- a/public/style.css +++ b/public/style.css @@ -48,6 +48,7 @@ h1 { font-size: 2.5rem; margin-bottom: 0.5rem; background: linear-gradient(to right, #fff, var(--text-secondary)); + background-clip: text; -webkit-background-clip: text; -webkit-text-fill-color: transparent; } @@ -178,18 +179,55 @@ video.active { overflow: hidden; } -.viewer-container video { +.video-wrapper { width: 100%; height: 100%; - object-fit: contain; - border-radius: 0; - border: none; - margin: 0; display: none; } -.viewer-container video.active { +.video-wrapper.active { display: block; + animation: fadeIn 0.5s ease forwards; +} + +/* Custom Video.js Overrides for Premium Glass Look */ +.video-js { + width: 100% !important; + height: 100% !important; + background-color: transparent !important; +} + +.video-js .vjs-tech { + object-fit: contain; +} + +.vjs-theme-city .vjs-control-bar { + background: rgba(15, 23, 42, 0.85) !important; + backdrop-filter: blur(8px) !important; + border-top: 1px solid rgba(255, 255, 255, 0.1) !important; + height: 50px !important; + padding: 0 10px !important; +} + +.vjs-theme-city .vjs-play-progress, +.vjs-theme-city .vjs-volume-level { + background: var(--accent-color) !important; +} + +.vjs-theme-city .vjs-big-play-button { + background: rgba(15, 23, 42, 0.85) !important; + backdrop-filter: blur(8px) !important; + border: 1px solid rgba(255, 255, 255, 0.1) !important; + border-radius: 50% !important; + width: 80px !important; + height: 80px !important; + line-height: 80px !important; + transition: all 0.3s ease !important; +} + +.vjs-theme-city .vjs-big-play-button:hover { + background: var(--accent-color) !important; + transform: scale(1.1) !important; } .overlay { diff --git a/public/viewer.html b/public/viewer.html index 5fa07af..3090a1f 100644 --- a/public/viewer.html +++ b/public/viewer.html @@ -24,7 +24,6 @@ controls preload="auto" playsinline - data-setup='{"fluid": true}' >

To view this video please enable JavaScript, and consider upgrading to a diff --git a/public/viewer.js b/public/viewer.js index ddd6d8a..5a7d0c0 100644 --- a/public/viewer.js +++ b/public/viewer.js @@ -1,6 +1,19 @@ const socket = io(); -const remoteVideo = document.getElementById('remoteVideo'); const overlay = document.getElementById('overlay'); +const videoWrapper = document.getElementById('videoWrapper'); + +// Initialize video.js player +const player = videojs('remoteVideo', { + controls: true, + autoplay: true, + preload: 'auto', + fluid: true, + controlBar: { + volumePanel: { inline: false }, + fullscreenToggle: true, + pictureInPictureToggle: true + } +}); let peerConnection; const config = { @@ -18,9 +31,27 @@ socket.on('offer', (id, description) => { peerConnection = new RTCPeerConnection(config); peerConnection.ontrack = event => { - remoteVideo.srcObject = event.streams[0]; - remoteVideo.classList.add('active'); - overlay.classList.add('hidden'); + // Need to set srcObject on the raw video element inside video.js + const videoElement = document.querySelector('#remoteVideo_html5_api'); + if (videoElement) { + videoElement.srcObject = event.streams[0]; + + // Notify video.js of the media change + player.trigger('loadstart'); + player.trigger('loadedmetadata'); + player.trigger('loadeddata'); + player.trigger('canplay'); + player.trigger('playing'); + + videoWrapper.classList.add('active'); + overlay.classList.add('hidden'); + + // Force play after stream is attached + setTimeout(() => { + player.muted(true); // Ensure autoplay policies don't block visuals + player.play().catch(e => console.error("Autoplay prevented:", e)); + }, 100); + } }; peerConnection.onicecandidate = event => { @@ -54,8 +85,11 @@ socket.on('disconnectPeer', () => { peerConnection.close(); peerConnection = null; } - remoteVideo.classList.remove('active'); - remoteVideo.srcObject = null; + + videoWrapper.classList.remove('active'); + const videoElement = document.querySelector('#remoteVideo_html5_api'); + if (videoElement) videoElement.srcObject = null; + overlay.classList.remove('hidden'); overlay.querySelector('h1').innerText = 'Stream Ended'; overlay.querySelector('.status-indicator span:last-child').innerText = 'Waiting for new stream...';