11import React , {
22 forwardRef ,
3+ useEffect ,
34 useImperativeHandle ,
45 useRef ,
5- useEffect ,
6+ useState ,
67} from 'react' ;
78import { cnx } from '../../../util' ;
8- import { FilePlayerProps , MediaPlayerFunction } from '../lib' ;
9+ import { MediaPlayerFunction , PlayerProps } from '../lib' ;
910
1011// Helper to extract Twitch video/clip ID from src
1112function getTwitchInfo ( src : string | { src : string } ) {
@@ -21,10 +22,12 @@ function getTwitchInfo(src: string | { src: string }) {
2122 return null ;
2223}
2324
24- const TwitchPlayer = forwardRef < MediaPlayerFunction , FilePlayerProps > (
25+ const TwitchPlayer = forwardRef < MediaPlayerFunction , PlayerProps < any > > (
2526 ( props , ref ) => {
27+ const [ playling , setPlaying ] = useState ( false ) ;
2628 const embedRef = useRef < HTMLDivElement > ( null ) ;
27- const playerRef = useRef < any > ( null ) ;
29+ const [ init , setInit ] = useState < boolean > ( false ) ;
30+ const [ player , setPlayer ] = useState < any > ( null ) ;
2831 const { playerProps } = props ;
2932 const {
3033 className,
@@ -33,7 +36,6 @@ const TwitchPlayer = forwardRef<MediaPlayerFunction, FilePlayerProps>(
3336 height,
3437 controls,
3538 autoplay,
36- loop,
3739 onEnded,
3840 onPause,
3941 onPlay,
@@ -46,7 +48,6 @@ const TwitchPlayer = forwardRef<MediaPlayerFunction, FilePlayerProps>(
4648
4749 // Load Twitch embed script
4850 useEffect ( ( ) => {
49- console . log ( 'Loading Twitch embed script' ) ;
5051 if ( ( window as any ) . Twitch && ( window as any ) . Twitch . Embed ) return ;
5152 if ( ! document . getElementById ( 'twitch-embed-script' ) ) {
5253 const script = document . createElement ( 'script' ) ;
@@ -56,12 +57,29 @@ const TwitchPlayer = forwardRef<MediaPlayerFunction, FilePlayerProps>(
5657 }
5758 } , [ ] ) ;
5859
59- // Create Twitch embed
6060 useEffect ( ( ) => {
61- if ( ! twitchInfo || ! embedRef . current ) return ( ) => { } ;
62- function createEmbed ( ) {
63- console . log ( 'PlayerRef' , playerRef . current ) ;
64- if ( playerRef . current ) return ;
61+ if ( playling && player && onProgress ) {
62+ onDurationChange ?.( {
63+ target : player ,
64+ currentTime : player . getPlayer ?.( ) ?. getCurrentTime ?.( ) ?? 0 ,
65+ duration : player . getPlayer ?.( ) ?. getDuration ?.( ) ?? 0 ,
66+ } ) ;
67+ const interval = setInterval ( ( ) => {
68+ onProgress ?.( {
69+ target : player ,
70+ currentTime : player . getPlayer ?.( ) ?. getCurrentTime ?.( ) ?? 0 ,
71+ duration : player . getPlayer ?.( ) ?. getDuration ?.( ) ?? 0 ,
72+ } ) ;
73+ } , 1000 ) ;
74+ return ( ) => {
75+ clearInterval ( interval ) ;
76+ } ;
77+ }
78+ return ( ) => { } ;
79+ } , [ player , playling ] ) ;
80+
81+ useEffect ( ( ) => {
82+ if ( init && ! player ) {
6583 const options : any = {
6684 width : width || '100%' ,
6785 height : height || 360 ,
@@ -73,77 +91,89 @@ const TwitchPlayer = forwardRef<MediaPlayerFunction, FilePlayerProps>(
7391 } else {
7492 options . clip = twitchInfo ! . id ;
7593 }
76- if ( controls !== undefined ) options . controls = controls ;
77- if ( loop !== undefined ) options . loop = loop ;
78- playerRef . current = new ( window as any ) . Twitch . Embed (
94+
95+ options . controls = controls === true ;
96+
97+ const pl = new ( window as any ) . Twitch . Embed (
7998 embedRef . current ! . id ,
8099 options ,
81100 ) ;
82- playerRef . current . addEventListener ( 'play' , ( ) => onPlay ?.( ) ) ;
83- playerRef . current . addEventListener ( 'pause' , ( ) => onPause ?.( ) ) ;
84- playerRef . current . addEventListener ( 'ended' , ( ) => onEnded ?.( ) ) ;
85- playerRef . current . addEventListener ( 'ready' , ( ) => onStart ?.( ) ) ;
86- playerRef . current . addEventListener ( 'playing' , ( ) => onPlay ?.( ) ) ;
87- playerRef . current . addEventListener ( 'timeupdate' , ( ) => {
88- const player = playerRef . current . getPlayer ( ) ;
89- onProgress ?.( {
90- target : player ,
91- currentTime : player . getCurrentTime ( ) ,
92- duration : player . getDuration ( ) ,
93- } ) ;
101+ pl . addEventListener ( 'play' , ( ) => {
102+ setPlaying ( true ) ;
103+ onPlay ?.( ) ;
104+ } ) ;
105+ pl . addEventListener ( 'pause' , ( ) => {
106+ setPlaying ( false ) ;
107+ onPause ?.( ) ;
108+ } ) ;
109+ pl . addEventListener ( 'ended' , ( ) => {
110+ setPlaying ( false ) ;
111+ onEnded ?.( ) ;
112+ } ) ;
113+ pl . addEventListener ( 'ready' , ( ) => {
94114 onDurationChange ?.( {
95- target : player ,
96- currentTime : player . getCurrentTime ( ) ,
97- duration : player . getDuration ( ) ,
115+ target : pl ,
116+ currentTime : pl . getPlayer ?. ( ) ?. getCurrentTime ?. ( ) ?? 0 ,
117+ duration : pl . getPlayer ?. ( ) ?. getDuration ?. ( ) ?? 0 ,
98118 } ) ;
119+ onStart ?.( ) ;
120+ } ) ;
121+ pl . addEventListener ( 'playing' , ( ) => {
122+ setPlaying ( true ) ;
123+ onPlay ?.( ) ;
124+ } ) ;
125+ console . log ( pl ) ;
126+ pl . addEventListener ( 'timeupdate' , ( ) => {
127+ console . log ( 'timeupdate' ) ;
99128 } ) ;
129+ setPlayer ( pl ) ;
130+ return ( ) => {
131+ if ( pl ) {
132+ pl . removeEventListener ?.( 'play' , onPlay ) ;
133+ pl . removeEventListener ?.( 'pause' , onPause ) ;
134+ pl . removeEventListener ?.( 'ended' , onEnded ) ;
135+ pl . removeEventListener ?.( 'ready' , onStart ) ;
136+ pl . removeEventListener ?.( 'playing' , onPlay ) ;
137+ pl . removeEventListener ?.( 'timeupdate' , onProgress ) ;
138+ }
139+ } ;
100140 }
101- if ( ( window as any ) . Twitch && ( window as any ) . Twitch . Embed ) {
102- createEmbed ( ) ;
103- } else {
141+ return ( ) => { } ;
142+ } , [ player , init ] ) ;
143+
144+ // Create Twitch embed
145+ useEffect ( ( ) => {
146+ if ( ! twitchInfo || ! embedRef . current ) return ;
147+ if ( ! ( window as any ) . Twitch || ! ( window as any ) . Twitch . Embed ) {
104148 document
105149 . getElementById ( 'twitch-embed-script' )
106150 ?. addEventListener ( 'load' , ( ) => {
107- createEmbed ( ) ;
151+ setInit ( true ) ;
108152 } ) ;
153+ } else {
154+ setInit ( true ) ;
109155 }
110- return ( ) => {
111- if ( playerRef . current ) {
112- playerRef . current . removeEventListener ?.( 'play' , onPlay ) ;
113- playerRef . current . removeEventListener ?.( 'pause' , onPause ) ;
114- playerRef . current . removeEventListener ?.( 'ended' , onEnded ) ;
115- playerRef . current . removeEventListener ?.( 'ready' , onStart ) ;
116- playerRef . current . removeEventListener ?.( 'playing' , onPlay ) ;
117- playerRef . current . removeEventListener ?.( 'timeupdate' , onProgress ) ;
118- playerRef . current = null ;
119- }
120- } ;
121- } , [ twitchInfo , playerRef ] ) ;
156+ } , [ twitchInfo , embedRef ] ) ;
122157
123158 // Imperative API
124159 useImperativeHandle ( ref , ( ) => ( {
125160 seekTo ( to : number ) {
126- const player = playerRef . current ?. getPlayer ?.( ) ;
127- player ?. seek ?.( to ) ;
161+ player ?. getPlayer ?.( ) ?. seek ?.( to ) ;
128162 } ,
129163 getRawPlayer < Y > ( ) : Y | null {
130- return playerRef . current ?. getPlayer ?.( ) as Y | null ;
164+ return player ?. getPlayer ?.( ) as Y | null ;
131165 } ,
132166 play ( ) {
133- const player = playerRef . current ?. getPlayer ?.( ) ;
134- player ?. play ?.( ) ;
167+ player ?. getPlayer ?.( ) ?. play ?.( ) ;
135168 } ,
136169 pause ( ) {
137- const player = playerRef . current ?. getPlayer ?.( ) ;
138- player ?. pause ?.( ) ;
170+ player ?. getPlayer ?.( ) ?. pause ?.( ) ;
139171 } ,
140172 getDuration ( ) {
141- const player = playerRef . current ?. getPlayer ?.( ) ;
142- return player ?. getDuration ?.( ) ?? - 1 ;
173+ return player ?. getPlayer ?.( ) ?. getDuration ?.( ) ?? - 1 ;
143174 } ,
144175 getCurrentTime ( ) {
145- const player = playerRef . current ?. getPlayer ?.( ) ;
146- return player ?. getCurrentTime ?.( ) ?? - 1 ;
176+ return player ?. getPlayer ?.( ) ?. getCurrentTime ?.( ) ?? - 1 ;
147177 } ,
148178 setPlayBackRate ( ) { } ,
149179 } ) ) ;
0 commit comments