/** * 유튜브 유틸리티 함수 * @description 유튜브 관련 유틸리티 함수를 제공합니다. */ /** * 유튜브 URL에서 비디오 ID를 추출합니다. * @param url - 유튜브 URL (watch, embed, youtu.be 등 다양한 형태 지원) * @returns 비디오 ID 또는 빈 문자열 */ export const getYouTubeId = (url: string): string => { if (!url) return '' // 다양한 유튜브 URL 패턴 지원 const patterns = [ /(?:youtube\.com\/watch\?v=|youtu\.be\/|youtube\.com\/embed\/|youtube\.com\/shorts\/)([^&\n?#]+)/, /youtube\.com\/watch\?.*v=([^&\n?#]+)/, /youtube\.com\/embed\/([^&\n?#]+)/, /youtube\.com\/shorts\/([^&\n?#]+)/, ] for (const pattern of patterns) { const match = url.match(pattern) if (match && match[1]) { return match[1] } } return '' } /** * 유튜브 URL을 반환합니다. * @param url - 유튜브 URL * @param autoplay - 자동재생 여부 * @param rel - 관련 비디오 표시 여부 * @returns 임베드 URL */ export const getYouTubeUrl = ( url: string, autoplay: boolean = true, rel: boolean = false ): string => { if (!url) return '' try { const urlObj = new URL(url) const params = new URLSearchParams(urlObj.searchParams) // 기본 파라미터 보장 if (!params.has('autoplay')) { params.set('autoplay', autoplay ? '1' : '0') } if (!params.has('rel')) { params.set('rel', rel ? '1' : '0') } if (!params.has('mute')) { params.set('mute', '1') } const baseUrl = (() => { const isEmbedUrl = urlObj.pathname.startsWith('/embed/') if (isEmbedUrl) { return `${urlObj.origin}${urlObj.pathname}` } // 일반 URL이면 id 추출 후 embed URL로 변환 const youtubeId = getYouTubeId(url) if (!youtubeId) return '' return `https://www.youtube.com/embed/${youtubeId}` })() const queryString = params.toString() return queryString ? `${baseUrl}?${queryString}` : baseUrl } catch { return url } } /** * 유튜브 URL에서 비디오 ID를 추출하고, 비디오 ID로부터 썸네일 URL을 생성합니다. * @param url - 유튜브 URL * @param quality - 썸네일 품질 ('default', 'medium', 'high', 'standard', 'maxres') * @param format - 이미지 포맷 ('jpg' | 'webp'), 기본값은 'webp' * @returns 썸네일 URL */ export const getYouTubeThumbnail = ( url: string, quality: 'default' | 'medium' | 'high' | 'standard' | 'maxres' = 'standard', format: 'jpg' | 'webp' = 'webp' ): string => { const videoId = getYouTubeId(url) if (!videoId) return '' const qualityMap = { default: 'default', medium: 'mqdefault', high: 'hqdefault', standard: 'sddefault', maxres: 'maxresdefault', } const basePath = format === 'webp' ? 'vi_webp' : 'vi' const extension = format === 'webp' ? 'webp' : 'jpg' return `https://img.youtube.com/${basePath}/${videoId}/${qualityMap[quality]}.${extension}` }