mirror of
https://github.com/sussy-code/smov.git
synced 2024-12-20 14:37:43 +01:00
Apply requested changes
This commit is contained in:
parent
c1f9382f50
commit
810a12a097
4 changed files with 37 additions and 40 deletions
|
@ -60,7 +60,6 @@ export async function downloadWebVTT(url: string): Promise<string> {
|
||||||
const cached = downloadCache.get(url);
|
const cached = downloadCache.get(url);
|
||||||
if (cached) return cached;
|
if (cached) return cached;
|
||||||
|
|
||||||
// Q: should this use proxiedFetch or sendExtensionRequest?
|
|
||||||
const data = await fetch(url).then((v) => v.text());
|
const data = await fetch(url).then((v) => v.text());
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,6 @@ export function makeVideoElementDisplayInterface(): DisplayInterface {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.log("Subtitle tracks loaded", hls?.subtitleTracks);
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,9 +3,25 @@ import subsrt from "subsrt-ts";
|
||||||
import { ContentCaption } from "subsrt-ts/dist/types/handler";
|
import { ContentCaption } from "subsrt-ts/dist/types/handler";
|
||||||
|
|
||||||
import { downloadCaption, downloadWebVTT } from "@/backend/helpers/subs";
|
import { downloadCaption, downloadWebVTT } from "@/backend/helpers/subs";
|
||||||
|
import { Caption } from "@/stores/player/slices/source";
|
||||||
import { usePlayerStore } from "@/stores/player/store";
|
import { usePlayerStore } from "@/stores/player/store";
|
||||||
import { useSubtitleStore } from "@/stores/subtitles";
|
import { useSubtitleStore } from "@/stores/subtitles";
|
||||||
|
|
||||||
|
import { parseVttSubtitles } from "../utils/captions";
|
||||||
|
|
||||||
|
const filterDuplicateCaptionCues = (cues: ContentCaption[]) =>
|
||||||
|
cues.reduce((acc: ContentCaption[], cap: ContentCaption) => {
|
||||||
|
const lastCap = acc[acc.length - 1];
|
||||||
|
const isSameAsLast =
|
||||||
|
lastCap?.start === cap.start &&
|
||||||
|
lastCap?.end === cap.end &&
|
||||||
|
lastCap?.content === cap.content;
|
||||||
|
if (lastCap === undefined || !isSameAsLast) {
|
||||||
|
acc.push(cap);
|
||||||
|
}
|
||||||
|
return acc;
|
||||||
|
}, []);
|
||||||
|
|
||||||
export function useCaptions() {
|
export function useCaptions() {
|
||||||
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
const setLanguage = useSubtitleStore((s) => s.setLanguage);
|
||||||
const enabled = useSubtitleStore((s) => s.enabled);
|
const enabled = useSubtitleStore((s) => s.enabled);
|
||||||
|
@ -33,16 +49,17 @@ export function useCaptions() {
|
||||||
async (captionId: string) => {
|
async (captionId: string) => {
|
||||||
const caption = captions.find((v) => v.id === captionId);
|
const caption = captions.find((v) => v.id === captionId);
|
||||||
if (!caption) return;
|
if (!caption) return;
|
||||||
if (!caption.hls) {
|
|
||||||
const srtData = await downloadCaption(caption);
|
const captionToSet: Caption = {
|
||||||
setCaption({
|
|
||||||
id: caption.id,
|
id: caption.id,
|
||||||
language: caption.language,
|
language: caption.language,
|
||||||
srtData,
|
|
||||||
url: caption.url,
|
url: caption.url,
|
||||||
});
|
srtData: "",
|
||||||
resetSubtitleSpecificSettings();
|
};
|
||||||
setLanguage(caption.language);
|
|
||||||
|
if (!caption.hls) {
|
||||||
|
const srtData = await downloadCaption(caption);
|
||||||
|
captionToSet.srtData = srtData;
|
||||||
} else {
|
} else {
|
||||||
// request a language change to hls, so it can load the subtitles
|
// request a language change to hls, so it can load the subtitles
|
||||||
await setSubtitlePreference?.(caption.language);
|
await setSubtitlePreference?.(caption.language);
|
||||||
|
@ -60,42 +77,20 @@ export function useCaptions() {
|
||||||
await Promise.all(
|
await Promise.all(
|
||||||
fragments.map(async (frag) => {
|
fragments.map(async (frag) => {
|
||||||
const vtt = await downloadWebVTT(frag.url);
|
const vtt = await downloadWebVTT(frag.url);
|
||||||
const parsed = subsrt.parse(vtt);
|
return parseVttSubtitles(vtt);
|
||||||
return parsed.filter(
|
|
||||||
(c) => c.type === "caption",
|
|
||||||
) as ContentCaption[];
|
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
).flat();
|
).flat();
|
||||||
|
|
||||||
// for some reason, in some cases there will be captions
|
const filtered = filterDuplicateCaptionCues(vttCaptions);
|
||||||
// with the same start/end times, the same text duplicated
|
|
||||||
const filtered = vttCaptions.reduce(
|
|
||||||
(acc: ContentCaption[], cap: ContentCaption) => {
|
|
||||||
const lastCap = acc[acc.length - 1];
|
|
||||||
const isSameAsLast =
|
|
||||||
lastCap?.start === cap.start &&
|
|
||||||
lastCap?.end === cap.end &&
|
|
||||||
lastCap?.content === cap.content;
|
|
||||||
if (lastCap === undefined || !isSameAsLast) {
|
|
||||||
acc.push(cap);
|
|
||||||
}
|
|
||||||
return acc;
|
|
||||||
},
|
|
||||||
[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const srtData = subsrt.build(filtered, { format: "srt" });
|
const srtData = subsrt.build(filtered, { format: "srt" });
|
||||||
|
captionToSet.srtData = srtData;
|
||||||
|
}
|
||||||
|
|
||||||
setCaption({
|
setCaption(captionToSet);
|
||||||
id: caption.id,
|
|
||||||
language: caption.language,
|
|
||||||
srtData,
|
|
||||||
url: caption.url,
|
|
||||||
});
|
|
||||||
resetSubtitleSpecificSettings();
|
resetSubtitleSpecificSettings();
|
||||||
setLanguage(caption.language);
|
setLanguage(caption.language);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
[
|
[
|
||||||
setLanguage,
|
setLanguage,
|
||||||
|
|
|
@ -50,12 +50,16 @@ export function convertSubtitlesToSrt(text: string): string {
|
||||||
return srt;
|
return srt;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function parseVttSubtitles(vtt: string) {
|
||||||
|
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
||||||
|
}
|
||||||
|
|
||||||
export function parseSubtitles(
|
export function parseSubtitles(
|
||||||
text: string,
|
text: string,
|
||||||
_language?: string,
|
_language?: string,
|
||||||
): CaptionCueType[] {
|
): CaptionCueType[] {
|
||||||
const vtt = convertSubtitlesToVtt(text);
|
const vtt = convertSubtitlesToVtt(text);
|
||||||
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
|
return parseVttSubtitles(vtt);
|
||||||
}
|
}
|
||||||
|
|
||||||
function stringToBase64(input: string): string {
|
function stringToBase64(input: string): string {
|
||||||
|
|
Loading…
Reference in a new issue