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.

revert to old captions/sub handling

Pas d8070e57 fe426a74

+9 -113
+4 -32
src/backend/helpers/subs.ts
··· 1 1 import { list } from "subsrt-ts"; 2 2 3 3 import { proxiedFetch } from "@/backend/helpers/fetch"; 4 - import { 5 - convertSubtitlesToSrt, 6 - fixUTF8Encoding, 7 - } from "@/components/player/utils/captions"; 4 + import { convertSubtitlesToSrt } from "@/components/player/utils/captions"; 8 5 import { CaptionListItem } from "@/stores/player/slices/source"; 9 6 import { SimpleCache } from "@/utils/cache"; 10 7 ··· 65 62 } 66 63 if (!data) throw new Error("failed to get caption data"); 67 64 68 - // Ensure the data is in UTF-8 and fix any encoding issues 69 - const encoder = new TextEncoder(); 70 - const decoder = new TextDecoder("utf-8"); 71 - const utf8Bytes = encoder.encode(data); 72 - const utf8Data = decoder.decode(utf8Bytes); 73 - const fixedData = fixUTF8Encoding(utf8Data); 74 - 75 - const output = convertSubtitlesToSrt(fixedData); 65 + const output = convertSubtitlesToSrt(data); 76 66 downloadCache.set(caption.url, output, expirySeconds); 77 67 return output; 78 68 } ··· 85 75 const cached = downloadCache.get(url); 86 76 if (cached) return cached; 87 77 88 - const response = await fetch(url); 89 - const contentType = response.headers.get("content-type") || ""; 90 - const charset = contentType.includes("charset=") 91 - ? contentType.split("charset=")[1].toLowerCase() 92 - : "utf-8"; 93 - 94 - // Get the raw bytes 95 - const buffer = await response.arrayBuffer(); 96 - // Decode using the detected charset, defaulting to UTF-8 97 - const decoder = new TextDecoder(charset); 98 - const data = decoder.decode(buffer); 99 - 100 - // Ensure the data is in UTF-8 and fix any encoding issues 101 - const encoder = new TextEncoder(); 102 - const utf8Bytes = encoder.encode(data); 103 - const utf8Data = decoder.decode(utf8Bytes); 104 - const fixedData = fixUTF8Encoding(utf8Data); 105 - 106 - downloadCache.set(url, fixedData, expirySeconds); 107 - return fixedData; 78 + const data = await fetch(url).then((v) => v.text()); 79 + return data; 108 80 }
+3 -18
src/components/player/atoms/settings/CaptionsView.tsx
··· 15 15 import { SelectableLink } from "@/components/player/internals/ContextMenu/Links"; 16 16 import { 17 17 captionIsVisible, 18 - fixUTF8Encoding, 19 18 parseSubtitles, 20 19 } from "@/components/player/utils/captions"; 21 20 import { useOverlayRouter } from "@/hooks/useOverlayRouter"; ··· 205 204 reader.addEventListener("load", (event) => { 206 205 if (!event.target || typeof event.target.result !== "string") 207 206 return; 208 - 209 - // Ensure the data is in UTF-8 and fix any encoding issues 210 - const encoder = new TextEncoder(); 211 - const decoder = new TextDecoder("utf-8"); 212 - const utf8Bytes = encoder.encode(event.target.result); 213 - const utf8Data = decoder.decode(utf8Bytes); 214 - const fixedData = fixUTF8Encoding(utf8Data); 215 - 216 - const converted = convert(fixedData, "srt"); 207 + const converted = convert(event.target.result, "srt"); 217 208 setCaption({ 218 209 language: "custom", 219 210 srtData: converted, ··· 309 300 reader.addEventListener("load", (e) => { 310 301 if (!e.target || typeof e.target.result !== "string") return; 311 302 312 - const encoder = new TextEncoder(); 313 - const decoder = new TextDecoder("utf-8"); 314 - const utf8Bytes = encoder.encode(e.target.result); 315 - const utf8Data = decoder.decode(utf8Bytes); 316 - const fixedData = fixUTF8Encoding(utf8Data); 317 - 318 - const converted = convert(fixedData, "srt"); 303 + const converted = convert(e.target.result, "srt"); 319 304 320 305 setCaption({ 321 306 language: "custom", ··· 324 309 }); 325 310 }); 326 311 327 - reader.readAsText(firstFile, "utf-8"); 312 + reader.readAsText(firstFile); 328 313 } 329 314 330 315 // Render subtitle option
+2 -63
src/components/player/utils/captions.ts
··· 8 8 export type CaptionCueType = ContentCaption; 9 9 export const sanitize = DOMPurify.sanitize; 10 10 11 - // UTF-8 character mapping for fixing corrupted special characters 12 - const utf8Map: Record<string, string> = { 13 - "ä": "ä", 14 - "Ä": "Ä", 15 - "ä": "ä", 16 - "Ä": "Ä", 17 - "ö": "ö", 18 - "ö": "ö", 19 - "Ã¥": "å", 20 - "Ã¥": "å", 21 - "é": "é", 22 - "é": "é", 23 - ú: "ú", 24 - ú: "ú", 25 - "ñ": "ñ", 26 - "ñ": "ñ", 27 - "á": "á", 28 - "á": "á", 29 - "í": "í", 30 - "í": "í", 31 - "ó": "ó", 32 - "ó": "ó", 33 - "ü": "ü", 34 - "ü": "ü", 35 - "ç": "ç", 36 - "ç": "ç", 37 - "è": "è", 38 - "è": "è", 39 - "ì": "ì", 40 - "ì": "ì", 41 - "ò": "ò", 42 - "ò": "ò", 43 - "ù": "ù", 44 - "ù": "ù", 45 - ÃÂ: "à", 46 - Ã: "à", 47 - "Â": "", 48 - Â: "", 49 - " ": "", 50 - }; 51 - 52 - /** 53 - * Fixes UTF-8 encoding issues in subtitle text 54 - * Handles common cases where special characters and accents get corrupted 55 - * 56 - * Example: 57 - * Input: "Hyvä on, ohjelma oli tässä." 58 - * Output: "Hyvä on, ohjelma oli tässä." 59 - */ 60 - export function fixUTF8Encoding(text: string): string { 61 - let fixedText = text; 62 - Object.keys(utf8Map).forEach((bad) => { 63 - fixedText = fixedText.split(bad).join(utf8Map[bad]); 64 - }); 65 - return fixedText; 66 - } 67 - 68 11 export function captionIsVisible( 69 12 start: number, 70 13 end: number, ··· 88 31 if (textTrimmed === "") { 89 32 throw new Error("Given text is empty"); 90 33 } 91 - // Fix UTF-8 encoding issues before conversion 92 - const fixedText = fixUTF8Encoding(textTrimmed); 93 - const vtt = convert(fixedText, "vtt"); 34 + const vtt = convert(textTrimmed, "vtt"); 94 35 if (detect(vtt) === "") { 95 36 throw new Error("Invalid subtitle format"); 96 37 } ··· 102 43 if (textTrimmed === "") { 103 44 throw new Error("Given text is empty"); 104 45 } 105 - // Fix UTF-8 encoding issues before conversion 106 - const fixedText = fixUTF8Encoding(textTrimmed); 107 - const srt = convert(fixedText, "srt"); 46 + const srt = convert(textTrimmed, "srt"); 108 47 if (detect(srt) === "") { 109 48 throw new Error("Invalid subtitle format"); 110 49 }