diff --git a/src/components/player/atoms/settings/CaptionsView.tsx b/src/components/player/atoms/settings/CaptionsView.tsx
index dc9a112f..3d89655d 100644
--- a/src/components/player/atoms/settings/CaptionsView.tsx
+++ b/src/components/player/atoms/settings/CaptionsView.tsx
@@ -75,6 +75,7 @@ function CustomCaptionOption() {
setCaption({
language: "custom",
srtData: converted,
+ id: "custom-caption",
});
setCustomSubs();
});
@@ -115,22 +116,22 @@ function useSubtitleList(subs: CaptionListItem[], searchQuery: string) {
export function CaptionsView({ id }: { id: string }) {
const { t } = useTranslation();
const router = useOverlayRouter(id);
- const lang = usePlayerStore((s) => s.caption.selected?.language);
+ const selectedCaptionId = usePlayerStore((s) => s.caption.selected?.id);
const [currentlyDownloading, setCurrentlyDownloading] = useState<
string | null
>(null);
- const { selectLanguage, disable } = useCaptions();
+ const { selectCaptionById, disable } = useCaptions();
const captionList = usePlayerStore((s) => s.captionList);
const [searchQuery, setSearchQuery] = useState("");
const subtitleList = useSubtitleList(captionList, searchQuery);
const [downloadReq, startDownload] = useAsyncFn(
- async (language: string) => {
- setCurrentlyDownloading(language);
- return selectLanguage(language);
+ async (captionId: string) => {
+ setCurrentlyDownloading(captionId);
+ return selectCaptionById(captionId);
},
- [selectLanguage, setCurrentlyDownloading],
+ [selectCaptionById, setCurrentlyDownloading],
);
const content = subtitleList.map((v, i) => {
@@ -140,14 +141,14 @@ export function CaptionsView({ id }: { id: string }) {
// eslint-disable-next-line react/no-array-index-key
key={`${i}-${v.url}`}
countryCode={v.language}
- selected={lang === v.language}
- loading={v.language === currentlyDownloading && downloadReq.loading}
+ selected={v.id === selectedCaptionId}
+ loading={v.id === currentlyDownloading && downloadReq.loading}
error={
- v.language === currentlyDownloading && downloadReq.error
+ v.id === currentlyDownloading && downloadReq.error
? downloadReq.error.toString()
: undefined
}
- onClick={() => startDownload(v.language)}
+ onClick={() => startDownload(v.id)}
>
{v.languageName}
@@ -176,7 +177,7 @@ export function CaptionsView({ id }: { id: string }) {
- disable()} selected={!lang}>
+ disable()} selected={!selectedCaptionId}>
{t("player.menus.subtitles.offChoice")}
diff --git a/src/components/player/display/displayInterface.ts b/src/components/player/display/displayInterface.ts
index 604bdeca..8ba8480a 100644
--- a/src/components/player/display/displayInterface.ts
+++ b/src/components/player/display/displayInterface.ts
@@ -41,6 +41,7 @@ export interface DisplayMeta {
}
export interface DisplayCaption {
+ id: string;
srtData: string;
language: string;
url?: string;
diff --git a/src/components/player/hooks/useCaptions.ts b/src/components/player/hooks/useCaptions.ts
index 9f96c41c..0f79aa51 100644
--- a/src/components/player/hooks/useCaptions.ts
+++ b/src/components/player/hooks/useCaptions.ts
@@ -14,12 +14,30 @@ export function useCaptions() {
const lastSelectedLanguage = useSubtitleStore((s) => s.lastSelectedLanguage);
const captionList = usePlayerStore((s) => s.captionList);
+ const selectCaptionById = useCallback(
+ async (captionId: string) => {
+ const caption = captionList.find((v) => v.id === captionId);
+ if (!caption) return;
+ const srtData = await downloadCaption(caption);
+ setCaption({
+ id: caption.id,
+ language: caption.language,
+ srtData,
+ url: caption.url,
+ });
+ resetSubtitleSpecificSettings();
+ setLanguage(caption.language);
+ },
+ [setLanguage, captionList, setCaption, resetSubtitleSpecificSettings],
+ );
+
const selectLanguage = useCallback(
async (language: string) => {
const caption = captionList.find((v) => v.language === language);
if (!caption) return;
const srtData = await downloadCaption(caption);
setCaption({
+ id: caption.id,
language: caption.language,
srtData,
url: caption.url,
@@ -56,5 +74,6 @@ export function useCaptions() {
selectLastUsedLanguage,
toggleLastUsed,
selectLastUsedLanguageIfEnabled,
+ selectCaptionById,
};
}
diff --git a/src/components/player/utils/captions.ts b/src/components/player/utils/captions.ts
index abccee9f..bc2079db 100644
--- a/src/components/player/utils/captions.ts
+++ b/src/components/player/utils/captions.ts
@@ -80,6 +80,7 @@ export function convertProviderCaption(
captions: RunOutput["stream"]["captions"],
): CaptionListItem[] {
return captions.map((v) => ({
+ id: v.id,
language: v.language,
url: v.url,
needsProxy: v.hasCorsRestrictions,
diff --git a/src/stores/player/slices/source.ts b/src/stores/player/slices/source.ts
index 56e84f74..1e26abc2 100644
--- a/src/stores/player/slices/source.ts
+++ b/src/stores/player/slices/source.ts
@@ -42,12 +42,14 @@ export interface PlayerMeta {
}
export interface Caption {
+ id: string;
language: string;
url?: string;
srtData: string;
}
export interface CaptionListItem {
+ id: string;
language: string;
url: string;
needsProxy: boolean;