Skip to content

Commit c0af611

Browse files
authored
Merge pull request #602 from ArjunCodess/fix/cldvideoplayer-nextjs15-route-change
fix: resolve CldVideoPlayer route change issue #572
2 parents 0bf1f06 + 70975ed commit c0af611

File tree

1 file changed

+55
-17
lines changed

1 file changed

+55
-17
lines changed

next-cloudinary/src/components/CldVideoPlayer/CldVideoPlayer.tsx

Lines changed: 55 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, {useRef, MutableRefObject, useEffect, useId} from 'react';
1+
import React, {useRef, MutableRefObject, useEffect, useId, useState} from 'react';
22
import Script from 'next/script';
33
import Head from 'next/head';
44
import { CloudinaryVideoPlayer } from '@cloudinary-util/types';
@@ -29,6 +29,8 @@ const CldVideoPlayer = (props: CldVideoPlayerProps) => {
2929
} = props;
3030

3131
const uniqueId = useId();
32+
const [isScriptLoaded, setIsScriptLoaded] = useState(false);
33+
const [playerInitialized, setPlayerInitialized] = useState(false);
3234

3335
const cloudinaryConfig = getCloudinaryConfig(config);
3436
const playerOptions = getVideoPlayerOptions(props, cloudinaryConfig);
@@ -53,15 +55,6 @@ const CldVideoPlayer = (props: CldVideoPlayerProps) => {
5355
playerClassName = `${playerClassName} ${className}`;
5456
}
5557

56-
// Check if the same id is being used for multiple video instances.
57-
const checkForMultipleInstance = playerInstances.filter((id) => id === playerId).length > 1
58-
if (checkForMultipleInstance) {
59-
console.warn(`Multiple instances of the same video detected on the
60-
page which may cause some features to not work.
61-
Try adding a unique id to each player.`)
62-
} else {
63-
playerInstances.push(playerId)
64-
}
6558

6659
const events: Record<string, Function|undefined> = {
6760
error: onError,
@@ -86,31 +79,76 @@ const CldVideoPlayer = (props: CldVideoPlayerProps) => {
8679
}
8780

8881
/**
89-
* handleOnLoad
90-
* @description Stores the Cloudinary window instance to a ref when the widget script loads
82+
* disposePlayer
83+
* @description Properly dispose of the player instance and clean up
9184
*/
9285

93-
function handleOnLoad() {
94-
if ( 'cloudinary' in window ) {
86+
const disposePlayer = () => {
87+
if (playerRef.current?.videojs?.cloudinary) {
88+
playerRef.current.videojs.cloudinary.dispose();
89+
}
90+
// remove from global instances array
91+
playerInstances = playerInstances.filter((instanceId) => instanceId !== playerId);
92+
playerRef.current = null;
93+
setPlayerInitialized(false);
94+
};
95+
96+
/**
97+
* initializePlayer
98+
* @description Initialize the Cloudinary video player
99+
*/
100+
101+
const initializePlayer = () => {
102+
if (typeof window !== 'undefined' && 'cloudinary' in window && videoRef.current && !playerInitialized) {
95103
cloudinaryRef.current = window.cloudinary;
104+
105+
// dispose any existing player instance first to prevent conflicts
106+
if (playerRef.current) {
107+
disposePlayer();
108+
}
109+
96110
playerRef.current = cloudinaryRef.current.videoPlayer(videoRef.current, playerOptions);
111+
setPlayerInitialized(true);
97112

98113
Object.keys(events).forEach((key) => {
99114
if ( typeof events[key] === 'function' ) {
100115
playerRef.current?.on(key, handleEvent);
101116
}
102117
});
103118
}
119+
};
120+
121+
/**
122+
* handleOnLoad
123+
* @description Stores the Cloudinary window instance to a ref when the widget script loads
124+
*/
125+
126+
function handleOnLoad() {
127+
setIsScriptLoaded(true);
128+
if ( 'cloudinary' in window ) {
129+
initializePlayer();
130+
}
104131
}
105132

133+
// effect to handle component mounting and cleanup
106134
useEffect(() => {
135+
// initialize player if script is already loaded
136+
if (isScriptLoaded && typeof window !== 'undefined' && 'cloudinary' in window) {
137+
initializePlayer();
138+
}
107139

108140
return () => {
109-
playerRef.current?.videojs.cloudinary.dispose();
110-
playerInstances = playerInstances.filter((id) => id !== playerId)
111-
}
141+
disposePlayer();
142+
};
112143
}, []);
113144

145+
// effect to handle script loading after mount
146+
useEffect(() => {
147+
if (isScriptLoaded && !playerInitialized && typeof window !== 'undefined' && 'cloudinary' in window) {
148+
initializePlayer();
149+
}
150+
}, [isScriptLoaded, playerInitialized]);
151+
114152
/**
115153
*getPlayerRefs
116154
*/

0 commit comments

Comments
 (0)