Improve video playback by ensuring correct volume and mute settings

Update VideoCard component to correctly manage muted state and volume across HLS.js and native HLS playback events, fixing issues where audio was not playing or was stuck muted.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 45a1dcfc-f8a2-475a-a6b9-96fbb841dc27
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/60d372ff-2c10-46c7-b01b-10c3435136b0/45a1dcfc-f8a2-475a-a6b9-96fbb841dc27/HOGfHKv
This commit is contained in:
sebastjanartic 2025-09-17 11:04:36 +00:00
parent 2936285412
commit 0cb6846478
2 changed files with 60 additions and 14 deletions

View File

@ -16,7 +16,7 @@ localPort = 5000
externalPort = 80 externalPort = 80
[[ports]] [[ports]]
localPort = 43411 localPort = 40259
externalPort = 3000 externalPort = 3000
[env] [env]

View File

@ -157,28 +157,53 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
hlsRef.current = hls; hlsRef.current = hls;
hls.on(Hls.Events.MANIFEST_PARSED, () => { hls.on(Hls.Events.MANIFEST_PARSED, () => {
// Set muted state before playing // Set muted state and volume before playing
videoElement.muted = isMuted; videoElement.muted = isMuted;
if (isMuted) {
videoElement.volume = 0;
} else if (videoElement.volume === 0) {
videoElement.volume = 0.8;
}
videoElement.play().catch(e => console.log('Preview autoplay failed:', e)); videoElement.play().catch(e => console.log('Preview autoplay failed:', e));
}); });
hls.on(Hls.Events.MEDIA_ATTACHED, () => { hls.on(Hls.Events.MEDIA_ATTACHED, () => {
// Set muted state after media is attached // Set muted state and volume after media is attached
videoElement.muted = isMuted; videoElement.muted = isMuted;
if (isMuted) {
videoElement.volume = 0;
} else if (videoElement.volume === 0) {
videoElement.volume = 0.8;
}
videoElement.addEventListener('loadedmetadata', () => { videoElement.addEventListener('loadedmetadata', () => {
setDuration(videoElement.duration); setDuration(videoElement.duration);
// Ensure muted state is preserved after metadata loads // Ensure muted state and volume are preserved after metadata loads
videoElement.muted = isMuted; videoElement.muted = isMuted;
if (isMuted) {
videoElement.volume = 0;
} else if (videoElement.volume === 0) {
videoElement.volume = 0.8;
}
}); });
}); });
} else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) { } else if (videoElement.canPlayType('application/vnd.apple.mpegurl')) {
// Safari native HLS support // Safari native HLS support
videoElement.src = video.videoUrl; videoElement.src = video.videoUrl;
videoElement.muted = isMuted; videoElement.muted = isMuted;
if (isMuted) {
videoElement.volume = 0;
} else if (videoElement.volume === 0) {
videoElement.volume = 0.8;
}
videoElement.addEventListener('loadedmetadata', () => { videoElement.addEventListener('loadedmetadata', () => {
setDuration(videoElement.duration); setDuration(videoElement.duration);
// Ensure muted state is preserved after metadata loads // Ensure muted state and volume are preserved after metadata loads
videoElement.muted = isMuted; videoElement.muted = isMuted;
if (isMuted) {
videoElement.volume = 0;
} else if (videoElement.volume === 0) {
videoElement.volume = 0.8;
}
}); });
videoElement.play().catch(e => console.log('Preview autoplay failed:', e)); videoElement.play().catch(e => console.log('Preview autoplay failed:', e));
} }
@ -242,25 +267,37 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
controls={false} controls={false}
disablePictureInPicture disablePictureInPicture
onLoadStart={() => { onLoadStart={() => {
// Force muted state on load start // Set muted state and appropriate volume on load start
if (videoRef.current) { if (videoRef.current) {
videoRef.current.muted = isMuted; videoRef.current.muted = isMuted;
videoRef.current.volume = 0; if (isMuted) {
videoRef.current.volume = 0;
} else if (videoRef.current.volume === 0) {
videoRef.current.volume = 0.8;
}
} }
}} }}
onError={() => {}} onError={() => {}}
onPlay={() => { onPlay={() => {
// Force muted state on play // Set muted state and appropriate volume on play
if (videoRef.current) { if (videoRef.current) {
videoRef.current.muted = isMuted; videoRef.current.muted = isMuted;
videoRef.current.volume = 0; if (isMuted) {
videoRef.current.volume = 0;
} else if (videoRef.current.volume === 0) {
videoRef.current.volume = 0.8;
}
} }
}} }}
onCanPlay={() => { onCanPlay={() => {
// Force muted state when video can play // Set muted state and appropriate volume when video can play
if (videoRef.current) { if (videoRef.current) {
videoRef.current.muted = isMuted; videoRef.current.muted = isMuted;
videoRef.current.volume = 0; if (isMuted) {
videoRef.current.volume = 0;
} else if (videoRef.current.volume === 0) {
videoRef.current.volume = 0.8;
}
} }
}} }}
onTimeUpdate={(e) => setCurrentTime(e.currentTarget.currentTime)} onTimeUpdate={(e) => setCurrentTime(e.currentTarget.currentTime)}
@ -313,13 +350,22 @@ export default function VideoCard({ video, onClick, className = "", hideOverlay
try { try {
videoRef.current.muted = newMutedState; videoRef.current.muted = newMutedState;
if (!newMutedState) { if (!newMutedState) {
// When unmuting, ensure volume is audible // When unmuting, ensure volume is audible and play if paused
videoRef.current.volume = 0.8; if (videoRef.current.volume === 0) {
videoRef.current.volume = 0.8;
}
if (videoRef.current.paused) {
videoRef.current.play().catch(e => console.log('Unmute play failed:', e));
}
} else {
// When muting, set volume to 0
videoRef.current.volume = 0;
} }
console.log('🔊 Mute button clicked:', { console.log('🔊 Mute button clicked:', {
newMutedState, newMutedState,
videoMuted: videoRef.current.muted, videoMuted: videoRef.current.muted,
videoVolume: videoRef.current.volume videoVolume: videoRef.current.volume,
videoPaused: videoRef.current.paused
}); });
} catch (error) { } catch (error) {
console.error('Error setting video audio:', error); console.error('Error setting video audio:', error);