/** * YouTube URL에서 video ID 추출 (watch?v=, youtu.be/, /embed/, /shorts/ 지원). */ export function youTubeId(url: string|null|undefined): string|null { if (!url) { return null; } try { const u = new URL(url); let id = ''; if (u.hostname.includes('youtu.be')) { id = u.pathname.slice(1); } else if (u.searchParams.get('v')) { id = u.searchParams.get('v') ?? ''; } else if (u.pathname.includes('/embed/')) { id = u.pathname.split('/embed/')[1] ?? ''; } else if (u.pathname.includes('/shorts/')) { id = u.pathname.split('/shorts/')[1] ?? ''; } id = id.split('/')[0].split('?')[0]; return id || null; } catch { return null; } } /** * YouTube embed URL (`https://www.youtube.com/embed/`). */ export function youTubeEmbedUrl(url: string|null|undefined): string|null { const id = youTubeId(url); return id ? `https://www.youtube.com/embed/${id}` : null; } /** * YouTube 썸네일 URL (`https://img.youtube.com/vi//hqdefault.jpg`). */ export function youTubeThumbnail(url: string|null|undefined): string|null { const id = youTubeId(url); return id ? `https://img.youtube.com/vi/${id}/hqdefault.jpg` : null; }