add trailer api!

This commit is contained in:
Pas 2025-08-24 23:01:01 -06:00
parent a9ff5cb168
commit 7161ee8163
4 changed files with 73 additions and 45 deletions

View file

@ -106,16 +106,18 @@ export function DetailsContent({ data, minimal = false }: DetailsContentProps) {
undefined,
undefined,
formattedLanguage,
data.type,
);
// Transform the data to match the expected format
if (
typeof imdbMetadata.imdb_rating === "number" &&
typeof imdbMetadata.votes === "number"
(typeof imdbMetadata.imdb_rating === "number" &&
typeof imdbMetadata.votes === "number") ||
imdbMetadata.trailer_url
) {
setImdbData({
rating: imdbMetadata.imdb_rating,
votes: imdbMetadata.votes,
trailer_url: imdbMetadata.trailer_url || null,
trailer_url: imdbMetadata.trailer_url,
});
} else {
setImdbData(null);

View file

@ -12,14 +12,23 @@ export function TrailerOverlay({ trailerUrl, onClose }: TrailerOverlayProps) {
className="relative w-[90%] max-w-6xl aspect-video"
onClick={(e) => e.stopPropagation()}
>
<video
className="w-full h-full object-contain"
autoPlay
controls
playsInline
>
<source src={trailerUrl} type="video/mp4" />
</video>
{trailerUrl.includes("youtube.com/embed") ? (
<iframe
src={trailerUrl}
className="w-full h-full"
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
allowFullScreen
/>
) : (
<video
className="w-full h-full object-contain"
autoPlay
controls
playsInline
>
<source src={trailerUrl} type="video/mp4" />
</video>
)}
{/* Close Button */}
<button

View file

@ -171,7 +171,13 @@ export function FeaturedCarousel({
if (!hasExtension.current || !currentMedia?.external_ids?.imdb_id) return;
try {
const imdbData = await scrapeIMDb(currentMedia.external_ids.imdb_id);
const imdbData = await scrapeIMDb(
currentMedia.external_ids.imdb_id,
undefined,
undefined,
undefined,
currentMedia.type,
);
// Only update if we have both rating and votes as non-null numbers
if (
typeof imdbData.imdb_rating === "number" &&

View file

@ -40,30 +40,30 @@ function getImdbLanguageCode(language: string): string {
}
interface IMDbMetadata {
title: string;
original_title: string;
title_type: string;
year: number | null;
end_year: number | null;
day: number | null;
month: number | null;
date: string;
runtime: number | null;
age_rating: string;
imdb_rating: number | null;
votes: number | null;
plot: string;
poster_url: string;
trailer_url: string;
url: string;
genre: string[];
cast: string[];
directors: string[];
writers: string[];
keywords: string[];
countries: string[];
languages: string[];
locations: string[];
title?: string;
original_title?: string;
title_type?: string;
year?: number | null;
end_year?: number | null;
day?: number | null;
month?: number | null;
date?: string;
runtime?: number | null;
age_rating?: string;
imdb_rating?: number | null;
votes?: number | null;
plot?: string;
poster_url?: string;
trailer_url?: string;
url?: string;
genre?: string[];
cast?: string[];
directors?: string[];
writers?: string[];
keywords?: string[];
countries?: string[];
languages?: string[];
locations?: string[];
season?: number;
episode?: number;
episode_title?: string;
@ -115,12 +115,23 @@ export async function scrapeIMDb(
season?: number,
episode?: number,
language?: string,
type?: "movie" | "show",
): Promise<IMDbMetadata> {
// Check if we have a proxy or extension
const hasExtension = await isExtensionActive();
const hasProxy = Boolean(useAuthStore.getState().proxySet);
if (!hasExtension && !hasProxy) {
// Custom API for trailers:
const trailerResponse = await fetch(
`https://fed-trailers.pstream.mov/${type === "movie" ? "movie" : "tv"}/${imdbId}`,
).then((res) => res.json());
if (trailerResponse.trailer?.embed_url) {
return {
trailer_url: trailerResponse.trailer.embed_url,
};
}
// END CUSTOM API
throw new Error(
"IMDb scraping requires either the browser extension or a custom proxy to be set up. " +
"Please install the extension or set up a proxy in the settings.",
@ -300,17 +311,17 @@ export function printIMDbMetadata(metadata: IMDbMetadata): void {
}
console.log("Type:", metadata.title_type);
console.log("Year:", metadata.year);
console.log("Runtime:", formatRuntime(metadata.runtime));
console.log("Runtime:", formatRuntime(metadata.runtime || null));
console.log("Date:", metadata.date);
console.log("Age Rating:", metadata.age_rating);
console.log("Genre:", arrayToString(metadata.genre));
console.log("Cast:", arrayToString(metadata.cast));
console.log("Directed by:", arrayToString(metadata.directors));
console.log("Writers:", arrayToString(metadata.writers));
console.log("Countries:", arrayToString(metadata.countries));
console.log("Filming Locations:", arrayToString(metadata.locations));
console.log("Languages:", arrayToString(metadata.languages));
console.log("Keywords:", arrayToString(metadata.keywords));
console.log("Genre:", arrayToString(metadata.genre || []));
console.log("Cast:", arrayToString(metadata.cast || []));
console.log("Directed by:", arrayToString(metadata.directors || []));
console.log("Writers:", arrayToString(metadata.writers || []));
console.log("Countries:", arrayToString(metadata.countries || []));
console.log("Filming Locations:", arrayToString(metadata.locations || []));
console.log("Languages:", arrayToString(metadata.languages || []));
console.log("Keywords:", arrayToString(metadata.keywords || []));
if (metadata.season && metadata.episode) {
console.log("\nEpisode Details:");