1- import React , { useRef , MutableRefObject , useEffect , useId } from 'react' ;
1+ import React , { useRef , MutableRefObject , useEffect , useId , useState } from 'react' ;
22import Script from 'next/script' ;
33import Head from 'next/head' ;
44import { 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