Merge branch 'feat/audio-select'

This commit is contained in:
Fredrik Burmester
2024-08-13 13:27:09 +02:00
9 changed files with 253 additions and 19 deletions

View File

@@ -34,6 +34,8 @@ import CastContext, {
import { chromecastProfile } from "@/utils/profiles/chromecast";
import ios12 from "@/utils/profiles/ios12";
import { currentlyPlayingItemAtom } from "@/components/CurrentlyPlayingBar";
import { AudioTrackSelector } from "@/components/AudioTrackSelector";
import { SubtitleTrackSelector } from "@/components/SubtitleTrackSelector";
const page: React.FC = () => {
const local = useLocalSearchParams();
@@ -45,7 +47,9 @@ const page: React.FC = () => {
const castDevice = useCastDevice();
const chromecastReady = useMemo(() => !!castDevice?.deviceId, [castDevice]);
const [selectedAudioStream, setSelectedAudioStream] = useState<number>(-1);
const [selectedSubtitleStream, setSelectedSubtitleStream] =
useState<number>(0);
const [maxBitrate, setMaxBitrate] = useState<Bitrate>({
key: "Max",
value: undefined,
@@ -95,7 +99,13 @@ const page: React.FC = () => {
});
const { data: playbackUrl } = useQuery({
queryKey: ["playbackUrl", item?.Id, maxBitrate, castDevice],
queryKey: [
"playbackUrl",
item?.Id,
maxBitrate,
castDevice,
selectedAudioStream,
],
queryFn: async () => {
if (!api || !user?.Id || !sessionData) return null;
@@ -107,8 +117,12 @@ const page: React.FC = () => {
maxStreamingBitrate: maxBitrate.value,
sessionData,
deviceProfile: castDevice?.deviceId ? chromecastProfile : ios12,
audioStreamIndex: selectedAudioStream,
subtitleStreamIndex: selectedSubtitleStream,
});
console.log("Transcode URL: ", url);
return url;
},
enabled: !!sessionData,
@@ -247,15 +261,23 @@ const page: React.FC = () => {
<Text>{item.Overview}</Text>
</View>
<View className="flex flex-col p-4">
<BitrateSelector
onChange={(val) => setMaxBitrate(val)}
selected={maxBitrate}
/>
<PlayButton
item={item}
chromecastReady={chromecastReady}
onPress={onPressPlay}
/>
<View className="flex flex-row items-center space-x-2 w-full">
<BitrateSelector
onChange={(val) => setMaxBitrate(val)}
selected={maxBitrate}
/>
<AudioTrackSelector
item={item}
onChange={setSelectedAudioStream}
selected={selectedAudioStream}
/>
<SubtitleTrackSelector
item={item}
onChange={setSelectedSubtitleStream}
selected={selectedSubtitleStream}
/>
</View>
<PlayButton item={item} chromecastReady={false} onPress={onPressPlay} />
</View>
<ScrollView horizontal className="flex px-4 mb-4">
<View className="flex flex-row space-x-2 ">

View File

@@ -78,7 +78,7 @@ export default function RootLayout() {
<JellyfinProvider>
<StatusBar style="light" backgroundColor="#000" />
<ThemeProvider value={DarkTheme}>
<Stack screenOptions={{}}>
<Stack>
<Stack.Screen
name="(auth)/(tabs)"
options={{

View File

@@ -3,6 +3,7 @@ import { Input } from "@/components/common/Input";
import { Text } from "@/components/common/Text";
import { apiAtom, useJellyfin } from "@/providers/JellyfinProvider";
import { Ionicons } from "@expo/vector-icons";
import { AxiosError } from "axios";
import { useAtom } from "jotai";
import React, { useMemo, useState } from "react";
import { KeyboardAvoidingView, Platform, View } from "react-native";
@@ -18,6 +19,7 @@ const Login: React.FC = () => {
const [api] = useAtom(apiAtom);
const [serverURL, setServerURL] = useState<string>("");
const [error, setError] = useState<string>("");
const [credentials, setCredentials] = useState<{
username: string;
password: string;
@@ -36,7 +38,18 @@ const Login: React.FC = () => {
await login(credentials.username, credentials.password);
}
} catch (error) {
console.error(error);
const e = error as AxiosError | z.ZodError;
if (e instanceof z.ZodError) {
setError("An error occured.");
} else {
if (e.response?.status === 401) {
setError("Invalid credentials.");
} else {
setError(
"A network error occurred. Did you enter the correct server URL?",
);
}
}
} finally {
setLoading(false);
}
@@ -122,6 +135,8 @@ const Login: React.FC = () => {
/>
</View>
<Text className="text-red-600 mb-2">{error}</Text>
<Button onPress={handleLogin} loading={loading}>
Log in
</Button>