add imdbId to scrape media

This commit is contained in:
Jorrin
2024-02-05 20:51:46 +01:00
parent a6a3f8042f
commit eeb0b921dc
4 changed files with 83 additions and 46 deletions

View File

@@ -0,0 +1,41 @@
import type { VideoRef } from "react-native-video";
import { useCallback, useRef } from "react";
import * as ScreenOrientation from "expo-screen-orientation";
export const usePlayer = () => {
const ref = useRef<VideoRef>(null);
const lockOrientation = useCallback(async () => {
await ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.LANDSCAPE,
);
}, []);
const unlockOrientation = useCallback(async () => {
await ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.PORTRAIT_UP,
);
}, []);
const presentFullscreenPlayer = useCallback(async () => {
if (ref.current) {
ref.current.presentFullscreenPlayer();
await lockOrientation();
}
}, [lockOrientation]);
const dismissFullscreenPlayer = useCallback(async () => {
if (ref.current) {
ref.current.dismissFullscreenPlayer();
await unlockOrientation();
}
}, [unlockOrientation]);
return {
videoRef: ref,
lockOrientation,
unlockOrientation,
presentFullscreenPlayer,
dismissFullscreenPlayer,
} as const;
};

View File

@@ -1,5 +1,5 @@
import type { VideoRef } from "react-native-video"; import type { ReactVideoSource } from "react-native-video";
import React, { useEffect, useRef, useState } from "react"; import React, { useEffect, useState } from "react";
import { ActivityIndicator, StyleSheet } from "react-native"; import { ActivityIndicator, StyleSheet } from "react-native";
import { SafeAreaView } from "react-native-safe-area-context"; import { SafeAreaView } from "react-native-safe-area-context";
import Video from "react-native-video"; import Video from "react-native-video";
@@ -14,6 +14,7 @@ import {
import { fetchMediaDetails } from "@movie-web/tmdb"; import { fetchMediaDetails } from "@movie-web/tmdb";
import type { ItemData } from "./components/item/item"; import type { ItemData } from "./components/item/item";
import { usePlayer } from "./hooks/usePlayer";
export default function VideoPlayerWrapper() { export default function VideoPlayerWrapper() {
const params = useLocalSearchParams(); const params = useLocalSearchParams();
@@ -28,11 +29,15 @@ interface VideoPlayerProps {
} }
const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => { const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
const [videoUrl, setVideoUrl] = useState(""); const [videoSrc, setVideoSrc] = useState<ReactVideoSource>();
const [headers, setHeaders] = useState({} as Record<string, string>);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const videoPlayer = useRef<VideoRef>(null);
const router = useRouter(); const router = useRouter();
const {
videoRef,
unlockOrientation,
presentFullscreenPlayer,
dismissFullscreenPlayer,
} = usePlayer();
useEffect(() => { useEffect(() => {
const initializePlayer = async () => { const initializePlayer = async () => {
@@ -84,13 +89,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
url = stream.playlist; url = stream.playlist;
} }
const combinedHeaders = { setVideoSrc({
...stream.headers, uri: url,
...stream.preferredHeaders, headers: {
}; ...stream.preferredHeaders,
...stream.headers,
setHeaders(combinedHeaders); },
setVideoUrl(url); });
setIsLoading(false); setIsLoading(false);
} else { } else {
await ScreenOrientation.lockAsync( await ScreenOrientation.lockAsync(
@@ -100,40 +105,21 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
} }
}; };
const lockOrientation = async () => {
await ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.LANDSCAPE,
);
};
const unlockOrientation = async () => {
await ScreenOrientation.lockAsync(
ScreenOrientation.OrientationLock.PORTRAIT_UP,
);
};
const presentFullscreenPlayer = async () => {
if (videoPlayer.current) {
videoPlayer.current.presentFullscreenPlayer();
await lockOrientation();
}
};
const dismissFullscreenPlayer = async () => {
if (videoPlayer.current) {
videoPlayer.current.dismissFullscreenPlayer();
await unlockOrientation();
}
};
setIsLoading(true); setIsLoading(true);
void presentFullscreenPlayer(); void presentFullscreenPlayer();
void initializePlayer(); void initializePlayer();
return () => { return () => {
void dismissFullscreenPlayer(); void dismissFullscreenPlayer();
void unlockOrientation();
}; };
}, [data, router]); }, [
data,
dismissFullscreenPlayer,
presentFullscreenPlayer,
router,
unlockOrientation,
]);
const onVideoLoadStart = () => { const onVideoLoadStart = () => {
setIsLoading(true); setIsLoading(true);
@@ -146,8 +132,8 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
return ( return (
<SafeAreaView style={styles.container}> <SafeAreaView style={styles.container}>
<Video <Video
ref={videoPlayer} ref={videoRef}
source={{ uri: videoUrl, headers }} source={videoSrc}
style={styles.fullScreen} style={styles.fullScreen}
fullscreen={true} fullscreen={true}
paused={false} paused={false}

View File

@@ -1,4 +1,4 @@
import type { MovieDetails, TvShowDetails } from "tmdb-ts"; import type { AppendToResponse, MovieDetails, TvShowDetails } from "tmdb-ts";
import type { ScrapeMedia } from "@movie-web/providers"; import type { ScrapeMedia } from "@movie-web/providers";
@@ -9,10 +9,15 @@ export function transformSearchResultToScrapeMedia(
episode?: number, episode?: number,
): ScrapeMedia { ): ScrapeMedia {
if (type === "tv") { if (type === "tv") {
const tvResult = result as TvShowDetails; const tvResult = result as AppendToResponse<
TvShowDetails,
"external_ids"[],
"tvShow"
>;
return { return {
type: "show", type: "show",
tmdbId: tvResult.id.toString(), tmdbId: tvResult.id.toString(),
imdbId: tvResult.external_ids.imdb_id,
title: tvResult.name, title: tvResult.name,
releaseYear: new Date(tvResult.first_air_date).getFullYear(), releaseYear: new Date(tvResult.first_air_date).getFullYear(),
season: { season: {
@@ -30,10 +35,15 @@ export function transformSearchResultToScrapeMedia(
}; };
} }
if (type === "movie") { if (type === "movie") {
const movieResult = result as MovieDetails; const movieResult = result as AppendToResponse<
MovieDetails,
"external_ids"[],
"movie"
>;
return { return {
type: "movie", type: "movie",
tmdbId: movieResult.id.toString(), tmdbId: movieResult.id.toString(),
imdbId: movieResult.external_ids.imdb_id,
title: movieResult.title, title: movieResult.title,
releaseYear: new Date(movieResult.release_date).getFullYear(), releaseYear: new Date(movieResult.release_date).getFullYear(),
}; };

View File

@@ -11,8 +11,8 @@ export async function fetchMediaDetails(
try { try {
const result = const result =
type === "movie" type === "movie"
? await tmdb.movies.details(parseInt(id, 10)) ? await tmdb.movies.details(parseInt(id, 10), ["external_ids"])
: await tmdb.tvShows.details(parseInt(id, 10)); : await tmdb.tvShows.details(parseInt(id, 10), ["external_ids"]);
return { return {
type, type,