From 055b95830ced5ffa440146819f6de5fd8ac1c20d Mon Sep 17 00:00:00 2001 From: Pinapelz Date: Wed, 29 Jul 2026 22:29:32 -0700 Subject: add support for srv3 subtitles --- pages/index.tsx | 57 ++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 48 insertions(+), 9 deletions(-) (limited to 'pages/index.tsx') diff --git a/pages/index.tsx b/pages/index.tsx index a008fdc..ee80836 100644 --- a/pages/index.tsx +++ b/pages/index.tsx @@ -17,12 +17,13 @@ const CustomPlayerPage = () => { const [urlVideo, setUrlVideo] = React.useState(""); const [urlChat, setUrlChat] = React.useState(""); const [urlYtt, setUrlYtt] = React.useState(""); + const [captionFormat, setCaptionFormat] = React.useState<"srv3" | "srt" | undefined>(undefined); const [infoJson, setInfoJson] = React.useState({} as any); const [showPlayer, setShowPlayer] = React.useState(false); const [dataSet, setDataSet] = React.useState(false); const { query } = router; - const jsonDataUrl = query.jsonData as string; + const jsonDataUrl = query.data as string; const timeSeconds = query.time as string; useEffect(() => { @@ -36,7 +37,7 @@ const CustomPlayerPage = () => { fetch(jsonDataUrl) .then((res) => res.json()) .then((data) => { - const { info, video, chat, srv3, ts } = data; + const { info, video, chat, srv3, srt, captions } = data; if (info) { fetch(info) .then((res) => res.json()) @@ -52,6 +53,16 @@ const CustomPlayerPage = () => { } if (srv3) { setUrlYtt(srv3); + setCaptionFormat("srv3"); + } else if (srt) { + setUrlYtt(srt); + setCaptionFormat("srt"); + } else if (captions) { + const cap = Array.isArray(captions) ? captions[0] : captions; + if (cap?.src) { + setUrlYtt(cap.src); + setCaptionFormat(cap.format || (cap.src.toLowerCase().endsWith(".srt") ? "srt" : "srv3")); + } } setDataSet(true); setShowPlayer(true); @@ -66,7 +77,8 @@ const CustomPlayerPage = () => { const handleFile = ( e: React.ChangeEvent, - setter: (newValue: string) => any + setter: (newValue: string) => any, + opts?: { onFormat?: (format: "srv3" | "srt") => void } ) => { const file = e.target.files?.[0]; if (!file) { @@ -75,6 +87,10 @@ const CustomPlayerPage = () => { } const url = URL.createObjectURL(file).toString(); console.log(url); + if (opts?.onFormat) { + const name = file.name.toLowerCase(); + opts.onFormat(name.endsWith(".srt") ? "srt" : "srv3"); + } setter(url); }; @@ -84,10 +100,10 @@ const CustomPlayerPage = () => { { infoJson && infoJson.title ? ( {infoJson.title} - ) : + ) : a very nice video } - + {showPlayer ? (
@@ -114,6 +130,7 @@ const CustomPlayerPage = () => { { lang: "en", src: urlYtt, + format: captionFormat, }, ] : undefined @@ -177,7 +194,7 @@ const CustomPlayerPage = () => { ) : (
-

Custom Video Player

+

Moekyun Video Player

You can play locally-saved video files and chat replay JSON

@@ -238,14 +255,19 @@ const CustomPlayerPage = () => { @@ -255,12 +277,29 @@ const CustomPlayerPage = () => { onClick={() => { setShowPlayer(true); setDataSet(false); - }} > Launch player +
+

JSON data format

+

+ Pass a URL via the ?data= query parameter pointing to a JSON file. + All fields are optional. Recognized top-level keys: +

+
    +
  • info - URL to a YouTube info.json (yt-dlp metadata)
  • +
  • video - URL to the video file/stream
  • +
  • chat - URL to a chat replay JSON
  • +
  • srv3 - URL to a YouTube srv3 caption XML file
  • +
  • srt - URL to a SubRip (.srt) subtitle file
  • +
  • captions - a single object {`{ src, format }`} or an array of them, where format is "srv3" or "srt"
  • +
+

+ Example: {`?data=https://example.com/session.json`} +

+
)} -- cgit v1.2.3