.
This commit is contained in:
@@ -96,15 +96,9 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
if (tracks && processedSubtitles.length > 0) {
|
||||
const defaultSubtitle = processedSubtitles.find((sub) => sub.default)
|
||||
if (defaultSubtitle) {
|
||||
// Find the corresponding track and set it as showing
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
const track = tracks[i]
|
||||
if (track.language === defaultSubtitle.lang) {
|
||||
track.mode = 'showing'
|
||||
setSubtitle(defaultSubtitle)
|
||||
break
|
||||
}
|
||||
}
|
||||
console.log(`🎯 Found default subtitle in metadata: ${defaultSubtitle.label}`)
|
||||
// Set subtitle in context (this will trigger the useEffect that enables it)
|
||||
setSubtitle(defaultSubtitle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -218,6 +212,8 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
|
||||
// Process subtitles - convert SRT to VTT blob URLs
|
||||
useEffect(() => {
|
||||
let cancelled = false
|
||||
|
||||
// Clean up old blob URLs
|
||||
subtitleBlobUrlsRef.current.forEach((url) => URL.revokeObjectURL(url))
|
||||
subtitleBlobUrlsRef.current = []
|
||||
@@ -239,8 +235,17 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
throw new Error(`Failed to fetch subtitle: ${response.status} ${response.statusText}`)
|
||||
}
|
||||
const srtContent = await response.text()
|
||||
console.log(`SRT content length: ${srtContent.length} chars`)
|
||||
|
||||
const blobUrl = createSubtitleBlobURL(srtContent, 'srt')
|
||||
subtitleBlobUrlsRef.current.push(blobUrl)
|
||||
|
||||
// Debug: fetch the blob URL to verify VTT content
|
||||
const vttResponse = await fetch(blobUrl)
|
||||
const vttContent = await vttResponse.text()
|
||||
console.log(`VTT content preview (first 500 chars):`, vttContent.substring(0, 500))
|
||||
console.log(`Total VTT length: ${vttContent.length} chars`)
|
||||
|
||||
console.log(`Processed SRT subtitle "${subtitle.label}": ${subtitle.src} -> ${blobUrl}`)
|
||||
return { ...subtitle, src: blobUrl }
|
||||
}
|
||||
@@ -253,13 +258,18 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
}
|
||||
})
|
||||
)
|
||||
setProcessedSubtitles(processed)
|
||||
|
||||
// Only update state if not cancelled
|
||||
if (!cancelled) {
|
||||
setProcessedSubtitles(processed)
|
||||
}
|
||||
}
|
||||
|
||||
processSubtitles()
|
||||
|
||||
// Cleanup function
|
||||
return () => {
|
||||
cancelled = true
|
||||
subtitleBlobUrlsRef.current.forEach((url) => URL.revokeObjectURL(url))
|
||||
subtitleBlobUrlsRef.current = []
|
||||
}
|
||||
@@ -475,20 +485,50 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
const tracks = video.textTracks
|
||||
if (!tracks || tracks.length === 0) return
|
||||
|
||||
// Disable all tracks first
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
tracks[i].mode = 'hidden'
|
||||
const enableSubtitle = () => {
|
||||
// Disable all tracks first
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
tracks[i].mode = 'hidden'
|
||||
}
|
||||
|
||||
// Enable the selected subtitle track
|
||||
if (settings.subtitle) {
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
const track = tracks[i]
|
||||
if (track.language === settings.subtitle.lang) {
|
||||
// Wait for track to have cues before showing
|
||||
if (track.cues && track.cues.length > 0) {
|
||||
track.mode = 'showing'
|
||||
console.log(`🔊 Enabled subtitle track: ${track.label} (${track.language})`)
|
||||
console.log(` - cues available: ${track.cues.length}`)
|
||||
console.log(` - track.mode: ${track.mode}`)
|
||||
} else {
|
||||
console.warn(`⚠️ Track ${track.label} has no cues yet, waiting...`)
|
||||
// Track not ready yet, will be handled by load event
|
||||
track.mode = 'showing'
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Enable the selected subtitle track
|
||||
if (settings.subtitle) {
|
||||
// Try to enable immediately
|
||||
enableSubtitle()
|
||||
|
||||
// Also listen for track load events to retry
|
||||
const handleTrackChange = () => {
|
||||
console.log(`🔄 Track changed, re-enabling subtitle`)
|
||||
enableSubtitle()
|
||||
}
|
||||
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
tracks[i].addEventListener('load', handleTrackChange)
|
||||
}
|
||||
|
||||
return () => {
|
||||
for (let i = 0; i < tracks.length; i++) {
|
||||
const track = tracks[i]
|
||||
if (track.language === settings.subtitle.lang) {
|
||||
track.mode = 'showing'
|
||||
console.log(`Enabled subtitle track: ${track.label} (${track.language})`)
|
||||
break
|
||||
}
|
||||
tracks[i].removeEventListener('load', handleTrackChange)
|
||||
}
|
||||
}
|
||||
}, [settings.subtitle, videoRef])
|
||||
@@ -500,12 +540,26 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
|
||||
const handleTrackLoad = (e: Event) => {
|
||||
const track = e.target as HTMLTrackElement
|
||||
console.log(`Track loaded: ${track.label} (${track.srclang})`, track.readyState)
|
||||
const textTrack = track.track
|
||||
console.log(`✅ Track loaded: ${track.label} (${track.srclang})`)
|
||||
console.log(` - readyState: ${track.readyState}`)
|
||||
console.log(` - track.mode: ${textTrack.mode}`)
|
||||
console.log(` - track.cues: ${textTrack.cues?.length || 0}`)
|
||||
console.log(` - src: ${track.src}`)
|
||||
|
||||
// Log first few cues if available
|
||||
if (textTrack.cues && textTrack.cues.length > 0) {
|
||||
console.log(` - First cue: ${(textTrack.cues[0] as VTTCue).startTime}s - ${(textTrack.cues[0] as VTTCue).endTime}s: "${(textTrack.cues[0] as VTTCue).text}"`)
|
||||
} else {
|
||||
console.warn(` ⚠️ No cues found in track!`)
|
||||
}
|
||||
}
|
||||
|
||||
const handleTrackError = (e: Event) => {
|
||||
const track = e.target as HTMLTrackElement
|
||||
console.error(`Track error: ${track.label} (${track.srclang})`, track.track.cues?.length)
|
||||
console.error(`❌ Track error: ${track.label} (${track.srclang})`)
|
||||
console.error(` - src: ${track.src}`)
|
||||
console.error(` - readyState: ${track.readyState}`)
|
||||
}
|
||||
|
||||
const trackElements = video.querySelectorAll('track')
|
||||
@@ -520,7 +574,11 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
for (let i = 0; i < textTracks.length; i++) {
|
||||
const track = textTracks[i]
|
||||
if (track.mode === 'showing') {
|
||||
console.log(`Active track: ${track.label}, cues: ${track.cues?.length || 0}, active cues: ${track.activeCues?.length || 0}`)
|
||||
console.log(`🎬 Cuechange: ${track.label}, cues: ${track.cues?.length || 0}, active cues: ${track.activeCues?.length || 0}`)
|
||||
if (track.activeCues && track.activeCues.length > 0) {
|
||||
const cue = track.activeCues[0] as VTTCue
|
||||
console.log(` - Active cue text: "${cue.text}"`)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -529,6 +587,15 @@ export const VideoElement: React.FC<VideoElementProps> = ({
|
||||
textTracks[i].addEventListener('cuechange', handleCueChange)
|
||||
}
|
||||
|
||||
// Log all text tracks after a delay to see their state
|
||||
setTimeout(() => {
|
||||
console.log(`📊 Text tracks summary (${textTracks.length} total):`)
|
||||
for (let i = 0; i < textTracks.length; i++) {
|
||||
const track = textTracks[i]
|
||||
console.log(` [${i}] ${track.label} (${track.language}): mode=${track.mode}, cues=${track.cues?.length || 0}`)
|
||||
}
|
||||
}, 1000)
|
||||
|
||||
return () => {
|
||||
trackElements.forEach((track) => {
|
||||
track.removeEventListener('load', handleTrackLoad)
|
||||
|
||||
Reference in New Issue
Block a user