Some fixes
This commit is contained in:
@@ -405,6 +405,7 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
useEffect(() => {
|
||||
const video = videoRef.current
|
||||
if (!video) return
|
||||
let isCancelled = false
|
||||
|
||||
setAvailableAudioTracks([])
|
||||
onAudioTracksLoaded?.([])
|
||||
@@ -426,6 +427,38 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
const detection = detectVideoProtocol(src)
|
||||
let cleanupFn: (() => void) | null = null
|
||||
|
||||
const teardownPlayer = () => {
|
||||
if (cleanupFn) {
|
||||
cleanupFn()
|
||||
cleanupFn = null
|
||||
}
|
||||
|
||||
// Also check for any lingering player instances
|
||||
if ((video as any).__hlsInstance) {
|
||||
const hls = (video as any).__hlsInstance
|
||||
if (hls && typeof hls.destroy === 'function') {
|
||||
hls.destroy()
|
||||
}
|
||||
delete (video as any).__hlsInstance
|
||||
}
|
||||
|
||||
if ((video as any).__rtmpInstance) {
|
||||
const rtmp = (video as any).__rtmpInstance
|
||||
if (rtmp && typeof rtmp.destroy === 'function') {
|
||||
rtmp.destroy()
|
||||
}
|
||||
delete (video as any).__rtmpInstance
|
||||
}
|
||||
|
||||
if ((video as any).__mpegtsInstance) {
|
||||
const mpegts = (video as any).__mpegtsInstance
|
||||
if (mpegts && typeof mpegts.destroy === 'function') {
|
||||
mpegts.destroy()
|
||||
}
|
||||
delete (video as any).__mpegtsInstance
|
||||
}
|
||||
}
|
||||
|
||||
console.log('[VideoElement] Source:', src)
|
||||
console.log('[VideoElement] Detected protocol:', detection.protocol)
|
||||
console.log('[VideoElement] Is live stream?', detection.isLive)
|
||||
@@ -451,20 +484,29 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
src,
|
||||
autoplay,
|
||||
onAudioTracksLoaded: (tracks) => {
|
||||
if (isCancelled) return
|
||||
setAvailableAudioTracks(tracks)
|
||||
onAudioTracksLoaded?.(tracks)
|
||||
},
|
||||
onQualityLevelsLoaded: (qualities) => {
|
||||
if (isCancelled) return
|
||||
setAvailableQualities(qualities)
|
||||
onQualityLevelsLoaded?.(qualities)
|
||||
},
|
||||
onSubtitleTracksLoaded: (tracks) => {
|
||||
if (isCancelled) return
|
||||
setHlsSubtitles(tracks)
|
||||
onSubtitleTracksLoaded?.(tracks)
|
||||
},
|
||||
onError: handleError,
|
||||
})
|
||||
|
||||
if (isCancelled) {
|
||||
teardownPlayer()
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if (isCancelled) return
|
||||
console.log('[VideoElement] Using native HLS playback')
|
||||
video.src = src
|
||||
if (autoplay) {
|
||||
@@ -484,6 +526,11 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
onError: handleError,
|
||||
onLoadedMetadata,
|
||||
})
|
||||
|
||||
if (isCancelled) {
|
||||
teardownPlayer()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
@@ -497,11 +544,17 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
onError: handleError,
|
||||
onLoadedMetadata,
|
||||
})
|
||||
|
||||
if (isCancelled) {
|
||||
teardownPlayer()
|
||||
return
|
||||
}
|
||||
break
|
||||
}
|
||||
|
||||
case 'dash': {
|
||||
// DASH streaming - not yet implemented
|
||||
if (isCancelled) return
|
||||
const error = new Error('DASH streaming is not yet supported')
|
||||
console.error('[VideoElement]', error.message)
|
||||
setVideoState((prev) => ({ ...prev, error, loading: false }))
|
||||
@@ -512,6 +565,7 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
case 'native':
|
||||
default: {
|
||||
// Native HTML5 video (MP4, WebM, etc.)
|
||||
if (isCancelled) return
|
||||
console.log('[VideoElement] Using native video.src')
|
||||
video.src = src
|
||||
if (autoplay) {
|
||||
@@ -528,6 +582,9 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
} else {
|
||||
error = err instanceof Error ? err : new Error(`Failed to load ${detection.protocol.toUpperCase()} video`)
|
||||
}
|
||||
|
||||
if (isCancelled) return
|
||||
|
||||
console.error('[VideoElement] Setup error:', error)
|
||||
setVideoState((prev) => ({
|
||||
...prev,
|
||||
@@ -538,35 +595,12 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
}
|
||||
}
|
||||
|
||||
setupPlayer()
|
||||
void setupPlayer()
|
||||
|
||||
// Cleanup function
|
||||
return () => {
|
||||
if (cleanupFn) {
|
||||
cleanupFn()
|
||||
}
|
||||
// Also check for any lingering player instances
|
||||
if ((video as any).__hlsInstance) {
|
||||
const hls = (video as any).__hlsInstance
|
||||
if (hls && typeof hls.destroy === 'function') {
|
||||
hls.destroy()
|
||||
}
|
||||
delete (video as any).__hlsInstance
|
||||
}
|
||||
if ((video as any).__rtmpInstance) {
|
||||
const rtmp = (video as any).__rtmpInstance
|
||||
if (rtmp && typeof rtmp.destroy === 'function') {
|
||||
rtmp.destroy()
|
||||
}
|
||||
delete (video as any).__rtmpInstance
|
||||
}
|
||||
if ((video as any).__mpegtsInstance) {
|
||||
const mpegts = (video as any).__mpegtsInstance
|
||||
if (mpegts && typeof mpegts.destroy === 'function') {
|
||||
mpegts.destroy()
|
||||
}
|
||||
delete (video as any).__mpegtsInstance
|
||||
}
|
||||
isCancelled = true
|
||||
teardownPlayer()
|
||||
}
|
||||
}, [
|
||||
src,
|
||||
|
||||
Reference in New Issue
Block a user