feat: apply phase1 DX cleanup for private registry
This commit is contained in:
+17
-15
@@ -5,6 +5,7 @@
|
||||
|
||||
import type { AudioTrack, VideoQuality, SubtitleTrack } from '../types'
|
||||
import { getTranslations, detectBrowserLanguage } from '../i18n'
|
||||
import { logger } from './logger'
|
||||
|
||||
// Re-export control functions for backward compatibility
|
||||
export { setHlsQualityLevel, setHlsAudioTrack } from './hlsControl'
|
||||
@@ -47,20 +48,20 @@ const loadHlsFromCDN = (): Promise<any> => {
|
||||
*/
|
||||
export const loadHls = async (): Promise<any> => {
|
||||
try {
|
||||
console.log('[HLS Loader] Attempting to load from npm package...')
|
||||
logger.log('[HLS Loader] Attempting to load from npm package...')
|
||||
// Try loading from npm package first
|
||||
const hlsModule = await import('hls.js')
|
||||
console.log('[HLS Loader] Successfully loaded from npm package')
|
||||
logger.log('[HLS Loader] Successfully loaded from npm package')
|
||||
return hlsModule.default
|
||||
} catch (npmError) {
|
||||
console.warn('[HLS Loader] Failed to load from npm, trying CDN...', npmError)
|
||||
logger.warn('[HLS Loader] Failed to load from npm, trying CDN...', npmError)
|
||||
try {
|
||||
// Fallback to CDN
|
||||
const Hls = await loadHlsFromCDN()
|
||||
console.log('[HLS Loader] Successfully loaded from CDN')
|
||||
logger.log('[HLS Loader] Successfully loaded from CDN')
|
||||
return Hls
|
||||
} catch (cdnError) {
|
||||
console.error('[HLS Loader] Failed to load from CDN:', cdnError)
|
||||
logger.error('[HLS Loader] Failed to load from CDN:', cdnError)
|
||||
throw new Error('Unable to load HLS.js library. HLS streaming is not available.')
|
||||
}
|
||||
}
|
||||
@@ -87,17 +88,17 @@ export const hasNativeHlsSupport = (): boolean => {
|
||||
export const getHlsAudioTracks = (hls: any): AudioTrack[] => {
|
||||
try {
|
||||
if (!hls) {
|
||||
console.warn('[HLS Loader] getHlsAudioTracks: No HLS instance provided')
|
||||
logger.warn('[HLS Loader] getHlsAudioTracks: No HLS instance provided')
|
||||
return []
|
||||
}
|
||||
|
||||
// Check if audioTracks property exists
|
||||
if (!hls.audioTracks || !Array.isArray(hls.audioTracks)) {
|
||||
console.warn('[HLS Loader] getHlsAudioTracks: No audioTracks array found on HLS instance')
|
||||
logger.warn('[HLS Loader] getHlsAudioTracks: No audioTracks array found on HLS instance')
|
||||
return []
|
||||
}
|
||||
|
||||
console.log('[HLS Loader] getHlsAudioTracks: Raw audioTracks from HLS:', hls.audioTracks)
|
||||
logger.log('[HLS Loader] getHlsAudioTracks: Raw audioTracks from HLS:', hls.audioTracks)
|
||||
|
||||
const audioTracks: AudioTrack[] = hls.audioTracks.map((track: any, index: number) => {
|
||||
const audioTrack = {
|
||||
@@ -111,10 +112,10 @@ export const getHlsAudioTracks = (hls: any): AudioTrack[] => {
|
||||
return audioTrack
|
||||
})
|
||||
|
||||
console.log('[HLS Loader] getHlsAudioTracks: Processed tracks:', audioTracks)
|
||||
logger.log('[HLS Loader] getHlsAudioTracks: Processed tracks:', audioTracks)
|
||||
return audioTracks
|
||||
} catch (error) {
|
||||
console.error('[HLS Loader] getHlsAudioTracks: Error extracting audio tracks:', error)
|
||||
logger.error('[HLS Loader] getHlsAudioTracks: Error extracting audio tracks:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
@@ -154,16 +155,16 @@ export const getHlsSubtitleTracks = (hls: any): SubtitleTrack[] => {
|
||||
export const getHlsQualities = (hls: any): VideoQuality[] => {
|
||||
try {
|
||||
if (!hls) {
|
||||
console.warn('[HLS Loader] getHlsQualities: No HLS instance provided')
|
||||
logger.warn('[HLS Loader] getHlsQualities: No HLS instance provided')
|
||||
return []
|
||||
}
|
||||
|
||||
if (!Array.isArray(hls.levels)) {
|
||||
console.warn('[HLS Loader] getHlsQualities: No levels array found on HLS instance')
|
||||
logger.warn('[HLS Loader] getHlsQualities: No levels array found on HLS instance')
|
||||
return []
|
||||
}
|
||||
|
||||
console.log('[HLS Loader] getHlsQualities: Raw levels from HLS:', hls.levels)
|
||||
logger.log('[HLS Loader] getHlsQualities: Raw levels from HLS:', hls.levels)
|
||||
|
||||
const qualities: VideoQuality[] = hls.levels.map((level: any, index: number) => {
|
||||
const resolution = typeof level.attrs?.RESOLUTION === 'string' ? level.attrs.RESOLUTION : undefined
|
||||
@@ -205,11 +206,12 @@ export const getHlsQualities = (hls: any): VideoQuality[] => {
|
||||
return (b.bitrate || 0) - (a.bitrate || 0)
|
||||
})
|
||||
|
||||
console.log('[HLS Loader] getHlsQualities: Processed qualities:', sortedQualities)
|
||||
logger.log('[HLS Loader] getHlsQualities: Processed qualities:', sortedQualities)
|
||||
return sortedQualities
|
||||
} catch (error) {
|
||||
console.error('[HLS Loader] getHlsQualities: Error extracting qualities:', error)
|
||||
logger.error('[HLS Loader] getHlsQualities: Error extracting qualities:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
+12
-10
@@ -3,6 +3,7 @@
|
||||
*/
|
||||
|
||||
import type { AudioTrack, VideoQuality, SubtitleTrack } from '../types'
|
||||
import { logger } from './logger'
|
||||
|
||||
interface HlsSetupOptions {
|
||||
video: HTMLVideoElement
|
||||
@@ -30,7 +31,7 @@ export const setupHlsInstance = async ({
|
||||
throw new Error('HLS.js is not supported in this browser')
|
||||
}
|
||||
|
||||
console.log('[HLS Setup] Creating HLS instance for:', src)
|
||||
logger.log('[HLS Setup] Creating HLS instance for:', src)
|
||||
|
||||
const hls = new Hls({
|
||||
enableWorker: true,
|
||||
@@ -44,10 +45,10 @@ export const setupHlsInstance = async ({
|
||||
let manifestParsedHandled = false
|
||||
|
||||
hls.on(Hls.Events.MANIFEST_PARSED, () => {
|
||||
console.log('[HLS Setup] MANIFEST_PARSED event fired')
|
||||
logger.log('[HLS Setup] MANIFEST_PARSED event fired')
|
||||
|
||||
if (manifestParsedHandled) {
|
||||
console.warn('[HLS Setup] MANIFEST_PARSED already handled, skipping')
|
||||
logger.warn('[HLS Setup] MANIFEST_PARSED already handled, skipping')
|
||||
return
|
||||
}
|
||||
manifestParsedHandled = true
|
||||
@@ -58,23 +59,23 @@ export const setupHlsInstance = async ({
|
||||
const qualities = getHlsQualities(hls)
|
||||
const subtitles = getHlsSubtitleTracks(hls)
|
||||
|
||||
console.log('[HLS Setup] Detected tracks:', {
|
||||
logger.log('[HLS Setup] Detected tracks:', {
|
||||
audioTracks: tracks.length,
|
||||
qualities: qualities.length,
|
||||
subtitles: subtitles.length
|
||||
})
|
||||
|
||||
if (tracks.length > 0) {
|
||||
console.log('[HLS Setup] Loading audio tracks:', tracks)
|
||||
logger.log('[HLS Setup] Loading audio tracks:', tracks)
|
||||
onAudioTracksLoaded?.(tracks)
|
||||
}
|
||||
|
||||
if (subtitles.length > 0) {
|
||||
console.log('[HLS Setup] Loading subtitle tracks:', subtitles)
|
||||
logger.log('[HLS Setup] Loading subtitle tracks:', subtitles)
|
||||
onSubtitleTracksLoaded?.(subtitles)
|
||||
}
|
||||
|
||||
console.log('[HLS Setup] Loading quality levels:', qualities)
|
||||
logger.log('[HLS Setup] Loading quality levels:', qualities)
|
||||
onQualityLevelsLoaded?.(qualities)
|
||||
}
|
||||
|
||||
@@ -93,14 +94,14 @@ export const setupHlsInstance = async ({
|
||||
hls.on(Hls.Events.LEVEL_LOADED, () => {
|
||||
const qualities = getHlsQualities(hls)
|
||||
if (qualities.length > 0) {
|
||||
console.log('[HLS Setup] LEVEL_LOADED - Qualities available:', qualities.length)
|
||||
logger.log('[HLS Setup] LEVEL_LOADED - Qualities available:', qualities.length)
|
||||
onQualityLevelsLoaded?.(qualities)
|
||||
}
|
||||
})
|
||||
|
||||
hls.on(Hls.Events.AUDIO_TRACKS_UPDATED, () => {
|
||||
const tracks = getHlsAudioTracks(hls)
|
||||
console.log('[HLS Setup] AUDIO_TRACKS_UPDATED event:', tracks.length, 'tracks')
|
||||
logger.log('[HLS Setup] AUDIO_TRACKS_UPDATED event:', tracks.length, 'tracks')
|
||||
if (tracks.length > 0) {
|
||||
onAudioTracksLoaded?.(tracks)
|
||||
}
|
||||
@@ -108,7 +109,7 @@ export const setupHlsInstance = async ({
|
||||
|
||||
hls.on(Hls.Events.SUBTITLE_TRACKS_UPDATED, () => {
|
||||
const subtitles = getHlsSubtitleTracks(hls)
|
||||
console.log('[HLS Setup] SUBTITLE_TRACKS_UPDATED event:', subtitles.length, 'tracks')
|
||||
logger.log('[HLS Setup] SUBTITLE_TRACKS_UPDATED event:', subtitles.length, 'tracks')
|
||||
if (subtitles.length > 0) {
|
||||
onSubtitleTracksLoaded?.(subtitles)
|
||||
}
|
||||
@@ -139,3 +140,4 @@ export const setupHlsInstance = async ({
|
||||
delete (video as any).__hlsInstance
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
type LoggerMethod = (..._args: unknown[]) => void
|
||||
|
||||
const noop: LoggerMethod = () => undefined
|
||||
|
||||
export const logger = {
|
||||
log: noop,
|
||||
warn: noop,
|
||||
error: noop,
|
||||
}
|
||||
@@ -2,6 +2,7 @@
|
||||
* MPEG-TS loader utility
|
||||
* Dynamically loads mpegts.js library
|
||||
*/
|
||||
import { logger } from './logger'
|
||||
|
||||
export interface MpegtsConfig {
|
||||
enableWorker?: boolean
|
||||
@@ -29,26 +30,26 @@ let loadingPromise: Promise<any> | null = null
|
||||
export const loadMpegts = async (): Promise<any> => {
|
||||
// Return cached instance if available
|
||||
if (mpegtsInstance) {
|
||||
console.log('[MPEG-TS Loader] Using cached mpegts.js instance')
|
||||
logger.log('[MPEG-TS Loader] Using cached mpegts.js instance')
|
||||
return mpegtsInstance
|
||||
}
|
||||
|
||||
// Return existing loading promise if already loading
|
||||
if (loadingPromise) {
|
||||
console.log('[MPEG-TS Loader] Already loading, waiting for existing promise...')
|
||||
logger.log('[MPEG-TS Loader] Already loading, waiting for existing promise...')
|
||||
return loadingPromise
|
||||
}
|
||||
|
||||
// Start loading
|
||||
loadingPromise = (async () => {
|
||||
try {
|
||||
console.log('[MPEG-TS Loader] Attempting to load from npm package...')
|
||||
logger.log('[MPEG-TS Loader] Attempting to load from npm package...')
|
||||
const module = await import('mpegts.js')
|
||||
mpegtsInstance = module.default || module
|
||||
console.log('[MPEG-TS Loader] Successfully loaded from npm package')
|
||||
logger.log('[MPEG-TS Loader] Successfully loaded from npm package')
|
||||
return mpegtsInstance
|
||||
} catch (error) {
|
||||
console.error('[MPEG-TS Loader] Failed to load mpegts.js:', error)
|
||||
logger.error('[MPEG-TS Loader] Failed to load mpegts.js:', error)
|
||||
throw new Error('Failed to load mpegts.js. Make sure it is installed: npm install mpegts.js')
|
||||
} finally {
|
||||
loadingPromise = null
|
||||
@@ -103,5 +104,6 @@ export const getMpegtsInstance = (): any | null => {
|
||||
export const clearMpegtsCache = (): void => {
|
||||
mpegtsInstance = null
|
||||
loadingPromise = null
|
||||
console.log('[MPEG-TS Loader] Cache cleared')
|
||||
logger.log('[MPEG-TS Loader] Cache cleared')
|
||||
}
|
||||
|
||||
|
||||
+17
-15
@@ -5,6 +5,7 @@
|
||||
|
||||
import { loadMpegts, isMpegtsSupported, createDefaultMpegtsConfig } from './mpegtsLoader'
|
||||
import { isLiveStream } from './videoProtocol'
|
||||
import { logger } from './logger'
|
||||
|
||||
export interface MpegtsSetupOptions {
|
||||
video: HTMLVideoElement
|
||||
@@ -41,7 +42,7 @@ export const setupMpegtsInstance = async ({
|
||||
throw error
|
||||
}
|
||||
|
||||
console.log('[MPEG-TS Setup] Creating player instance for:', src)
|
||||
logger.log('[MPEG-TS Setup] Creating player instance for:', src)
|
||||
|
||||
// Detect if stream is live
|
||||
const isLive = isLiveStream(src)
|
||||
@@ -72,40 +73,40 @@ export const setupMpegtsInstance = async ({
|
||||
|
||||
// Event handlers
|
||||
player.on(mpegts.Events.ERROR, (errorType: string, errorDetail: string, errorInfo: any) => {
|
||||
console.error('mpegts.js error:', { errorType, errorDetail, errorInfo })
|
||||
logger.error('mpegts.js error:', { errorType, errorDetail, errorInfo })
|
||||
|
||||
const error = new Error(`MPEG-TS Player Error: ${errorType} - ${errorDetail}`)
|
||||
|
||||
// Handle specific error types
|
||||
if (errorType === mpegts.ErrorTypes.NETWORK_ERROR) {
|
||||
console.error('Network error occurred:', errorDetail)
|
||||
logger.error('Network error occurred:', errorDetail)
|
||||
|
||||
// Attempt recovery for recoverable network errors
|
||||
if (
|
||||
errorDetail === mpegts.ErrorDetails.NETWORK_EXCEPTION ||
|
||||
errorDetail === mpegts.ErrorDetails.NETWORK_STATUS_CODE_INVALID
|
||||
) {
|
||||
console.log('Attempting to recover from network error...')
|
||||
logger.log('Attempting to recover from network error...')
|
||||
try {
|
||||
player.unload()
|
||||
player.load()
|
||||
return
|
||||
} catch (recoveryError) {
|
||||
console.error('Failed to recover from network error:', recoveryError)
|
||||
logger.error('Failed to recover from network error:', recoveryError)
|
||||
}
|
||||
}
|
||||
} else if (errorType === mpegts.ErrorTypes.MEDIA_ERROR) {
|
||||
console.error('Media error occurred:', errorDetail)
|
||||
logger.error('Media error occurred:', errorDetail)
|
||||
|
||||
// Some media errors are recoverable
|
||||
if (errorDetail === mpegts.ErrorDetails.MEDIA_MSE_ERROR) {
|
||||
console.log('Attempting to recover from media error...')
|
||||
logger.log('Attempting to recover from media error...')
|
||||
try {
|
||||
player.unload()
|
||||
player.load()
|
||||
return
|
||||
} catch (recoveryError) {
|
||||
console.error('Failed to recover from media error:', recoveryError)
|
||||
logger.error('Failed to recover from media error:', recoveryError)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -117,15 +118,15 @@ export const setupMpegtsInstance = async ({
|
||||
})
|
||||
|
||||
player.on(mpegts.Events.LOADING_COMPLETE, () => {
|
||||
console.log('mpegts.js: Loading complete')
|
||||
logger.log('mpegts.js: Loading complete')
|
||||
})
|
||||
|
||||
player.on(mpegts.Events.RECOVERED_EARLY_EOF, () => {
|
||||
console.log('mpegts.js: Recovered from early EOF')
|
||||
logger.log('mpegts.js: Recovered from early EOF')
|
||||
})
|
||||
|
||||
player.on(mpegts.Events.METADATA_ARRIVED, (metadata: any) => {
|
||||
console.log('mpegts.js: Metadata arrived', metadata)
|
||||
logger.log('mpegts.js: Metadata arrived', metadata)
|
||||
|
||||
// Trigger onLoadedMetadata callback
|
||||
if (onLoadedMetadata) {
|
||||
@@ -145,7 +146,7 @@ export const setupMpegtsInstance = async ({
|
||||
try {
|
||||
await video.play()
|
||||
} catch (playError) {
|
||||
console.warn('Autoplay failed:', playError)
|
||||
logger.warn('Autoplay failed:', playError)
|
||||
// Autoplay might be blocked by browser, ignore error
|
||||
}
|
||||
}
|
||||
@@ -153,7 +154,7 @@ export const setupMpegtsInstance = async ({
|
||||
// Return cleanup function
|
||||
return () => {
|
||||
try {
|
||||
console.log('Cleaning up mpegts.js player...')
|
||||
logger.log('Cleaning up mpegts.js player...')
|
||||
|
||||
// Remove event listeners
|
||||
player.off(mpegts.Events.ERROR)
|
||||
@@ -176,11 +177,11 @@ export const setupMpegtsInstance = async ({
|
||||
delete (video as any).__mpegtsInstance
|
||||
delete (video as any).__mpegtsStats
|
||||
} catch (cleanupError) {
|
||||
console.error('Error during mpegts.js cleanup:', cleanupError)
|
||||
logger.error('Error during mpegts.js cleanup:', cleanupError)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to setup mpegts.js player:', error)
|
||||
logger.error('Failed to setup mpegts.js player:', error)
|
||||
|
||||
const setupError =
|
||||
error instanceof Error ? error : new Error('Failed to setup MPEG-TS player')
|
||||
@@ -225,3 +226,4 @@ export const getMpegtsStats = (video: HTMLVideoElement | null): any | null => {
|
||||
export const hasMpegtsInstance = (video: HTMLVideoElement | null): boolean => {
|
||||
return getMpegtsInstance(video) !== null
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* Loads flv.js library with NPM fallback to CDN strategy
|
||||
* Mirrors the HLS loader pattern for consistency
|
||||
*/
|
||||
import { logger } from './logger'
|
||||
|
||||
const FLVJS_CDN_URL = 'https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js'
|
||||
|
||||
@@ -48,14 +49,14 @@ export const loadFlvjs = async (): Promise<any> => {
|
||||
const flvModule = await import('flv.js')
|
||||
return flvModule.default || flvModule
|
||||
} catch (npmError) {
|
||||
console.warn('flv.js NPM package not available, loading from CDN...', npmError)
|
||||
logger.warn('flv.js NPM package not available, loading from CDN...', npmError)
|
||||
|
||||
try {
|
||||
// Fallback to CDN
|
||||
const flvjs = await loadFlvjsFromCDN()
|
||||
return flvjs
|
||||
} catch (cdnError) {
|
||||
console.error('Failed to load flv.js from both NPM and CDN', cdnError)
|
||||
logger.error('Failed to load flv.js from both NPM and CDN', cdnError)
|
||||
throw new Error(
|
||||
'Failed to load flv.js library. Please ensure flv.js is available or check your network connection.'
|
||||
)
|
||||
@@ -162,7 +163,8 @@ export const extractFlvQualityInfo = (player: any): {
|
||||
audioBitrate: stats.audioBitrate,
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('Failed to extract flv.js quality info:', error)
|
||||
logger.warn('Failed to extract flv.js quality info:', error)
|
||||
return null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+17
-15
@@ -6,6 +6,7 @@
|
||||
|
||||
import { loadFlvjs, isFlvjsSupported, createDefaultFlvConfig } from './rtmpLoader'
|
||||
import { isLiveStream } from './videoProtocol'
|
||||
import { logger } from './logger'
|
||||
|
||||
export interface RtmpSetupOptions {
|
||||
video: HTMLVideoElement
|
||||
@@ -50,7 +51,7 @@ export const setupRtmpInstance = async ({
|
||||
if (src.startsWith('rtmp://') || src.startsWith('rtmps://')) {
|
||||
// For RTMP URLs, flv.js expects HTTP-FLV endpoint
|
||||
// This is a limitation - direct RTMP playback requires server-side conversion
|
||||
console.warn(
|
||||
logger.warn(
|
||||
'Direct RTMP playback requires an HTTP-FLV proxy. Please ensure your RTMP stream is available via HTTP-FLV.'
|
||||
)
|
||||
type = 'flv'
|
||||
@@ -84,40 +85,40 @@ export const setupRtmpInstance = async ({
|
||||
|
||||
// Event handlers
|
||||
player.on(flvjs.Events.ERROR, (errorType: string, errorDetail: string, errorInfo: any) => {
|
||||
console.error('flv.js error:', { errorType, errorDetail, errorInfo })
|
||||
logger.error('flv.js error:', { errorType, errorDetail, errorInfo })
|
||||
|
||||
const error = new Error(`FLV Player Error: ${errorType} - ${errorDetail}`)
|
||||
|
||||
// Handle specific error types
|
||||
if (errorType === flvjs.ErrorTypes.NETWORK_ERROR) {
|
||||
console.error('Network error occurred:', errorDetail)
|
||||
logger.error('Network error occurred:', errorDetail)
|
||||
|
||||
// Attempt recovery for recoverable network errors
|
||||
if (
|
||||
errorDetail === flvjs.ErrorDetails.NETWORK_EXCEPTION ||
|
||||
errorDetail === flvjs.ErrorDetails.NETWORK_STATUS_CODE_INVALID
|
||||
) {
|
||||
console.log('Attempting to recover from network error...')
|
||||
logger.log('Attempting to recover from network error...')
|
||||
try {
|
||||
player.unload()
|
||||
player.load()
|
||||
return
|
||||
} catch (recoveryError) {
|
||||
console.error('Failed to recover from network error:', recoveryError)
|
||||
logger.error('Failed to recover from network error:', recoveryError)
|
||||
}
|
||||
}
|
||||
} else if (errorType === flvjs.ErrorTypes.MEDIA_ERROR) {
|
||||
console.error('Media error occurred:', errorDetail)
|
||||
logger.error('Media error occurred:', errorDetail)
|
||||
|
||||
// Some media errors are recoverable
|
||||
if (errorDetail === flvjs.ErrorDetails.MEDIA_MSE_ERROR) {
|
||||
console.log('Attempting to recover from media error...')
|
||||
logger.log('Attempting to recover from media error...')
|
||||
try {
|
||||
player.unload()
|
||||
player.load()
|
||||
return
|
||||
} catch (recoveryError) {
|
||||
console.error('Failed to recover from media error:', recoveryError)
|
||||
logger.error('Failed to recover from media error:', recoveryError)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -129,15 +130,15 @@ export const setupRtmpInstance = async ({
|
||||
})
|
||||
|
||||
player.on(flvjs.Events.LOADING_COMPLETE, () => {
|
||||
console.log('flv.js: Loading complete')
|
||||
logger.log('flv.js: Loading complete')
|
||||
})
|
||||
|
||||
player.on(flvjs.Events.RECOVERED_EARLY_EOF, () => {
|
||||
console.log('flv.js: Recovered from early EOF')
|
||||
logger.log('flv.js: Recovered from early EOF')
|
||||
})
|
||||
|
||||
player.on(flvjs.Events.METADATA_ARRIVED, (metadata: any) => {
|
||||
console.log('flv.js: Metadata arrived', metadata)
|
||||
logger.log('flv.js: Metadata arrived', metadata)
|
||||
|
||||
// Trigger onLoadedMetadata callback
|
||||
if (onLoadedMetadata) {
|
||||
@@ -158,7 +159,7 @@ export const setupRtmpInstance = async ({
|
||||
try {
|
||||
await video.play()
|
||||
} catch (playError) {
|
||||
console.warn('Autoplay failed:', playError)
|
||||
logger.warn('Autoplay failed:', playError)
|
||||
// Autoplay might be blocked by browser, ignore error
|
||||
}
|
||||
}
|
||||
@@ -166,7 +167,7 @@ export const setupRtmpInstance = async ({
|
||||
// Return cleanup function
|
||||
return () => {
|
||||
try {
|
||||
console.log('Cleaning up flv.js player...')
|
||||
logger.log('Cleaning up flv.js player...')
|
||||
|
||||
// Remove event listeners
|
||||
player.off(flvjs.Events.ERROR)
|
||||
@@ -189,11 +190,11 @@ export const setupRtmpInstance = async ({
|
||||
delete (video as any).__rtmpInstance
|
||||
delete (video as any).__rtmpStats
|
||||
} catch (cleanupError) {
|
||||
console.error('Error during flv.js cleanup:', cleanupError)
|
||||
logger.error('Error during flv.js cleanup:', cleanupError)
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Failed to setup flv.js player:', error)
|
||||
logger.error('Failed to setup flv.js player:', error)
|
||||
|
||||
const setupError =
|
||||
error instanceof Error ? error : new Error('Failed to setup RTMP/FLV player')
|
||||
@@ -238,3 +239,4 @@ export const getRtmpStats = (video: HTMLVideoElement | null): any | null => {
|
||||
export const hasRtmpInstance = (video: HTMLVideoElement | null): boolean => {
|
||||
return getRtmpInstance(video) !== null
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user