Something went wrong. Try again.
[READ-ONLY] Mirror of https://github.com/flo-bit/atmo-watch. atmo.watch
Something went wrong. Try again.
2.4 kB · 103 lines
TypeScript
at main
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104import type { MediaImage } from './types';
export const VIDEO_TYPES = [ 'trailer', 'teaser', 'scene', 'clip', 'deleted_scene', 'featurette', 'behind_the_scenes', 'interview', 'blooper', 'supercut', 'recap', 'review', 'analysis', 'reaction', 'fan_edit', 'other'] as const;
export type VideoType = (typeof VIDEO_TYPES)[number];export type VideoCreativeWorkType = 'movie' | 'tv_show' | 'tv_season' | 'tv_episode';
export const VIDEO_TYPE_LABELS: Record<VideoType, string> = { trailer: 'Trailer', teaser: 'Teaser', scene: 'Scene', clip: 'Clip', deleted_scene: 'Deleted scene', featurette: 'Featurette', behind_the_scenes: 'Behind the scenes', interview: 'Interview', blooper: 'Blooper', supercut: 'Supercut', recap: 'Recap', review: 'Review', analysis: 'Analysis', reaction: 'Reaction', fan_edit: 'Fan edit', other: 'Other'};
export type VideoEpisodeOption = { tmdbId: number; tmdbTvSeriesId: number; seasonNumber: number; episodeNumber: number; title: string; label: string;};
export type VideoTarget = { creativeWorkType: VideoCreativeWorkType; tmdbId: number; tmdbTvSeriesId?: number; seasonNumber?: number; episodeNumber?: number; title: string; poster: MediaImage | null; episodeOptions?: VideoEpisodeOption[];};
export type YouTubeVideo = { youtubeId: string; videoUrl: string;};
const YOUTUBE_ID_PATTERN = /^[A-Za-z0-9_-]{11}$/;const YOUTUBE_HOSTS = new Set([ 'youtube.com', 'www.youtube.com', 'm.youtube.com', 'music.youtube.com', 'youtube-nocookie.com', 'www.youtube-nocookie.com']);
export function parseYouTubeVideo(value: string): YouTubeVideo | null { try { const url = new URL(value.trim()); if (url.protocol !== 'https:') return null;
const hostname = url.hostname.toLowerCase(); let youtubeId: string | null = null;
if (hostname === 'youtu.be') { youtubeId = url.pathname.split('/').filter(Boolean)[0] ?? null; } else if (YOUTUBE_HOSTS.has(hostname)) { const segments = url.pathname.split('/').filter(Boolean); if (url.pathname === '/watch') youtubeId = url.searchParams.get('v'); else if (['embed', 'live', 'shorts'].includes(segments[0])) youtubeId = segments[1] ?? null; }
if (!youtubeId || !YOUTUBE_ID_PATTERN.test(youtubeId)) return null; return { youtubeId, videoUrl: `https://www.youtube.com/watch?v=${encodeURIComponent(youtubeId)}` }; } catch { return null; }}