diff --git a/app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx b/app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx index 071d9127..5f4e8186 100644 --- a/app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx +++ b/app/(auth)/(tabs)/(home,libraries,search)/items/page.tsx @@ -2,6 +2,10 @@ import { Text } from "@/components/common/Text"; import { ItemContent } from "@/components/ItemContent"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { getUserItemData } from "@/utils/jellyfin/user-library/getUserItemData"; +import { + getMediaInfoApi, + getUserLibraryApi, +} from "@jellyfin/sdk/lib/utils/api"; import { useQuery } from "@tanstack/react-query"; import { useLocalSearchParams } from "expo-router"; import { useAtom } from "jotai"; @@ -22,16 +26,16 @@ const Page: React.FC = () => { const { data: item, isError } = useQuery({ queryKey: ["item", id], queryFn: async () => { - const res = await getUserItemData({ - api, - userId: user?.Id, + if (!api) return; + const res = await getUserLibraryApi(api).getItem({ itemId: id, + userId: user?.Id, }); - return res; + return res.data; }, enabled: !!id && !!api, - staleTime: 60 * 1000 * 5, // 5 minutes + staleTime: 0, }); const opacity = useSharedValue(1); diff --git a/app/(auth)/play-music.tsx b/app/(auth)/play-music.tsx index 4138ecc2..12b810cb 100644 --- a/app/(auth)/play-music.tsx +++ b/app/(auth)/play-music.tsx @@ -52,7 +52,6 @@ export default function page() { const togglePlay = useCallback( async (ticks: number) => { - console.log("togglePlay"); Haptics.impactAsync(Haptics.ImpactFeedbackStyle.Light); if (isPlaying) { videoRef.current?.pause(); diff --git a/app/(auth)/vlc-player.tsx b/app/(auth)/vlc-player.tsx index f4ee96d9..a3d4c29e 100644 --- a/app/(auth)/vlc-player.tsx +++ b/app/(auth)/vlc-player.tsx @@ -9,7 +9,7 @@ import { ProgressUpdatePayload, VlcPlayerViewRef, } from "@/modules/vlc-player/src/VlcPlayer.types"; -import { apiAtom } from "@/providers/JellyfinProvider"; +import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { PlaybackType, usePlaySettings, @@ -17,9 +17,11 @@ import { import { useSettings } from "@/utils/atoms/settings"; import { getBackdropUrl } from "@/utils/jellyfin/image/getBackdropUrl"; import { getAuthHeaders } from "@/utils/jellyfin/jellyfin"; +import native from "@/utils/profiles/native"; import { ticksToSeconds } from "@/utils/time"; import { Api } from "@jellyfin/sdk"; -import { getPlaystateApi } from "@jellyfin/sdk/lib/utils/api"; +import { getMediaInfoApi, getPlaystateApi } from "@jellyfin/sdk/lib/utils/api"; +import { useQuery } from "@tanstack/react-query"; import * as Haptics from "expo-haptics"; import { useFocusEffect } from "expo-router"; import { useAtomValue } from "jotai"; @@ -35,13 +37,13 @@ import { useSharedValue } from "react-native-reanimated"; import { SelectedTrackType } from "react-native-video"; export default function page() { - const { playSettings, playUrl, playSessionId } = usePlaySettings(); + const { playSettings, playUrl, playSessionId, mediaSource } = + usePlaySettings(); const api = useAtomValue(apiAtom); const [settings] = useSettings(); const videoRef = useRef(null); const poster = usePoster(playSettings, api); const videoSource = useVideoSource(playSettings, api, poster, playUrl); - const firstTime = useRef(true); const screenDimensions = Dimensions.get("screen"); @@ -54,12 +56,20 @@ export default function page() { const progress = useSharedValue(0); const isSeeking = useSharedValue(false); const cacheProgress = useSharedValue(0); + const user = useAtomValue(userAtom); const [playbackState, setPlaybackState] = useState< PlaybackStatePayload["nativeEvent"] | null >(null); - if (!playSettings || !playUrl || !api || !videoSource || !playSettings.item) + if ( + !playSettings || + !playUrl || + !api || + !videoSource || + !playSettings.item || + !mediaSource + ) return null; const togglePlay = useCallback( @@ -99,7 +109,7 @@ export default function page() { }); } }, - [isPlaying, api, playSettings?.item?.Id, videoRef, settings] + [isPlaying, api, playSettings?.item?.Id, videoRef] ); const play = useCallback(() => { @@ -151,13 +161,6 @@ export default function page() { setIsBuffering(isBuffering); - // console.log("onProgress ~", { - // currentTime, - // duration, - // isBuffering, - // isPlaying, - // }); - progress.value = currentTime; // cacheProgress.value = secondsToTicks(data.playableDuration); @@ -204,46 +207,9 @@ export default function page() { stopPlayback: stop, }); - const selectedSubtitleTrack = useMemo(() => { - const a = playSettings?.mediaSource?.MediaStreams?.find( - (s) => s.Index === playSettings.subtitleIndex - ); - console.log(a); - return a; - }, [playSettings]); - - const [hlsSubTracks, setHlsSubTracks] = useState< - { - index: number; - language?: string | undefined; - selected?: boolean | undefined; - title?: string | undefined; - type: any; - }[] - >([]); - - const selectedTextTrack = useMemo(() => { - for (let st of hlsSubTracks) { - if (st.title === selectedSubtitleTrack?.DisplayTitle) { - return { - type: SelectedTrackType.TITLE, - value: selectedSubtitleTrack?.DisplayTitle ?? "", - }; - } - } - return undefined; - }, [hlsSubTracks]); - const onPlaybackStateChanged = (e: PlaybackStatePayload) => { const { target, state, isBuffering, isPlaying } = e.nativeEvent; - console.log("onPlaybackStateChanged", { - target, - state, - isBuffering, - isPlaying, - }); - if (state === "Playing") { setIsPlaying(true); return; @@ -299,12 +265,9 @@ export default function page() { onVideoProgress={onProgress} progressUpdateInterval={1000} onVideoStateChange={onPlaybackStateChanged} - onVideoLoadStart={() => { - console.log("onVideoLoadStart"); - }} + onVideoLoadStart={() => {}} onVideoLoadEnd={() => { setIsVideoLoaded(true); - console.log("onVideoLoadEnd"); }} /> @@ -325,6 +288,7 @@ export default function page() { /> */} { if (!token || !deviceId || !baseDirectory) return BackgroundFetch.BackgroundFetchResult.NoData; - console.log({ - token, - url, - deviceId, - }); - const jobs = await getAllJobsByDeviceId({ deviceId, authHeader: token, @@ -120,14 +114,6 @@ TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { for (let job of jobs) { if (job.status === "completed") { const downloadUrl = url + "download/" + job.id; - console.log({ - token, - deviceId, - baseDirectory, - url, - downloadUrl, - }); - const tasks = await checkForExistingDownloads(); if (tasks.find((task) => task.id === job.id)) { @@ -137,7 +123,7 @@ TaskManager.defineTask(BACKGROUND_FETCH_TASK, async () => { download({ id: job.id, - url: url + "download/" + job.id, + url: downloadUrl, destination: `${baseDirectory}${job.item.Id}.mp4`, headers: { Authorization: token, diff --git a/app/login.tsx b/app/login.tsx index d312ce58..abc7dcc1 100644 --- a/app/login.tsx +++ b/app/login.tsx @@ -128,9 +128,9 @@ const Login: React.FC = () => { } catch (e) { const error = e as Error; if (error.name === "AbortError") { - console.log(`Request to ${protocol}${url} timed out`); + console.error(`Request to ${protocol}${url} timed out`); } else { - console.log(`Error checking ${protocol}${url}:`, error); + console.error(`Error checking ${protocol}${url}:`, error); } } } diff --git a/components/DownloadItem.tsx b/components/DownloadItem.tsx index 41a4ff26..e68b5dae 100644 --- a/components/DownloadItem.tsx +++ b/components/DownloadItem.tsx @@ -3,7 +3,8 @@ import { useDownload } from "@/providers/DownloadProvider"; import { apiAtom, userAtom } from "@/providers/JellyfinProvider"; import { queueActions, queueAtom } from "@/utils/atoms/queue"; import { useSettings } from "@/utils/atoms/settings"; -import ios from "@/utils/profiles/ios"; +import { getDefaultPlaySettings } from "@/utils/jellyfin/getDefaultPlaySettings"; +import iosFmp4 from "@/utils/profiles/iosFmp4"; import native from "@/utils/profiles/native"; import old from "@/utils/profiles/old"; import Ionicons from "@expo/vector-icons/Ionicons"; @@ -20,18 +21,16 @@ import { import { router, useFocusEffect } from "expo-router"; import { useAtom } from "jotai"; import { useCallback, useMemo, useRef, useState } from "react"; -import { Alert, TouchableOpacity, View, ViewProps } from "react-native"; +import { TouchableOpacity, View, ViewProps } from "react-native"; +import { toast } from "sonner-native"; import { AudioTrackSelector } from "./AudioTrackSelector"; -import { Bitrate, BITRATES, BitrateSelector } from "./BitrateSelector"; +import { Bitrate, BitrateSelector } from "./BitrateSelector"; import { Button } from "./Button"; import { Text } from "./common/Text"; import { Loader } from "./Loader"; import { MediaSourceSelector } from "./MediaSourceSelector"; import ProgressCircle from "./ProgressCircle"; import { SubtitleTrackSelector } from "./SubtitleTrackSelector"; -import { toast } from "sonner-native"; -import iosFmp4 from "@/utils/profiles/iosFmp4"; -import { getDefaultPlaySettings } from "@/utils/jellyfin/getDefaultPlaySettings"; interface DownloadProps extends ViewProps { item: BaseItemDto; @@ -46,7 +45,7 @@ export const DownloadItem: React.FC = ({ item, ...props }) => { const { startRemuxing } = useRemuxHlsToMp4(item); const [selectedMediaSource, setSelectedMediaSource] = useState< - MediaSourceInfo | undefined + MediaSourceInfo | undefined | null >(undefined); const [selectedAudioStream, setSelectedAudioStream] = useState(-1); const [selectedSubtitleStream, setSelectedSubtitleStream] = diff --git a/components/ItemContent.tsx b/components/ItemContent.tsx index eb5e82e8..a93c8e4e 100644 --- a/components/ItemContent.tsx +++ b/components/ItemContent.tsx @@ -105,7 +105,6 @@ export const ItemContent: React.FC<{ item: BaseItemDto }> = React.memo( }, [playSettings?.bitrate]); const setMaxBitrate = (bitrate: Bitrate | undefined) => { - console.log("setMaxBitrate", bitrate); setPlaySettings((prev) => ({ ...prev, bitrate, diff --git a/components/PlayButton.tsx b/components/PlayButton.tsx index c2db6636..556e4e5a 100644 --- a/components/PlayButton.tsx +++ b/components/PlayButton.tsx @@ -205,7 +205,7 @@ export const PlayButton: React.FC = ({ ...props }) => { }); break; case 1: - router.push("/play-video"); + router.push("/vlc-player"); break; case cancelButtonIndex: break; diff --git a/components/downloads/ActiveDownloads.tsx b/components/downloads/ActiveDownloads.tsx index 2f68689f..3e96f53a 100644 --- a/components/downloads/ActiveDownloads.tsx +++ b/components/downloads/ActiveDownloads.tsx @@ -85,7 +85,7 @@ const DownloadCard = ({ process, ...props }: DownloadCardProps) => { toast.success("Download canceled"); }, onError: (e) => { - console.log(e); + console.error(e); toast.error("Could not cancel download"); }, }); diff --git a/components/video-player/Controls.tsx b/components/video-player/Controls.tsx index b299d49d..72d70e96 100644 --- a/components/video-player/Controls.tsx +++ b/components/video-player/Controls.tsx @@ -14,6 +14,7 @@ import { formatTimeString, secondsToMs, ticksToMs } from "@/utils/time"; import { Ionicons } from "@expo/vector-icons"; import { BaseItemDto, + MediaSourceInfo, type MediaStream, } from "@jellyfin/sdk/lib/generated-client"; import { Image } from "expo-image"; @@ -26,6 +27,7 @@ import React, { useState, } from "react"; import { + Alert, Dimensions, Platform, Pressable, @@ -43,6 +45,8 @@ import { useSafeAreaInsets } from "react-native-safe-area-context"; import * as DropdownMenu from "zeego/dropdown-menu"; import { Text } from "../common/Text"; import { Loader } from "../Loader"; +import { useAtomValue } from "jotai"; +import { apiAtom } from "@/providers/JellyfinProvider"; interface Props { item: BaseItemDto; @@ -60,6 +64,7 @@ interface Props { setShowControls: (shown: boolean) => void; offline?: boolean; isVideoLoaded?: boolean; + mediaSource: MediaSourceInfo; } export const Controls: React.FC = ({ @@ -75,14 +80,15 @@ export const Controls: React.FC = ({ setShowControls, ignoreSafeAreas, setIgnoreSafeAreas, + mediaSource, isVideoLoaded, offline = false, }) => { const [settings] = useSettings(); const router = useRouter(); const insets = useSafeAreaInsets(); - const { setPlaySettings } = usePlaySettings(); - + const { setPlaySettings, playSettings } = usePlaySettings(); + const api = useAtomValue(apiAtom); const windowDimensions = Dimensions.get("window"); const { previousItem, nextItem } = useAdjacentItems({ item }); @@ -209,7 +215,6 @@ export const Controls: React.FC = ({ }, [showControls, isPlaying]); const handleSkipBackward = useCallback(async () => { - console.log("handleSkipBackward"); if (!settings?.rewindSkipTime) return; wasPlayingRef.current = isPlaying; try { @@ -232,7 +237,6 @@ export const Controls: React.FC = ({ const curr = progress.value; if (curr !== undefined) { const newTime = curr + secondsToMs(settings.forwardSkipTime); - console.log("handleSkipForward", newTime); await videoRef.current?.seekTo(Math.max(0, newTime)); if (wasPlayingRef.current === true) videoRef.current?.play(); } @@ -261,8 +265,6 @@ export const Controls: React.FC = ({ const subtitles = await videoRef.current.getSubtitleTracks(); setAudioTracks(audio); setSubtitleTracks(subtitles); - console.log("embedded audio", audio); - console.log("embedded sutitles", subtitles); } }; @@ -292,12 +294,12 @@ export const Controls: React.FC = ({ })) || []; const externalSubs = - item.MediaStreams?.filter( + mediaSource?.MediaStreams?.filter( (stream) => stream.Type === "Subtitle" && stream.IsExternal ).map((s) => ({ name: s.DisplayTitle!, index: s.Index!, - isExternal: s.DeliveryMethod === "External", + isExternal: true, deliveryUrl: s.DeliveryUrl, })) || []; @@ -309,13 +311,12 @@ export const Controls: React.FC = ({ (sub) => !embeddedSubNames.has(sub.name) ); - console.log([...embeddedSubs, ...uniqueExternalSubs]); // Combine embedded and unique external subs return [...embeddedSubs, ...uniqueExternalSubs] as ( | EmbeddedSubtitle | ExternalSubtitle )[]; - }, [item, isVideoLoaded, subtitleTracks]); + }, [item, isVideoLoaded, subtitleTracks, mediaSource]); return ( = ({ value="off" onValueChange={() => { if (sub.isExternal) { - videoRef.current?.setSubtitleURL(sub.deliveryUrl); - console.log( - "Setting external subtitle:", - sub.deliveryUrl + videoRef.current?.setSubtitleURL( + api?.basePath + sub.deliveryUrl ); return; } - console.log("Settings embedded subtitle", sub.name); videoRef.current?.setSubtitleTrack(sub.index); - console.log(sub); }} > diff --git a/hooks/useAdjacentEpisodes.ts b/hooks/useAdjacentEpisodes.ts index 26fa777f..b05ea591 100644 --- a/hooks/useAdjacentEpisodes.ts +++ b/hooks/useAdjacentEpisodes.ts @@ -28,8 +28,6 @@ export const useAdjacentItems = ({ item }: AdjacentEpisodesProps) => { return null; } - console.log("Getting previous item for " + indexNumber); - const newIndexNumber = indexNumber - 2; const res = await getItemsApi(api).getItems({ diff --git a/hooks/useCreditSkipper.ts b/hooks/useCreditSkipper.ts index e7d71ba6..ba574a78 100644 --- a/hooks/useCreditSkipper.ts +++ b/hooks/useCreditSkipper.ts @@ -30,7 +30,6 @@ export const useCreditSkipper = ( queryKey: ["creditTimestamps", itemId], queryFn: async () => { if (!itemId) { - console.log("No item id"); return null; } @@ -61,7 +60,6 @@ export const useCreditSkipper = ( }, [creditTimestamps, currentTime]); const skipCredit = useCallback(() => { - console.log("skipCredits"); if (!creditTimestamps || !videoRef.current) return; try { videoRef.current.seek(creditTimestamps.Credits.End); diff --git a/hooks/useDownloadedFileOpener.ts b/hooks/useDownloadedFileOpener.ts index 29aa7c56..8a1e4d1c 100644 --- a/hooks/useDownloadedFileOpener.ts +++ b/hooks/useDownloadedFileOpener.ts @@ -24,9 +24,6 @@ export const useFileOpener = () => { try { const files = await FileSystem.readDirectoryAsync(directory); - for (let f of files) { - console.log(f); - } const path = item.Id!; const matchingFile = files.find((file) => file.startsWith(path)); diff --git a/hooks/useImageStorage.ts b/hooks/useImageStorage.ts index ad271f07..56b44ba0 100644 --- a/hooks/useImageStorage.ts +++ b/hooks/useImageStorage.ts @@ -8,7 +8,6 @@ const useImageStorage = () => { try { // Save the base64 string to AsyncStorage storage.set(key, base64); - console.log("Image saved successfully"); } catch (error) { console.error("Error saving image:", error); throw error; diff --git a/hooks/useIntroSkipper.ts b/hooks/useIntroSkipper.ts index 43d1699a..fa1f154b 100644 --- a/hooks/useIntroSkipper.ts +++ b/hooks/useIntroSkipper.ts @@ -26,7 +26,6 @@ export const useIntroSkipper = ( queryKey: ["introTimestamps", itemId], queryFn: async () => { if (!itemId) { - console.log("No item id"); return null; } diff --git a/hooks/useRemuxHlsToMp4.ts b/hooks/useRemuxHlsToMp4.ts index 785e4f08..db7c0a88 100644 --- a/hooks/useRemuxHlsToMp4.ts +++ b/hooks/useRemuxHlsToMp4.ts @@ -26,8 +26,7 @@ export const useRemuxHlsToMp4 = (item: BaseItemDto) => { const queryClient = useQueryClient(); const { saveDownloadedItemInfo, setProcesses } = useDownload(); const router = useRouter(); - const { loadImage, saveImage, image2Base64, saveBase64Image } = - useImageStorage(); + const { saveImage } = useImageStorage(); if (!item.Id || !item.Name) { writeToLog("ERROR", "useRemuxHlsToMp4 ~ missing arguments"); diff --git a/providers/DownloadProvider.tsx b/providers/DownloadProvider.tsx index 5e6ca8e9..b1286c81 100644 --- a/providers/DownloadProvider.tsx +++ b/providers/DownloadProvider.tsx @@ -174,7 +174,7 @@ function useDownloadProvider() { url: settings?.optimizedVersionsServerUrl, }); } catch (error) { - console.log(error); + console.error(error); } }, [settings?.optimizedVersionsServerUrl, authHeader] @@ -184,7 +184,6 @@ function useDownloadProvider() { async (process: JobStatus) => { if (!process?.item.Id || !authHeader) throw new Error("No item id"); - console.log("[0] Setting process to downloading"); setProcesses((prev) => prev.map((p) => p.id === process.id @@ -239,7 +238,6 @@ function useDownloadProvider() { }) .progress((data) => { const percent = (data.bytesDownloaded / data.bytesTotal) * 100; - console.log("Download progress:", percent); setProcesses((prev) => prev.map((p) => p.id === process.id @@ -467,7 +465,6 @@ function useDownloadProvider() { if (itemNameWithoutExtension === id) { const filePath = `${directory}${item}`; await FileSystem.deleteAsync(filePath, { idempotent: true }); - console.log(`Successfully deleted file: ${item}`); break; } } @@ -480,10 +477,6 @@ function useDownloadProvider() { } queryClient.invalidateQueries({ queryKey: ["downloadedItems"] }); - - console.log( - `Successfully deleted file and AsyncStorage entry for ID ${id}` - ); } catch (error) { console.error( `Failed to delete file and AsyncStorage entry for ID ${id}:`, diff --git a/providers/PlaySettingsProvider.tsx b/providers/PlaySettingsProvider.tsx index 7e07fcdb..f3ceecdd 100644 --- a/providers/PlaySettingsProvider.tsx +++ b/providers/PlaySettingsProvider.tsx @@ -7,6 +7,7 @@ import old from "@/utils/profiles/old"; import { BaseItemDto, MediaSourceInfo, + PlaybackInfoResponse, } from "@jellyfin/sdk/lib/generated-client"; import { getSessionApi } from "@jellyfin/sdk/lib/utils/api"; import { useAtomValue } from "jotai"; @@ -30,6 +31,7 @@ export type PlaybackType = { type PlaySettingsContextType = { playSettings: PlaybackType | null; + mediaSource: MediaSourceInfo | null; setPlaySettings: ( dataOrUpdater: | PlaybackType @@ -51,6 +53,7 @@ export const PlaySettingsProvider: React.FC<{ children: React.ReactNode }> = ({ children, }) => { const [playSettings, _setPlaySettings] = useState(null); + const [mediaSource, setMediaSource] = useState(null); const [playUrl, setPlayUrl] = useState(null); const [playSessionId, setPlaySessionId] = useState(null); @@ -109,11 +112,10 @@ export const PlaySettingsProvider: React.FC<{ children: React.ReactNode }> = ({ forceDirectPlay: settings.forceDirectPlay, }); - console.log("getStreamUrl ~ ", data?.url); - _setPlaySettings(newSettings); setPlayUrl(data?.url!); setPlaySessionId(data?.sessionId!); + setMediaSource(data?.mediaSource!); return data; } catch (error) { @@ -158,6 +160,7 @@ export const PlaySettingsProvider: React.FC<{ children: React.ReactNode }> = ({ setMusicPlaySettings, setOfflineSettings, playSessionId, + mediaSource, }} > {children} diff --git a/utils/jellyfin/media/getPlaybackInfo.ts b/utils/jellyfin/media/getPlaybackInfo.ts deleted file mode 100644 index 5d85376e..00000000 --- a/utils/jellyfin/media/getPlaybackInfo.ts +++ /dev/null @@ -1,19 +0,0 @@ -import { Api } from "@jellyfin/sdk"; -import { getMediaInfoApi } from "@jellyfin/sdk/lib/utils/api"; - -export const getPlaybackInfo = async ( - api?: Api | null | undefined, - itemId?: string | null | undefined, - userId?: string | null | undefined, -) => { - if (!api || !itemId || !userId) { - return null; - } - - const a = await getMediaInfoApi(api).getPlaybackInfo({ - itemId, - userId, - }); - - return a.data; -}; diff --git a/utils/jellyfin/media/getStreamUrl.ts b/utils/jellyfin/media/getStreamUrl.ts index a8a0e414..8096d827 100644 --- a/utils/jellyfin/media/getStreamUrl.ts +++ b/utils/jellyfin/media/getStreamUrl.ts @@ -37,6 +37,7 @@ export const getStreamUrl = async ({ }): Promise<{ url: string | null; sessionId: string | null; + mediaSource: MediaSourceInfo | undefined; } | null> => { if (!api || !userId || !item?.Id) { return null; @@ -70,7 +71,11 @@ export const getStreamUrl = async ({ sessionId = res0.data.PlaySessionId || null; if (transcodeUrl) { - return { url: `${api.basePath}${transcodeUrl}`, sessionId }; + return { + url: `${api.basePath}${transcodeUrl}`, + sessionId, + mediaSource: res0.data.MediaSources?.[0], + }; } } @@ -108,13 +113,12 @@ export const getStreamUrl = async ({ (source: MediaSourceInfo) => source.Id === mediaSourceId ); - console.log("getStreamUrl ~ ", item.MediaType); - if (item.MediaType === "Video") { if (mediaSource?.SupportsDirectPlay || forceDirectPlay === true) { return { url: `${api.basePath}/Videos/${itemId}/stream.mp4?playSessionId=${sessionData?.PlaySessionId}&mediaSourceId=${mediaSource?.Id}&static=true&subtitleStreamIndex=${subtitleStreamIndex}&audioStreamIndex=${audioStreamIndex}&deviceId=${api.deviceInfo.id}&api_key=${api.accessToken}`, sessionId: sessionId, + mediaSource, }; } @@ -122,15 +126,18 @@ export const getStreamUrl = async ({ return { url: `${api.basePath}${mediaSource.TranscodingUrl}`, sessionId: sessionId, + mediaSource, }; } } if (item.MediaType === "Audio") { - console.log("getStreamUrl ~ Audio"); - if (mediaSource?.TranscodingUrl) { - return { url: `${api.basePath}${mediaSource.TranscodingUrl}`, sessionId }; + return { + url: `${api.basePath}${mediaSource.TranscodingUrl}`, + sessionId, + mediaSource, + }; } const searchParams = new URLSearchParams({ @@ -153,6 +160,7 @@ export const getStreamUrl = async ({ api.basePath }/Audio/${itemId}/universal?${searchParams.toString()}`, sessionId, + mediaSource, }; } diff --git a/utils/profiles/native.js b/utils/profiles/native.js index 3aa7d8b8..41bf0f29 100644 --- a/utils/profiles/native.js +++ b/utils/profiles/native.js @@ -259,11 +259,11 @@ export default { ], SubtitleProfiles: [ { - Format: "pgssub", - Method: "embed", + Format: "srt", + Method: "external", }, { - Format: "subrip", + Format: "pgssub", Method: "embed", }, {