feat: autoplay

This commit is contained in:
Adrian Castro
2024-03-25 20:20:07 +01:00
parent 37e61d1296
commit 0aa9c9d8f7
5 changed files with 134 additions and 43 deletions

View File

@@ -4,7 +4,11 @@ import { ScrollView } from "react-native-gesture-handler";
import { useRouter } from "expo-router";
import { View } from "tamagui";
import type { HlsBasedStream } from "@movie-web/provider-utils";
import type {
HlsBasedStream,
RunOutput,
ScrapeMedia,
} from "@movie-web/provider-utils";
import {
extractTracksFromHLS,
findHighestQuality,
@@ -12,21 +16,27 @@ import {
import type { ItemData } from "../item/item";
import type { AudioTrack } from "./AudioTrackSelector";
import type { PlayerMeta } from "~/stores/player/slices/video";
import { useDownloadManager } from "~/hooks/DownloadManagerContext";
import { useMeta } from "~/hooks/player/useMeta";
import { useScrape } from "~/hooks/player/useSourceScrape";
import { convertMetaToScrapeMedia } from "~/lib/meta";
import { constructFullUrl } from "~/lib/url";
import { PlayerStatus } from "~/stores/player/slices/interface";
import { convertMetaToScrapeMedia } from "~/stores/player/slices/video";
import { usePlayerStore } from "~/stores/player/store";
import { ScrapeCard, ScrapeItem } from "./ScrapeCard";
interface ScraperProcessProps {
data: ItemData;
data?: ItemData;
media?: ScrapeMedia;
download?: boolean;
}
export const ScraperProcess = ({ data, download }: ScraperProcessProps) => {
export const ScraperProcess = ({
data,
media,
download,
}: ScraperProcessProps) => {
const router = useRouter();
const { startDownload } = useDownloadManager();
@@ -43,10 +53,19 @@ export const ScraperProcess = ({ data, download }: ScraperProcessProps) => {
useEffect(() => {
const fetchData = async () => {
if (!data) return router.back();
const meta = await convertMovieIdToMeta(data.id, data.type);
if (!meta) return;
const streamResult = await startScraping(convertMetaToScrapeMedia(meta));
if (!data && !media) return router.back();
let streamResult: RunOutput | null = null;
let meta: PlayerMeta | undefined = undefined;
if (!media && data) {
meta = await convertMovieIdToMeta(data.id, data.type);
if (!meta) return router.back();
}
const scrapeMedia = media ?? (meta && convertMetaToScrapeMedia(meta));
if (!scrapeMedia) return router.back();
streamResult = await startScraping(scrapeMedia);
if (!streamResult) return router.back();
if (download) {
@@ -76,7 +95,7 @@ export const ScraperProcess = ({ data, download }: ScraperProcessProps) => {
if (tracks?.audio.length) {
const audioTracks: AudioTrack[] = tracks.audio.map((track) => ({
uri: constructFullUrl(
(streamResult.stream as HlsBasedStream).playlist,
(streamResult?.stream as HlsBasedStream).playlist,
track.uri,
),
name: track.properties[0]?.attributes.name?.toString() ?? "Unknown",
@@ -106,6 +125,7 @@ export const ScraperProcess = ({ data, download }: ScraperProcessProps) => {
convertMovieIdToMeta,
data,
download,
media,
router,
setAudioTracks,
setHlsTracks,

View File

@@ -1,3 +1,4 @@
import type { AVPlaybackStatus } from "expo-av";
import type { SharedValue } from "react-native-reanimated";
import { useEffect, useState } from "react";
import { Dimensions, Platform } from "react-native";
@@ -23,6 +24,7 @@ import { useBrightness } from "~/hooks/player/useBrightness";
import { usePlaybackSpeed } from "~/hooks/player/usePlaybackSpeed";
import { usePlayer } from "~/hooks/player/usePlayer";
import { useVolume } from "~/hooks/player/useVolume";
import { convertMetaToScrapeMedia, getNextEpisode } from "~/lib/meta";
import { useAudioTrackStore } from "~/stores/audio";
import { usePlayerStore } from "~/stores/player/store";
import { usePlayerSettingsStore } from "~/stores/settings";
@@ -61,8 +63,10 @@ export const VideoPlayer = () => {
const setIsIdle = usePlayerStore((state) => state.setIsIdle);
const toggleAudio = usePlayerStore((state) => state.toggleAudio);
const toggleState = usePlayerStore((state) => state.toggleState);
const meta = usePlayerStore((state) => state.meta);
const setMeta = usePlayerStore((state) => state.setMeta);
const { gestureControls } = usePlayerSettingsStore();
const { gestureControls, autoPlay } = usePlayerSettingsStore();
const updateResizeMode = (newMode: ResizeMode) => {
setResizeMode(newMode);
@@ -212,6 +216,27 @@ export const VideoPlayer = () => {
}
};
const onPlaybackStatusUpdate = async (status: AVPlaybackStatus) => {
setStatus(status);
if (
status.isLoaded &&
status.didJustFinish &&
!status.isLooping &&
autoPlay
) {
if (meta?.type !== "show") return;
const nextEpisodeMeta = await getNextEpisode(meta);
if (!nextEpisodeMeta) return;
setMeta(nextEpisodeMeta);
const media = convertMetaToScrapeMedia(nextEpisodeMeta);
router.replace({
pathname: "/videoPlayer",
params: { media: JSON.stringify(media) },
});
}
};
return (
<GestureDetector gesture={composedGesture}>
<View
@@ -230,7 +255,7 @@ export const VideoPlayer = () => {
rate={currentSpeed}
onLoadStart={onVideoLoadStart}
onReadyForDisplay={onReadyForDisplay}
onPlaybackStatusUpdate={setStatus}
onPlaybackStatusUpdate={onPlaybackStatusUpdate}
style={[
{
position: "absolute",