Files
web-temp/layers/utils/youtubeUtil.ts
2026-03-05 14:38:18 +09:00

105 lines
2.9 KiB
TypeScript

/**
* 유튜브 유틸리티 함수
* @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')
}
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}`
}