Added bandaid fix

This commit is contained in:
Alex Kim
2024-12-13 05:03:16 +11:00
parent 4291ef55b9
commit a9b1d9fb0a
6 changed files with 205 additions and 65 deletions

View File

@@ -20,6 +20,7 @@ import { getLogoImageUrlById } from "@/utils/jellyfin/image/getLogoImageUrlById"
import {
BaseItemDto,
MediaSourceInfo,
MediaStream,
} from "@jellyfin/sdk/lib/generated-client/models";
import { Image } from "expo-image";
import { useNavigation } from "expo-router";
@@ -32,6 +33,7 @@ import { Chromecast } from "./Chromecast";
import { ItemHeader } from "./ItemHeader";
import { MediaSourceSelector } from "./MediaSourceSelector";
import { MoreMoviesWithActor } from "./MoreMoviesWithActor";
import { SubtitleHelper } from "@/utils/SubtitleHelper";
export type SelectedOptions = {
bitrate: Bitrate;
@@ -109,6 +111,36 @@ export const ItemContent: React.FC<{ item: BaseItemDto }> = React.memo(
return Boolean(logoUrl && loadingLogo);
}, [loadingLogo, logoUrl]);
const [isTranscoding, setIsTranscoding] = useState(false);
const [previouslyChosenSubtitleIndex, setPreviouslyChosenSubtitleIndex] =
useState<number | undefined>(selectedOptions?.subtitleIndex);
useEffect(() => {
const isTranscoding = Boolean(selectedOptions?.bitrate.value);
if (isTranscoding) {
setPreviouslyChosenSubtitleIndex(selectedOptions?.subtitleIndex);
const subHelper = new SubtitleHelper(
selectedOptions?.mediaSource?.MediaStreams ?? []
);
const newSubtitleIndex = subHelper.getMostCommonSubtitleByName(
selectedOptions?.subtitleIndex
);
setSelectedOptions((prev) => ({
...prev!,
subtitleIndex: newSubtitleIndex ?? -1,
}));
}
if (!isTranscoding && previouslyChosenSubtitleIndex !== undefined) {
setSelectedOptions((prev) => ({
...prev!,
subtitleIndex: previouslyChosenSubtitleIndex,
}));
}
setIsTranscoding(isTranscoding);
}, [selectedOptions?.bitrate]);
if (!selectedOptions) return null;
return (
@@ -199,6 +231,7 @@ export const ItemContent: React.FC<{ item: BaseItemDto }> = React.memo(
selected={selectedOptions.audioIndex}
/>
<SubtitleTrackSelector
isTranscoding={isTranscoding}
source={selectedOptions.mediaSource}
onChange={(val) =>
setSelectedOptions(

View File

@@ -1,26 +1,34 @@
import { tc } from "@/utils/textTools";
import { MediaSourceInfo } from "@jellyfin/sdk/lib/generated-client/models";
import { useMemo } from "react";
import { TouchableOpacity, View } from "react-native";
import { Platform, TouchableOpacity, View } from "react-native";
import * as DropdownMenu from "zeego/dropdown-menu";
import { Text } from "./common/Text";
import { SubtitleHelper } from "@/utils/SubtitleHelper";
interface Props extends React.ComponentProps<typeof View> {
source?: MediaSourceInfo;
onChange: (value: number) => void;
selected?: number | undefined;
isTranscoding?: boolean;
}
export const SubtitleTrackSelector: React.FC<Props> = ({
source,
onChange,
selected,
isTranscoding,
...props
}) => {
const subtitleStreams = useMemo(
() => source?.MediaStreams?.filter((x) => x.Type === "Subtitle") ?? [],
[source]
);
const subtitleStreams = useMemo(() => {
const subtitleHelper = new SubtitleHelper(source?.MediaStreams ?? []);
if (isTranscoding && Platform.OS === "ios") {
return subtitleHelper.getUniqueSubtitles();
}
return subtitleHelper.getSubtitles();
}, [source, isTranscoding]);
const selectedSubtitleSteam = useMemo(
() => subtitleStreams.find((x) => x.Index === selected),

View File

@@ -8,6 +8,7 @@ import { TranscodedSubtitle } from "../types";
import { useAtomValue } from "jotai";
import { apiAtom } from "@/providers/JellyfinProvider";
import { useLocalSearchParams, useRouter } from "expo-router";
import { SubtitleHelper } from "@/utils/SubtitleHelper";
interface DropdownViewProps {
showControls: boolean;
@@ -43,6 +44,8 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
mediaSource?.MediaStreams?.filter((x) => x.Type === "Subtitle") ?? [];
const textBasedSubs = allSubs.filter((x) => x.IsTextSubtitleStream);
const subtitleHelper = new SubtitleHelper(mediaSource?.MediaStreams ?? []);
const allSubtitleTracksForTranscodingStream = useMemo(() => {
const disableSubtitle = {
name: "Disable",
@@ -57,28 +60,9 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
IsTextSubtitleStream: true,
})) || [];
console.log("textSubtitles", textSubtitles);
let textIndex = 0; // To track position in textSubtitles
// Merge text and image subtitles in the order of allSubs
const sortedSubtitles = allSubs.map((sub) => {
if (sub.IsTextSubtitleStream) {
if (textSubtitles.length === 0) return disableSubtitle;
const textSubtitle = textSubtitles[textIndex];
if (!textSubtitle) return disableSubtitle;
textIndex++;
return textSubtitle;
} else {
return {
name: sub.DisplayTitle!,
index: sub.Index!,
IsTextSubtitleStream: sub.IsTextSubtitleStream,
} as TranscodedSubtitle;
}
});
const sortedSubtitles = subtitleHelper.getSortedSubtitles(textSubtitles);
console.log("sortedSubtitles", sortedSubtitles);
return [disableSubtitle, ...sortedSubtitles];
}
@@ -114,16 +98,6 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
index: x.Index!,
})) || [];
// HLS stream indexes are not the same as the actual source indexes.
// This function aims to get the source subtitle index from the embedded track index.
const getSourceSubtitleIndex = (embeddedTrackIndex: number): number => {
// If we're not on text-based subtitles, return the embedded track index
if (!isOnTextSubtitle) {
return parseInt(subtitleIndex);
}
return textBasedSubs[embeddedTrackIndex]?.Index ?? -1;
};
const ChangeTranscodingAudio = useCallback(
(audioIndex: number) => {
console.log("ChangeTranscodingAudio", subtitleIndex, audioIndex);
@@ -182,7 +156,9 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
value={
subtitleIndex ===
(isOnTextSubtitle && sub.IsTextSubtitleStream
? getSourceSubtitleIndex(sub.index).toString()
? subtitleHelper
.getSourceSubtitleIndex(sub.index)
.toString()
: sub?.index.toString())
}
key={`subtitle-item-${idx}`}
@@ -191,17 +167,18 @@ const DropdownView: React.FC<DropdownViewProps> = ({ showControls }) => {
if (
subtitleIndex ===
(isOnTextSubtitle && sub.IsTextSubtitleStream
? getSourceSubtitleIndex(sub.index).toString()
? subtitleHelper
.getSourceSubtitleIndex(sub.index)
.toString()
: sub?.index.toString())
)
return;
router.setParams({
subtitleIndex: getSourceSubtitleIndex(
sub.index
).toString(),
subtitleIndex: subtitleHelper
.getSourceSubtitleIndex(sub.index)
.toString(),
});
console.log("Got here");
if (sub.IsTextSubtitleStream && isOnTextSubtitle) {
setSubtitleTrack && setSubtitleTrack(sub.index);