This commit is contained in:
Alex Kim
2025-12-07 02:22:09 +11:00
parent 7135be198a
commit 074222050a
5 changed files with 48 additions and 27 deletions

View File

@@ -1,7 +1,33 @@
import { Stack } from "expo-router"; import { Stack } from "expo-router";
import { useEffect } from "react";
import { AppState } from "react-native";
import { SystemBars } from "react-native-edge-to-edge"; import { SystemBars } from "react-native-edge-to-edge";
import { useOrientation } from "@/hooks/useOrientation";
import { useSettings } from "@/utils/atoms/settings";
export default function Layout() { export default function Layout() {
const { settings } = useSettings();
const { lockOrientation, unlockOrientation } = useOrientation();
useEffect(() => {
if (settings?.defaultVideoOrientation) {
lockOrientation(settings.defaultVideoOrientation);
}
// Re-apply orientation lock when app returns to foreground (iOS resets it)
const subscription = AppState.addEventListener("change", (nextAppState) => {
if (nextAppState === "active" && settings?.defaultVideoOrientation) {
lockOrientation(settings.defaultVideoOrientation);
}
});
return () => {
subscription.remove();
unlockOrientation();
};
}, [settings?.defaultVideoOrientation, lockOrientation, unlockOrientation]);
return ( return (
<> <>
<SystemBars hidden /> <SystemBars hidden />

View File

@@ -25,7 +25,6 @@ import { Controls } from "@/components/video-player/controls/Controls";
import { PlayerProvider } from "@/components/video-player/controls/contexts/PlayerContext"; import { PlayerProvider } from "@/components/video-player/controls/contexts/PlayerContext";
import { VideoProvider } from "@/components/video-player/controls/contexts/VideoContext"; import { VideoProvider } from "@/components/video-player/controls/contexts/VideoContext";
import { useHaptic } from "@/hooks/useHaptic"; import { useHaptic } from "@/hooks/useHaptic";
import { useOrientation } from "@/hooks/useOrientation";
import { usePlaybackManager } from "@/hooks/usePlaybackManager"; import { usePlaybackManager } from "@/hooks/usePlaybackManager";
import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache"; import { useInvalidatePlaybackProgressCache } from "@/hooks/useRevalidatePlaybackProgressCache";
import { useWebSocket } from "@/hooks/useWebsockets"; import { useWebSocket } from "@/hooks/useWebsockets";
@@ -112,7 +111,6 @@ export default function page() {
playbackPosition?: string; playbackPosition?: string;
}>(); }>();
const { settings } = useSettings(); const { settings } = useSettings();
const { lockOrientation, unlockOrientation } = useOrientation();
const offline = offlineStr === "true"; const offline = offlineStr === "true";
const playbackManager = usePlaybackManager(); const playbackManager = usePlaybackManager();
@@ -175,16 +173,6 @@ export default function page() {
} }
}, [itemId, offline, api, user?.Id]); }, [itemId, offline, api, user?.Id]);
useEffect(() => {
if (settings?.defaultVideoOrientation) {
lockOrientation(settings.defaultVideoOrientation);
}
return () => {
unlockOrientation();
};
}, [settings?.defaultVideoOrientation]);
interface Stream { interface Stream {
mediaSource: MediaSourceInfo; mediaSource: MediaSourceInfo;
sessionId: string; sessionId: string;
@@ -338,7 +326,7 @@ export default function page() {
const currentPlayStateInfo = useCallback(() => { const currentPlayStateInfo = useCallback(() => {
if (!stream || !item?.Id) return; if (!stream || !item?.Id) return;
console.log("subtitle");
return { return {
itemId: item.Id, itemId: item.Id,
audioStreamIndex: audioIndex ? audioIndex : undefined, audioStreamIndex: audioIndex ? audioIndex : undefined,

View File

@@ -1,5 +1,5 @@
import type { OrientationChangeEvent } from "expo-screen-orientation"; import type { OrientationChangeEvent } from "expo-screen-orientation";
import { useEffect, useState } from "react"; import { useCallback, useEffect, useState } from "react";
import { Platform } from "react-native"; import { Platform } from "react-native";
import { import {
addOrientationChangeListener, addOrientationChangeListener,
@@ -53,27 +53,28 @@ export const useOrientation = () => {
}; };
}, []); }, []);
const lockOrientation = async ( const lockOrientation = useCallback(
lock: (typeof OrientationLock)[keyof typeof OrientationLock], async (lock: (typeof OrientationLock)[keyof typeof OrientationLock]) => {
) => { if (Platform.isTV) return;
if (Platform.isTV) return;
if (lock === OrientationLock.DEFAULT) { if (lock === OrientationLock.DEFAULT) {
await unlockAsync(); await unlockAsync();
} else { } else {
await lockAsync(lock); await lockAsync(lock);
} }
}; },
[],
);
const unlockOrientationFn = async () => { const unlockOrientation = useCallback(async () => {
if (Platform.isTV) return; if (Platform.isTV) return;
await unlockAsync(); await unlockAsync();
}; }, []);
return { return {
orientation, orientation,
setOrientation, setOrientation,
lockOrientation, lockOrientation,
unlockOrientation: unlockOrientationFn, unlockOrientation,
}; };
}; };

View File

@@ -558,6 +558,8 @@ final class MPVSoftwareRenderer {
} }
private func createPixelBufferPool(width: Int, height: Int) { private func createPixelBufferPool(width: Int, height: Int) {
guard width > 0, height > 0 else { return }
let pixelFormat = kCVPixelFormatType_32BGRA let pixelFormat = kCVPixelFormatType_32BGRA
let attrs: [CFString: Any] = [ let attrs: [CFString: Any] = [

View File

@@ -107,6 +107,10 @@ class MpvPlayerView: ExpoView {
} }
func loadVideo(config: VideoLoadConfig) { func loadVideo(config: VideoLoadConfig) {
// Skip reload if same URL is already playing
if currentURL == config.url {
return
}
currentURL = config.url currentURL = config.url
let preset = PlayerPreset( let preset = PlayerPreset(