auto select subtitle

This commit is contained in:
frost768 2023-04-06 01:49:33 +03:00
parent 9e961223f6
commit 2178057633
6 changed files with 54 additions and 16 deletions

View File

@ -4,6 +4,10 @@ import DOMPurify from "dompurify";
import { parse, detect, list } from "subsrt-ts";
import { ContentCaption } from "subsrt-ts/dist/types/handler";
export const customCaption = "external-custom";
export function makeCaptionId(caption: MWCaption, isLinked: boolean): string {
return isLinked ? `linked-${caption.langIso}` : `external-${caption.langIso}`;
}
export const subtitleTypeList = list().map((type) => `.${type}`);
export const sanitize = DOMPurify.sanitize;
export async function getCaptionUrl(caption: MWCaption): Promise<string> {

View File

@ -1,4 +1,11 @@
import { MWStreamQuality, MWStreamType } from "@/backend/helpers/streams";
import { getCaptionUrl, makeCaptionId } from "@/backend/helpers/captions";
import {
MWCaption,
MWStreamQuality,
MWStreamType,
} from "@/backend/helpers/streams";
import { captionLanguages } from "@/setup/iso6391";
import { useSettings } from "@/state/settings";
import { useInitialized } from "@/video/components/hooks/useInitialized";
import { useVideoPlayerDescriptor } from "@/video/state/hooks";
import { useControls } from "@/video/state/logic/controls";
@ -10,6 +17,19 @@ interface SourceControllerProps {
quality: MWStreamQuality;
providerId?: string;
embedId?: string;
captions: MWCaption[];
}
async function tryFetch(captions: MWCaption[]) {
for (let i = 0; i < captions.length; i += 1) {
const caption = captions[i];
try {
const blobUrl = await getCaptionUrl(caption);
return { caption, blobUrl };
} catch (error) {
continue;
}
}
return null;
}
export function SourceController(props: SourceControllerProps) {
@ -17,13 +37,35 @@ export function SourceController(props: SourceControllerProps) {
const controls = useControls(descriptor);
const { initialized } = useInitialized(descriptor);
const didInitialize = useRef<boolean>(false);
const { captionSettings } = useSettings();
useEffect(() => {
if (didInitialize.current) return;
if (!initialized) return;
controls.setSource(props);
// get preferred language
const preferredLanguage = captionLanguages.find(
(v) => v.id === captionSettings.language
);
if (!preferredLanguage) return;
const captions = props.captions.filter(
(v) =>
// langIso may contain the English name or the native name of the language
v.langIso.indexOf(preferredLanguage.englishName) !== -1 ||
v.langIso.indexOf(preferredLanguage.nativeName) !== -1
);
if (!captions) return;
// caption url can return a response other than 200
// that's why we fetch until we get a 200 response
tryFetch(captions).then((response) => {
// none of them were successful
if (!response) return;
// set the preferred language
const id = makeCaptionId(response.caption, true);
controls.setCaption(id, response.blobUrl);
});
didInitialize.current = true;
}, [props, controls, initialized]);
}, [props, controls, initialized, captionSettings.language]);
return null;
}

View File

@ -1,5 +1,7 @@
import {
customCaption,
getCaptionUrl,
makeCaptionId,
parseSubtitles,
subtitleTypeList,
} from "@/backend/helpers/captions";
@ -17,11 +19,6 @@ import { useMemo, useRef } from "react";
import { useTranslation } from "react-i18next";
import { PopoutListEntry, PopoutSection } from "./PopoutUtils";
const customCaption = "external-custom";
function makeCaptionId(caption: MWCaption, isLinked: boolean): string {
return isLinked ? `linked-${caption.langIso}` : `external-${caption.langIso}`;
}
export function CaptionSelectionPopout(props: {
router: ReturnType<typeof useFloatingRouter>;
prefix: string;

View File

@ -106,14 +106,7 @@ export function CaptionSettingsPopout(props: {
captionSettings.style.backgroundColor.substring(7, 9),
16
)}
onChange={(e) =>
setCaptionBackgroundColor(
`${captionSettings.style.backgroundColor.substring(
0,
7
)}${e.target.valueAsNumber.toString(16)}`
)
}
onChange={(e) => setCaptionBackgroundColor(e.target.valueAsNumber)}
/>
<div className="flex flex-row justify-between">
<label className="font-bold" htmlFor="color">

View File

@ -66,6 +66,7 @@ export default function VideoTesterView() {
source={video.streamUrl}
type={videoType}
quality={MWStreamQuality.QUNKNOWN}
captions={[]}
/>
</VideoPlayer>
</div>

View File

@ -148,6 +148,7 @@ export function MediaViewPlayer(props: MediaViewPlayerProps) {
quality={props.stream.quality}
embedId={props.stream.embedId}
providerId={props.stream.providerId}
captions={props.stream.captions}
/>
<ProgressListenerController
startAt={firstStartTime.current}