mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 14:43:25 +00:00
add imdbId to scrape media
This commit is contained in:
41
apps/expo/src/app/hooks/usePlayer.ts
Normal file
41
apps/expo/src/app/hooks/usePlayer.ts
Normal 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;
|
||||
};
|
@@ -1,5 +1,5 @@
|
||||
import type { VideoRef } from "react-native-video";
|
||||
import React, { useEffect, useRef, useState } from "react";
|
||||
import type { ReactVideoSource } from "react-native-video";
|
||||
import React, { useEffect, useState } from "react";
|
||||
import { ActivityIndicator, StyleSheet } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import Video from "react-native-video";
|
||||
@@ -14,6 +14,7 @@ import {
|
||||
import { fetchMediaDetails } from "@movie-web/tmdb";
|
||||
|
||||
import type { ItemData } from "./components/item/item";
|
||||
import { usePlayer } from "./hooks/usePlayer";
|
||||
|
||||
export default function VideoPlayerWrapper() {
|
||||
const params = useLocalSearchParams();
|
||||
@@ -28,11 +29,15 @@ interface VideoPlayerProps {
|
||||
}
|
||||
|
||||
const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
|
||||
const [videoUrl, setVideoUrl] = useState("");
|
||||
const [headers, setHeaders] = useState({} as Record<string, string>);
|
||||
const [videoSrc, setVideoSrc] = useState<ReactVideoSource>();
|
||||
const [isLoading, setIsLoading] = useState(true);
|
||||
const videoPlayer = useRef<VideoRef>(null);
|
||||
const router = useRouter();
|
||||
const {
|
||||
videoRef,
|
||||
unlockOrientation,
|
||||
presentFullscreenPlayer,
|
||||
dismissFullscreenPlayer,
|
||||
} = usePlayer();
|
||||
|
||||
useEffect(() => {
|
||||
const initializePlayer = async () => {
|
||||
@@ -84,13 +89,13 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
|
||||
url = stream.playlist;
|
||||
}
|
||||
|
||||
const combinedHeaders = {
|
||||
...stream.headers,
|
||||
...stream.preferredHeaders,
|
||||
};
|
||||
|
||||
setHeaders(combinedHeaders);
|
||||
setVideoUrl(url);
|
||||
setVideoSrc({
|
||||
uri: url,
|
||||
headers: {
|
||||
...stream.preferredHeaders,
|
||||
...stream.headers,
|
||||
},
|
||||
});
|
||||
setIsLoading(false);
|
||||
} else {
|
||||
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);
|
||||
void presentFullscreenPlayer();
|
||||
void initializePlayer();
|
||||
|
||||
return () => {
|
||||
void dismissFullscreenPlayer();
|
||||
void unlockOrientation();
|
||||
};
|
||||
}, [data, router]);
|
||||
}, [
|
||||
data,
|
||||
dismissFullscreenPlayer,
|
||||
presentFullscreenPlayer,
|
||||
router,
|
||||
unlockOrientation,
|
||||
]);
|
||||
|
||||
const onVideoLoadStart = () => {
|
||||
setIsLoading(true);
|
||||
@@ -146,8 +132,8 @@ const VideoPlayer: React.FC<VideoPlayerProps> = ({ data }) => {
|
||||
return (
|
||||
<SafeAreaView style={styles.container}>
|
||||
<Video
|
||||
ref={videoPlayer}
|
||||
source={{ uri: videoUrl, headers }}
|
||||
ref={videoRef}
|
||||
source={videoSrc}
|
||||
style={styles.fullScreen}
|
||||
fullscreen={true}
|
||||
paused={false}
|
||||
|
@@ -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";
|
||||
|
||||
@@ -9,10 +9,15 @@ export function transformSearchResultToScrapeMedia(
|
||||
episode?: number,
|
||||
): ScrapeMedia {
|
||||
if (type === "tv") {
|
||||
const tvResult = result as TvShowDetails;
|
||||
const tvResult = result as AppendToResponse<
|
||||
TvShowDetails,
|
||||
"external_ids"[],
|
||||
"tvShow"
|
||||
>;
|
||||
return {
|
||||
type: "show",
|
||||
tmdbId: tvResult.id.toString(),
|
||||
imdbId: tvResult.external_ids.imdb_id,
|
||||
title: tvResult.name,
|
||||
releaseYear: new Date(tvResult.first_air_date).getFullYear(),
|
||||
season: {
|
||||
@@ -30,10 +35,15 @@ export function transformSearchResultToScrapeMedia(
|
||||
};
|
||||
}
|
||||
if (type === "movie") {
|
||||
const movieResult = result as MovieDetails;
|
||||
const movieResult = result as AppendToResponse<
|
||||
MovieDetails,
|
||||
"external_ids"[],
|
||||
"movie"
|
||||
>;
|
||||
return {
|
||||
type: "movie",
|
||||
tmdbId: movieResult.id.toString(),
|
||||
imdbId: movieResult.external_ids.imdb_id,
|
||||
title: movieResult.title,
|
||||
releaseYear: new Date(movieResult.release_date).getFullYear(),
|
||||
};
|
||||
|
@@ -11,8 +11,8 @@ export async function fetchMediaDetails(
|
||||
try {
|
||||
const result =
|
||||
type === "movie"
|
||||
? await tmdb.movies.details(parseInt(id, 10))
|
||||
: await tmdb.tvShows.details(parseInt(id, 10));
|
||||
? await tmdb.movies.details(parseInt(id, 10), ["external_ids"])
|
||||
: await tmdb.tvShows.details(parseInt(id, 10), ["external_ids"]);
|
||||
|
||||
return {
|
||||
type,
|
||||
|
Reference in New Issue
Block a user