pstream is dead; long live pstream taciturnaxolotl.github.io/pstream-ng/
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: fix issues with captions code

+55 -32
+9 -4
src/components/player/base/SubtitleView.tsx
··· 123 123 const overrideCasing = useSubtitleStore((s) => s.overrideCasing); 124 124 const delay = useSubtitleStore((s) => s.delay); 125 125 126 - const parsedCaptions = useMemo( 127 - () => (srtData ? parseSubtitles(srtData, language) : []), 128 - [srtData, language], 129 - ); 126 + const parsedCaptions = useMemo(() => { 127 + if (!srtData) return []; 128 + try { 129 + return parseSubtitles(srtData, language); 130 + } catch (e) { 131 + console.error("Failed to parse subtitles:", e); 132 + return []; 133 + } 134 + }, [srtData, language]); 130 135 131 136 const visibleCaptions = useMemo( 132 137 () =>
+30 -25
src/components/player/hooks/useCaptions.ts
··· 90 90 srtData: "", 91 91 }; 92 92 93 - if (!caption.hls) { 94 - const srtData = await downloadCaption(caption); 95 - captionToSet.srtData = srtData; 96 - } else { 97 - // request a language change to hls, so it can load the subtitles 98 - await setSubtitlePreference?.(caption.language); 99 - const track = getSubtitleTracks?.().find( 100 - (t) => t.id.toString() === caption.id && t.details !== undefined, 101 - ); 102 - if (!track) return; 93 + try { 94 + if (!caption.hls) { 95 + const srtData = await downloadCaption(caption); 96 + captionToSet.srtData = srtData; 97 + } else { 98 + // request a language change to hls, so it can load the subtitles 99 + await setSubtitlePreference?.(caption.language); 100 + const track = getSubtitleTracks?.().find( 101 + (t) => t.id.toString() === caption.id && t.details !== undefined, 102 + ); 103 + if (!track) return; 103 104 104 - const fragments = 105 - track.details?.fragments?.filter( 106 - (frag) => frag !== null && frag.url !== null, 107 - ) ?? []; 105 + const fragments = 106 + track.details?.fragments?.filter( 107 + (frag) => frag !== null && frag.url !== null, 108 + ) ?? []; 108 109 109 - const vttCaptions = ( 110 - await Promise.all( 111 - fragments.map(async (frag) => { 112 - const vtt = await downloadWebVTT(frag.url); 113 - return parseVttSubtitles(vtt); 114 - }), 115 - ) 116 - ).flat(); 110 + const vttCaptions = ( 111 + await Promise.all( 112 + fragments.map(async (frag) => { 113 + const vtt = await downloadWebVTT(frag.url); 114 + return parseVttSubtitles(vtt); 115 + }), 116 + ) 117 + ).flat(); 117 118 118 - const filtered = filterDuplicateCaptionCues(vttCaptions); 119 + const filtered = filterDuplicateCaptionCues(vttCaptions); 119 120 120 - const srtData = subsrt.build(filtered, { format: "srt" }); 121 - captionToSet.srtData = srtData; 121 + const srtData = subsrt.build(filtered, { format: "srt" }); 122 + captionToSet.srtData = srtData; 123 + } 124 + } catch (e) { 125 + console.error("Failed to load caption:", e); 126 + return; 122 127 } 123 128 124 129 setDirectCaption(captionToSet, caption);
+10 -2
src/components/player/internals/VideoContainer.tsx
··· 73 73 (s) => s.enableNativeSubtitles, 74 74 ); 75 75 const trackObjectUrl = useObjectUrl( 76 - () => (srtData ? convertSubtitlesToObjectUrl(srtData) : null), 77 - [srtData], 76 + () => { 77 + if (!srtData || !enableNativeSubtitles) return null; 78 + try { 79 + return convertSubtitlesToObjectUrl(srtData); 80 + } catch (e) { 81 + console.error("Failed to convert subtitles for native track:", e); 82 + return null; 83 + } 84 + }, 85 + [srtData, enableNativeSubtitles], 78 86 ); 79 87 80 88 // Use native tracks when the setting is enabled
+6 -1
src/components/player/utils/captions.ts
··· 77 77 } 78 78 79 79 function stringToBase64(input: string): string { 80 - return btoa(String.fromCodePoint(...new TextEncoder().encode(input))); 80 + const bytes = new TextEncoder().encode(input); 81 + let binary = ""; 82 + for (let i = 0; i < bytes.length; i++) { 83 + binary += String.fromCharCode(bytes[i]); 84 + } 85 + return btoa(binary); 81 86 } 82 87 83 88 export function convertSubtitlesToSrtDataurl(text: string): string {