Add SRT/FLV/RTMP support and update documentation
Introduced Python scripts for SRT subtitle checking and fixing, and added comprehensive documentation covering advanced features such as protocol detection, subtitle/audio/quality management, keyboard shortcuts, and touch gestures. Updated local settings to allow new build and Python commands, added TypeScript definitions for FLV, and implemented RTMP/FLV protocol support in the player. Removed CHANGELOG.md and made various improvements to styles and example app.
This commit is contained in:
+58
-6
@@ -3,7 +3,7 @@
|
||||
* Handles loading hls.js from npm or CDN
|
||||
*/
|
||||
|
||||
import type { AudioTrack, VideoQuality } from '../types'
|
||||
import type { AudioTrack, VideoQuality, SubtitleTrack } from '../types'
|
||||
import { getTranslations, detectBrowserLanguage } from '../i18n'
|
||||
|
||||
// Re-export control functions for backward compatibility
|
||||
@@ -47,15 +47,20 @@ const loadHlsFromCDN = (): Promise<any> => {
|
||||
*/
|
||||
export const loadHls = async (): Promise<any> => {
|
||||
try {
|
||||
console.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')
|
||||
return hlsModule.default
|
||||
} catch {
|
||||
} catch (npmError) {
|
||||
console.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')
|
||||
return Hls
|
||||
} catch {
|
||||
} catch (cdnError) {
|
||||
console.error('[HLS Loader] Failed to load from CDN:', cdnError)
|
||||
throw new Error('Unable to load HLS.js library. HLS streaming is not available.')
|
||||
}
|
||||
}
|
||||
@@ -82,14 +87,18 @@ export const hasNativeHlsSupport = (): boolean => {
|
||||
export const getHlsAudioTracks = (hls: any): AudioTrack[] => {
|
||||
try {
|
||||
if (!hls) {
|
||||
console.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')
|
||||
return []
|
||||
}
|
||||
|
||||
console.log('[HLS Loader] getHlsAudioTracks: Raw audioTracks from HLS:', hls.audioTracks)
|
||||
|
||||
const audioTracks: AudioTrack[] = hls.audioTracks.map((track: any, index: number) => {
|
||||
const audioTrack = {
|
||||
name: track.name || track.label || `Audio ${index + 1}`,
|
||||
@@ -102,7 +111,38 @@ export const getHlsAudioTracks = (hls: any): AudioTrack[] => {
|
||||
return audioTrack
|
||||
})
|
||||
|
||||
console.log('[HLS Loader] getHlsAudioTracks: Processed tracks:', audioTracks)
|
||||
return audioTracks
|
||||
} catch (error) {
|
||||
console.error('[HLS Loader] getHlsAudioTracks: Error extracting audio tracks:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract subtitle tracks from HLS instance
|
||||
*/
|
||||
export const getHlsSubtitleTracks = (hls: any): SubtitleTrack[] => {
|
||||
try {
|
||||
if (!hls) {
|
||||
return []
|
||||
}
|
||||
|
||||
// Check if subtitleTracks property exists
|
||||
if (!hls.subtitleTracks || !Array.isArray(hls.subtitleTracks)) {
|
||||
return []
|
||||
}
|
||||
|
||||
const subtitleTracks: SubtitleTrack[] = hls.subtitleTracks.map((track: any, index: number) => {
|
||||
return {
|
||||
label: track.name || track.label || `Subtitle ${index + 1}`,
|
||||
lang: track.lang || track.language || 'unknown',
|
||||
src: track.url || '',
|
||||
default: track.default || false,
|
||||
}
|
||||
})
|
||||
|
||||
return subtitleTracks
|
||||
} catch {
|
||||
return []
|
||||
}
|
||||
@@ -113,10 +153,18 @@ export const getHlsAudioTracks = (hls: any): AudioTrack[] => {
|
||||
*/
|
||||
export const getHlsQualities = (hls: any): VideoQuality[] => {
|
||||
try {
|
||||
if (!hls || !Array.isArray(hls.levels)) {
|
||||
if (!hls) {
|
||||
console.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')
|
||||
return []
|
||||
}
|
||||
|
||||
console.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
|
||||
const [widthFromResolution, heightFromResolution] = resolution
|
||||
@@ -149,14 +197,18 @@ export const getHlsQualities = (hls: any): VideoQuality[] => {
|
||||
}
|
||||
})
|
||||
|
||||
return qualities.sort((a, b) => {
|
||||
const sortedQualities = qualities.sort((a, b) => {
|
||||
const heightDifference = (b.height || 0) - (a.height || 0)
|
||||
if (heightDifference !== 0) {
|
||||
return heightDifference
|
||||
}
|
||||
return (b.bitrate || 0) - (a.bitrate || 0)
|
||||
})
|
||||
} catch {
|
||||
|
||||
console.log('[HLS Loader] getHlsQualities: Processed qualities:', sortedQualities)
|
||||
return sortedQualities
|
||||
} catch (error) {
|
||||
console.error('[HLS Loader] getHlsQualities: Error extracting qualities:', error)
|
||||
return []
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user