Files
web-temp/layers/utils/youtube.ts
2025-09-24 21:20:41 +09:00

150 lines
4.2 KiB
TypeScript

// ============================================================================
// 유튜브 관련 유틸리티
// ============================================================================
/**
* 유튜브 URL에서 비디오 ID를 추출합니다.
* @param url - 유튜브 URL (watch, embed, youtu.be 등 다양한 형태 지원)
* @returns 비디오 ID 또는 빈 문자열
*/
export const getYouTubeVideoId = (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
*/
/** [TODO] 임베드 형태로 넘어오도록 데이터 수정 후 이부분 사용 필요 없음 */
export const getYouTubeEmbedUrl = (
url: string,
autoplay: boolean = false,
rel: boolean = false
): string => {
const videoId = getYouTubeVideoId(url)
if (!videoId) return ''
const params = new URLSearchParams()
if (autoplay) params.append('autoplay', '1')
if (!rel) params.append('rel', '0')
const queryString = params.toString()
return `https://www.youtube.com/embed/${videoId}${queryString ? `?${queryString}` : ''}`
}
/**
* 유튜브 비디오 ID로부터 썸네일 URL을 생성합니다.
* @param videoId - 유튜브 비디오 ID
* @param quality - 썸네일 품질 ('default', 'medium', 'high', 'standard', 'maxres')
* @returns 썸네일 URL
*/
export const getYouTubeThumbnail = (
videoId: string,
quality: 'default' | 'medium' | 'high' | 'standard' | 'maxres' = 'high'
): string => {
if (!videoId) return ''
const qualityMap = {
default: 'default',
medium: 'mqdefault',
high: 'hqdefault',
standard: 'sddefault',
maxres: 'maxresdefault',
}
return `https://img.youtube.com/vi/${videoId}/${qualityMap[quality]}.jpg`
}
/**
* 유튜브 URL에서 직접 썸네일 URL을 추출합니다.
* @param url - 유튜브 URL
* @param quality - 썸네일 품질
* @returns 썸네일 URL
*/
export const getYouTubeThumbnailFromUrl = (
url: string,
quality: 'default' | 'medium' | 'high' | 'standard' | 'maxres' = 'high'
): string => {
const videoId = getYouTubeVideoId(url)
return getYouTubeThumbnail(videoId, quality)
}
/**
* 미디어 text(src)를 추출합니다.
* @param source - 미디어 소스 객체
* @returns 미디어 text(src)
*/
export const getMediaText = (source: Record<string, any>): string => {
if (!source) return ''
const resource = source.groups?.[0]
const mediaUrl = resource?.display?.text
return mediaUrl || ''
}
/**
* 미디어 이미지를 추출합니다. (유튜브인 경우 썸네일)
* @param source - 미디어 소스 객체
* @param quality - 썸네일 품질
* @returns 미디어 이미지 소스
*/
export const getMediaImgSrc = (
source: Record<string, any>,
quality: 'default' | 'medium' | 'high' | 'standard' | 'maxres' = 'high'
): string => {
if (!source) return ''
const resource = source.groups?.[0]
const mediaType = resource?.group_type
const mediaUrl = resource?.display?.text
if (mediaType === 'video' && mediaUrl) {
const videoId = getYouTubeVideoId(mediaUrl)
const thumbnailUrl = getYouTubeThumbnail(videoId, quality)
return thumbnailUrl
}
return mediaUrl || ''
}
/**
* 미디어 타입을 확인합니다.
* @param source - 미디어 소스 객체
* @returns 미디어 타입 ('video' | 'image' | '')
*/
export const getMediaType = (source: Record<string, any>): string => {
if (!source) return ''
const resource = source.groups?.[0]
const mediaType = resource?.group_type
return mediaType || ''
}
/**
* 비디오 아이템인지 확인합니다.
* @param source - 미디어 소스 객체
* @returns 비디오 여부
*/
export const isVideoItem = (source: Record<string, any>): boolean => {
return getMediaType(source) === 'video'
}