// src/lib/utils/youtube.ts /** * YouTube URL Parser and Utilities * * Hilfsfunktionen zum Parsen von YouTube-URLs und Generieren von Embed-URLs. * Unterstützt verschiedene YouTube-URL-Formate: * - youtube.com/watch?v=VIDEO_ID * - youtu.be/VIDEO_ID * - youtube.com/embed/VIDEO_ID * - youtube.com/shorts/VIDEO_ID */ /** * Extrahiert die Video-ID aus einer YouTube-URL. * * @param url - Die YouTube-URL * @returns Die Video-ID oder null wenn nicht gefunden * * @example * extractYouTubeId('https://www.youtube.com/watch?v=dQw4w9WgXcQ') // 'dQw4w9WgXcQ' * extractYouTubeId('https://youtu.be/dQw4w9WgXcQ') // 'dQw4w9WgXcQ' * extractYouTubeId('https://www.youtube.com/shorts/VIDEO_ID') // 'VIDEO_ID' */ export function extractYouTubeId(url: string): string | null { if (!url) return null const patterns = [ /youtube\.com\/watch\?v=([^&]+)/, /youtu\.be\/([^?]+)/, /youtube\.com\/embed\/([^?]+)/, /youtube\.com\/shorts\/([^?]+)/, /youtube-nocookie\.com\/embed\/([^?]+)/, ] for (const pattern of patterns) { const match = url.match(pattern) if (match) return match[1] } return null } /** * Generiert eine YouTube Embed-URL. * * @param videoId - Die YouTube Video-ID * @param privacyMode - Wenn true, wird youtube-nocookie.com verwendet (DSGVO-konform) * @param options - Zusätzliche Embed-Optionen * @returns Die vollständige Embed-URL * * @example * getYouTubeEmbedUrl('dQw4w9WgXcQ') // 'https://www.youtube-nocookie.com/embed/dQw4w9WgXcQ' * getYouTubeEmbedUrl('dQw4w9WgXcQ', false) // 'https://www.youtube.com/embed/dQw4w9WgXcQ' */ export function getYouTubeEmbedUrl( videoId: string, privacyMode = true, options?: { autoplay?: boolean muted?: boolean loop?: boolean controls?: boolean startTime?: number } ): string { const domain = privacyMode ? 'www.youtube-nocookie.com' : 'www.youtube.com' const baseUrl = `https://${domain}/embed/${videoId}` // Build query parameters const params = new URLSearchParams() if (options?.autoplay) params.set('autoplay', '1') if (options?.muted) params.set('mute', '1') if (options?.loop) { params.set('loop', '1') params.set('playlist', videoId) // Required for loop to work } if (options?.controls === false) params.set('controls', '0') if (options?.startTime) params.set('start', String(options.startTime)) const queryString = params.toString() return queryString ? `${baseUrl}?${queryString}` : baseUrl } /** * Generiert eine YouTube Thumbnail-URL. * * @param videoId - Die YouTube Video-ID * @param quality - Die gewünschte Qualität * @returns Die Thumbnail-URL * * @example * getYouTubeThumbnail('dQw4w9WgXcQ') // 'https://img.youtube.com/vi/dQw4w9WgXcQ/hqdefault.jpg' * getYouTubeThumbnail('dQw4w9WgXcQ', 'maxres') // 'https://img.youtube.com/vi/dQw4w9WgXcQ/maxresdefault.jpg' */ export function getYouTubeThumbnail( videoId: string, quality: 'default' | 'mq' | 'hq' | 'sd' | 'maxres' = 'hq' ): string { const qualityMap: Record = { default: 'default', mq: 'mqdefault', hq: 'hqdefault', sd: 'sddefault', maxres: 'maxresdefault', } return `https://img.youtube.com/vi/${videoId}/${qualityMap[quality]}.jpg` } /** * Prüft, ob eine URL eine gültige YouTube-URL ist. * * @param url - Die zu prüfende URL * @returns true wenn die URL eine gültige YouTube-URL ist */ export function isValidYouTubeUrl(url: string): boolean { if (!url) return false const youtubePatterns = [ /youtube\.com\/watch\?v=/, /youtu\.be\//, /youtube\.com\/embed\//, /youtube\.com\/shorts\//, /youtube-nocookie\.com\/embed\//, ] return youtubePatterns.some((pattern) => pattern.test(url)) } /** * Extrahiert die Playlist-ID aus einer YouTube-Playlist-URL. * * @param url - Die YouTube-Playlist-URL * @returns Die Playlist-ID oder null wenn nicht gefunden * * @example * extractYouTubePlaylistId('https://www.youtube.com/playlist?list=PLxxxxxx') // 'PLxxxxxx' */ export function extractYouTubePlaylistId(url: string): string | null { if (!url) return null const patterns = [ /youtube\.com\/playlist\?list=([^&]+)/, /youtube\.com\/watch\?.*list=([^&]+)/, ] for (const pattern of patterns) { const match = url.match(pattern) if (match) return match[1] } return null } /** * Generiert eine YouTube Playlist Embed-URL. * * @param playlistId - Die YouTube Playlist-ID * @param privacyMode - Wenn true, wird youtube-nocookie.com verwendet * @returns Die vollständige Playlist Embed-URL */ export function getYouTubePlaylistEmbedUrl(playlistId: string, privacyMode = true): string { const domain = privacyMode ? 'www.youtube-nocookie.com' : 'www.youtube.com' return `https://${domain}/embed/videoseries?list=${playlistId}` }