mirror of
https://github.com/movie-web/native-app.git
synced 2025-09-13 18:13: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 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,
|
||||||
|
headers: {
|
||||||
...stream.preferredHeaders,
|
...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}
|
||||||
|
@@ -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(),
|
||||||
};
|
};
|
||||||
|
@@ -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,
|
||||||
|
Reference in New Issue
Block a user