diff --git a/apps/expo/src/app/videoPlayer.tsx b/apps/expo/src/app/videoPlayer.tsx index e79eeca..8d3a4e0 100644 --- a/apps/expo/src/app/videoPlayer.tsx +++ b/apps/expo/src/app/videoPlayer.tsx @@ -47,7 +47,7 @@ const VideoPlayer: React.FC = ({ data }) => { const fetchVideo = async () => { if (!data) return null; const { id, type } = data; - const media = await fetchMediaDetails(id, type); + const media = await fetchMediaDetails(id, type).catch(() => null); if (!media) return null; const { result } = media; @@ -66,7 +66,10 @@ const VideoPlayer: React.FC = ({ data }) => { episode, ); - const stream = await getVideoStream(scrapeMedia); + const stream = await getVideoStream({ + media: scrapeMedia, + forceVTT: true, + }).catch(() => null); if (!stream) { await ScreenOrientation.lockAsync( ScreenOrientation.OrientationLock.PORTRAIT_UP, diff --git a/packages/provider-utils/package.json b/packages/provider-utils/package.json index fda78cb..4f0f106 100644 --- a/packages/provider-utils/package.json +++ b/packages/provider-utils/package.json @@ -30,6 +30,7 @@ "prettier": "@movie-web/prettier-config", "dependencies": { "@movie-web/providers": "^2.2.0", + "srt-webvtt": "^2.0.0", "tmdb-ts": "^1.6.1" } } diff --git a/packages/provider-utils/src/video.ts b/packages/provider-utils/src/video.ts index aeb3ff6..f32310f 100644 --- a/packages/provider-utils/src/video.ts +++ b/packages/provider-utils/src/video.ts @@ -1,7 +1,8 @@ +import { default as toWebVTT } from "srt-webvtt"; + import type { FileBasedStream, Qualities, - RunnerOptions, ScrapeMedia, Stream, } from "@movie-web/providers"; @@ -11,22 +12,36 @@ import { targets, } from "@movie-web/providers"; -export async function getVideoStream( - media: ScrapeMedia, -): Promise { +export async function getVideoStream({ + media, + forceVTT, +}: { + media: ScrapeMedia; + forceVTT?: boolean; +}): Promise { const providers = makeProviders({ fetcher: makeStandardFetcher(fetch), target: targets.NATIVE, consistentIpForRequests: true, }); - const options: RunnerOptions = { - media, - }; + const result = await providers.runAll({ media }); + if (!result) return null; - const results = await providers.runAll(options); - if (!results) return null; - return results.stream; + if (forceVTT) { + if (result.stream.captions && result.stream.captions.length > 0) { + for (const caption of result.stream.captions) { + if (caption.type === "srt") { + const response = await fetch(caption.url); + const srtSubtitle = await response.blob(); + const vttSubtitleUrl = await toWebVTT(srtSubtitle); + caption.url = vttSubtitleUrl; + caption.type = "vtt"; + } + } + } + } + return result.stream; } export function findHighestQuality( diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index abd8b65..3bb8ff5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -176,6 +176,9 @@ importers: '@movie-web/providers': specifier: ^2.2.0 version: 2.2.0 + srt-webvtt: + specifier: ^2.0.0 + version: 2.0.0 tmdb-ts: specifier: ^1.6.1 version: 1.6.1 @@ -9745,6 +9748,10 @@ packages: resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} dev: false + /srt-webvtt@2.0.0: + resolution: {integrity: sha512-G2Z7/Jf2NRKrmLYNSIhSYZZYE6OFlKXFp9Au2/zJBKgrioUzmrAys1x7GT01dwl6d2sEnqr5uahEIOd0JW/Rbw==} + dev: false + /ssri@8.0.1: resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} engines: {node: '>= 8'}