diff --git a/components/settings/SettingToggles.tsx b/components/settings/SettingToggles.tsx
index 67ba5b60..05508818 100644
--- a/components/settings/SettingToggles.tsx
+++ b/components/settings/SettingToggles.tsx
@@ -159,6 +159,23 @@ export const SettingToggles: React.FC = () => {
onValueChange={(value) => updateSettings({ forceDirectPlay: value })}
/>
+
+
+
+ Use external player (VLC)
+
+ Open all videos in VLC instead of the default player. This requries
+ VLC to be installed on the phone.
+
+
+ {
+ updateSettings({ openInVLC: value, forceDirectPlay: value });
+ }}
+ />
+
+
{
diff --git a/providers/PlaybackProvider.tsx b/providers/PlaybackProvider.tsx
index b5171b1b..935c1480 100644
--- a/providers/PlaybackProvider.tsx
+++ b/providers/PlaybackProvider.tsx
@@ -21,6 +21,8 @@ import { useAtom } from "jotai";
import { OnProgressData, type VideoRef } from "react-native-video";
import { apiAtom, userAtom } from "./JellyfinProvider";
import { getDeviceId } from "@/utils/device";
+import * as Linking from "expo-linking";
+import { Platform } from "react-native";
type CurrentlyPlayingState = {
url: string;
@@ -87,19 +89,29 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
queryFn: getDeviceId,
});
- const setCurrentlyPlayingState = (state: CurrentlyPlayingState | null) => {
- if (state) {
- setCurrentlyPlaying(state);
- setIsPlaying(true);
+ const setCurrentlyPlayingState = useCallback(
+ (state: CurrentlyPlayingState | null) => {
+ const vlcLink = "vlc://" + state?.url;
+ console.log(vlcLink, settings?.openInVLC, Platform.OS === "ios");
+ if (vlcLink && settings?.openInVLC) {
+ Linking.openURL("vlc://" + state?.url || "");
+ return;
+ }
- if (settings?.openFullScreenVideoPlayerByDefault)
- presentFullscreenPlayer();
- } else {
- setCurrentlyPlaying(null);
- setIsFullscreen(false);
- setIsPlaying(false);
- }
- };
+ if (state) {
+ setCurrentlyPlaying(state);
+ setIsPlaying(true);
+
+ if (settings?.openFullScreenVideoPlayerByDefault)
+ presentFullscreenPlayer();
+ } else {
+ setCurrentlyPlaying(null);
+ setIsFullscreen(false);
+ setIsPlaying(false);
+ }
+ },
+ [settings]
+ );
// Define control methods
const playVideo = useCallback(() => {
@@ -167,7 +179,7 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
}, []);
useEffect(() => {
- if (!deviceId || !api) return;
+ if (!deviceId || !api || !user) return;
const url = `wss://${api?.basePath
.replace("https://", "")
@@ -212,7 +224,7 @@ export const PlaybackProvider: React.FC<{ children: ReactNode }> = ({
}
newWebSocket.close();
};
- }, [api, deviceId]);
+ }, [api, deviceId, user]);
useEffect(() => {
if (!ws) return;
diff --git a/utils/atoms/settings.ts b/utils/atoms/settings.ts
index e216b517..a56cd903 100644
--- a/utils/atoms/settings.ts
+++ b/utils/atoms/settings.ts
@@ -12,6 +12,7 @@ type Settings = {
mediaListCollectionIds?: string[];
searchEngine: "Marlin" | "Jellyfin";
marlinServerUrl?: string;
+ openInVLC?: boolean;
};
/**
@@ -37,6 +38,7 @@ const loadSettings = async (): Promise => {
mediaListCollectionIds: [],
searchEngine: "Jellyfin",
marlinServerUrl: "",
+ openInVLC: false,
};
};