fix custom subs + download

This commit is contained in:
mrjvs 2023-10-25 19:14:41 +02:00
parent 0883942093
commit ca402a219d
5 changed files with 40 additions and 12 deletions

View file

@ -13,7 +13,7 @@ interface Props {
className?: string;
href?: string;
disabled?: boolean;
download?: boolean;
download?: string;
}
export function Button(props: Props) {

View file

@ -15,6 +15,7 @@ import { Input } from "@/components/player/internals/ContextMenu/Input";
import { SelectableLink } from "@/components/player/internals/ContextMenu/Links";
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
import { usePlayerStore } from "@/stores/player/store";
import { useSubtitleStore } from "@/stores/subtitles";
export function CaptionOption(props: {
countryCode?: string;
@ -94,6 +95,7 @@ function searchSubs(
function CustomCaptionOption() {
const lang = usePlayerStore((s) => s.caption.selected?.language);
const setCaption = usePlayerStore((s) => s.setCaption);
const setCustomSubs = useSubtitleStore((s) => s.setCustomSubs);
const fileInput = useRef<HTMLInputElement>(null);
return (
@ -118,6 +120,7 @@ function CustomCaptionOption() {
language: "custom",
srtData: converted,
});
setCustomSubs();
});
reader.readAsText(e.target.files[0], "utf-8");
}}
@ -126,9 +129,7 @@ function CustomCaptionOption() {
);
}
// TODO on initialize, download captions
// TODO fix language names, some are unknown
// TODO delay setting for captions
export function CaptionsView({ id }: { id: string }) {
const router = useOverlayRouter(id);
const lang = usePlayerStore((s) => s.caption.selected?.language);

View file

@ -4,7 +4,7 @@ import { Button } from "@/components/Button";
import { Icon, Icons } from "@/components/Icon";
import { OverlayPage } from "@/components/overlays/OverlayPage";
import { Menu } from "@/components/player/internals/ContextMenu";
import { convertSubtitlesToDataurl } from "@/components/player/utils/captions";
import { convertSubtitlesToSrtDataurl } from "@/components/player/utils/captions";
import { useOverlayRouter } from "@/hooks/useOverlayRouter";
import { usePlayerStore } from "@/stores/player/store";
@ -24,11 +24,13 @@ export function DownloadView({ id }: { id: string }) {
const downloadUrl = useDownloadLink();
const selectedCaption = usePlayerStore((s) => s.caption?.selected);
const subtitleUrl = selectedCaption
? convertSubtitlesToDataurl(selectedCaption?.srtData)
: null;
console.log(subtitleUrl);
const subtitleUrl = useMemo(
() =>
selectedCaption
? convertSubtitlesToSrtDataurl(selectedCaption?.srtData)
: null,
[selectedCaption]
);
if (!downloadUrl) return null;
@ -66,7 +68,7 @@ export function DownloadView({ id }: { id: string }) {
href={subtitleUrl ?? undefined}
disabled={!subtitleUrl}
theme="secondary"
download
download="subtitles.srt"
>
Download current caption
</Button>

View file

@ -35,13 +35,31 @@ export function convertSubtitlesToVtt(text: string): string {
return vtt;
}
export function convertSubtitlesToSrt(text: string): string {
const textTrimmed = text.trim();
if (textTrimmed === "") {
throw new Error("Given text is empty");
}
const srt = convert(textTrimmed, "srt");
if (detect(srt) === "") {
throw new Error("Invalid subtitle format");
}
return srt;
}
export function parseSubtitles(text: string): CaptionCueType[] {
const vtt = convertSubtitlesToVtt(text);
return parse(vtt).filter((cue) => cue.type === "caption") as CaptionCueType[];
}
export function convertSubtitlesToDataurl(text: string): string {
return `data:text/vtt,${convertSubtitlesToVtt(text)}`;
function stringToBase64(input: string): string {
return btoa(String.fromCodePoint(...new TextEncoder().encode(input)));
}
export function convertSubtitlesToSrtDataurl(text: string): string {
return `data:application/x-subrip;base64,${stringToBase64(
convertSubtitlesToSrt(text)
)}`;
}
export function convertSubtitlesToObjectUrl(text: string): string {

View file

@ -27,6 +27,7 @@ export interface SubtitleStore {
delay: number;
updateStyling(newStyling: Partial<SubtitleStyling>): void;
setLanguage(language: string | null): void;
setCustomSubs(): void;
setOverrideCasing(enabled: boolean): void;
setDelay(delay: number): void;
}
@ -60,6 +61,12 @@ export const useSubtitleStore = create(
if (lang) s.lastSelectedLanguage = lang;
});
},
setCustomSubs() {
set((s) => {
s.enabled = true;
s.lastSelectedLanguage = null;
});
},
setOverrideCasing(enabled) {
set((s) => {
s.overrideCasing = enabled;