diff --git a/src/plugins/crossfade/index.ts b/src/plugins/crossfade/index.ts index ddf3093e9a..126fa3eda3 100644 --- a/src/plugins/crossfade/index.ts +++ b/src/plugins/crossfade/index.ts @@ -188,7 +188,8 @@ export default createPlugin< onPlayerApiReady() { let transitionAudio: Howl; // Howler audio used to fade out the current music let firstVideo = true; - let waitForTransition: Promise; + let waitForTransition: Promise = Promise.resolve(); + let originalVolume: number = 1; const getStreamURL = async (videoID: string): Promise => this.ipc?.invoke('audio-url', videoID) as Promise; @@ -199,6 +200,13 @@ export default createPlugin< const isReadyToCrossfade = () => transitionAudio && transitionAudio.state() === 'loaded'; + const ensureVideoVolume = () => { + const video = document.querySelector('video'); + if (video && video.volume === 0 && originalVolume > 0) { + video.volume = originalVolume; + } + }; + const watchVideoIDChanges = (cb: (id: string) => void) => { window.navigation.addEventListener('navigate', (event) => { const currentVideoID = getVideoIDFromURL( @@ -216,6 +224,7 @@ export default createPlugin< cb(nextVideoID); }); } else { + ensureVideoVolume(); cb(nextVideoID); firstVideo = false; } @@ -239,6 +248,10 @@ export default createPlugin< const syncVideoWithTransitionAudio = () => { const video = document.querySelector('video')!; + if (video.volume > 0) { + originalVolume = video.volume; + } + const videoFader = new VolumeFader(video, { fadeScaling: this.config?.fadeScaling, fadeDuration: this.config?.fadeInDuration, @@ -247,29 +260,40 @@ export default createPlugin< transitionAudio.play(); transitionAudio.seek(video.currentTime); - video.addEventListener('seeking', () => { + const onSeeking = () => { transitionAudio.seek(video.currentTime); - }); + }; - video.addEventListener('pause', () => { + const onPause = () => { transitionAudio.pause(); - }); + }; - video.addEventListener('play', () => { + const onPlay = () => { transitionAudio.play(); transitionAudio.seek(video.currentTime); // Fade in - const videoVolume = video.volume; + const videoVolume = originalVolume || video.volume || 1; video.volume = 0; videoFader.fadeTo(videoVolume); - }); + }; + + video.addEventListener('seeking', onSeeking); + video.addEventListener('pause', onPause); + video.addEventListener('play', onPlay); + + if (!video.paused) { + const videoVolume = originalVolume || video.volume || 1; + if (video.volume === 0) { + videoFader.fadeTo(videoVolume); + } + } // Exit just before the end for the transition const transitionBeforeEnd = () => { if ( video.currentTime >= - video.duration - (this.config?.secondsBeforeEnd ?? 0) && + video.duration - (this.config?.secondsBeforeEnd ?? 0) && isReadyToCrossfade() ) { video.removeEventListener('timeupdate', transitionBeforeEnd); @@ -284,6 +308,7 @@ export default createPlugin< const crossfade = (cb: () => void) => { if (!isReadyToCrossfade()) { + ensureVideoVolume() cb(); return; } @@ -295,8 +320,12 @@ export default createPlugin< const video = document.querySelector('video')!; + if (video.volume > 0) { + originalVolume = video.volume; + } + const fader = new VolumeFader(transitionAudio._sounds[0]._node, { - initialVolume: video.volume, + initialVolume: originalVolume, fadeScaling: this.config?.fadeScaling, fadeDuration: this.config?.fadeOutDuration, }); @@ -313,6 +342,7 @@ export default createPlugin< await waitForTransition; const url = await getStreamURL(videoID); if (!url) { + ensureVideoVolume(); return; }