2023-02-18 22:06:34 +08:00
|
|
|
export const YOUTUBE_REGEX = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be)(?!.*\/channel\/)(?!\/@)(.+)?$/
|
|
|
|
export const YOUTUBE_REGEX_GLOBAL = /^(https?:\/\/)?(www\.|music\.)?(youtube\.com|youtu\.be)(?!.*\/channel\/)(?!\/@)(.+)?$/g
|
2022-06-25 17:16:17 +08:00
|
|
|
|
2022-06-17 11:29:48 +08:00
|
|
|
export const isValidYoutubeUrl = (url: string) => {
|
2022-06-25 17:16:17 +08:00
|
|
|
return url.match(YOUTUBE_REGEX)
|
2022-06-17 11:29:48 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
export interface GetEmbedUrlOptions {
|
|
|
|
url: string;
|
2022-10-17 23:28:30 +08:00
|
|
|
allowFullscreen?: boolean;
|
|
|
|
autoplay?: boolean;
|
|
|
|
ccLanguage?:string;
|
|
|
|
ccLoadPolicy?:boolean;
|
2022-06-17 11:29:48 +08:00
|
|
|
controls?: boolean;
|
2022-10-17 23:28:30 +08:00
|
|
|
disableKBcontrols?: boolean,
|
|
|
|
enableIFrameApi?: boolean;
|
|
|
|
endTime?: number;
|
|
|
|
interfaceLanguage?: string;
|
|
|
|
ivLoadPolicy?: number;
|
|
|
|
loop?: boolean;
|
|
|
|
modestBranding?: boolean;
|
2022-06-17 11:29:48 +08:00
|
|
|
nocookie?: boolean;
|
2022-10-17 23:28:30 +08:00
|
|
|
origin?: string;
|
|
|
|
playlist?: string;
|
|
|
|
progressBarColor?: string;
|
2022-06-17 11:29:48 +08:00
|
|
|
startAt?: number;
|
|
|
|
}
|
|
|
|
|
|
|
|
export const getYoutubeEmbedUrl = (nocookie?: boolean) => {
|
|
|
|
return nocookie ? 'https://www.youtube-nocookie.com/embed/' : 'https://www.youtube.com/embed/'
|
|
|
|
}
|
|
|
|
|
2022-12-07 07:45:51 +08:00
|
|
|
export const getEmbedUrlFromYoutubeUrl = (options: GetEmbedUrlOptions) => {
|
2022-06-17 11:29:48 +08:00
|
|
|
const {
|
|
|
|
url,
|
2022-10-17 23:28:30 +08:00
|
|
|
allowFullscreen,
|
|
|
|
autoplay,
|
|
|
|
ccLanguage,
|
|
|
|
ccLoadPolicy,
|
2022-06-17 11:29:48 +08:00
|
|
|
controls,
|
2022-10-17 23:28:30 +08:00
|
|
|
disableKBcontrols,
|
|
|
|
enableIFrameApi,
|
|
|
|
endTime,
|
|
|
|
interfaceLanguage,
|
|
|
|
ivLoadPolicy,
|
|
|
|
loop,
|
|
|
|
modestBranding,
|
2022-06-17 11:29:48 +08:00
|
|
|
nocookie,
|
2022-10-17 23:28:30 +08:00
|
|
|
origin,
|
|
|
|
playlist,
|
|
|
|
progressBarColor,
|
2022-06-17 11:29:48 +08:00
|
|
|
startAt,
|
|
|
|
} = options
|
|
|
|
|
2023-11-06 14:57:56 +08:00
|
|
|
if (!isValidYoutubeUrl(url)) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
2022-06-17 11:29:48 +08:00
|
|
|
// if is already an embed url, return it
|
|
|
|
if (url.includes('/embed/')) {
|
|
|
|
return url
|
|
|
|
}
|
|
|
|
|
|
|
|
// if is a youtu.be url, get the id after the /
|
|
|
|
if (url.includes('youtu.be')) {
|
|
|
|
const id = url.split('/').pop()
|
|
|
|
|
|
|
|
if (!id) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
return `${getYoutubeEmbedUrl(nocookie)}${id}`
|
|
|
|
}
|
|
|
|
|
|
|
|
const videoIdRegex = /v=([-\w]+)/gm
|
|
|
|
const matches = videoIdRegex.exec(url)
|
|
|
|
|
|
|
|
if (!matches || !matches[1]) {
|
|
|
|
return null
|
|
|
|
}
|
|
|
|
|
|
|
|
let outputUrl = `${getYoutubeEmbedUrl(nocookie)}${matches[1]}`
|
|
|
|
|
|
|
|
const params = []
|
|
|
|
|
2022-11-05 00:21:52 +08:00
|
|
|
if (allowFullscreen === false) {
|
2022-10-17 23:28:30 +08:00
|
|
|
params.push('fs=0')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (autoplay) {
|
|
|
|
params.push('autoplay=1')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ccLanguage) {
|
|
|
|
params.push(`cc_lang_pref=${ccLanguage}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ccLoadPolicy) {
|
|
|
|
params.push('cc_load_policy=1')
|
|
|
|
}
|
|
|
|
|
2022-06-17 11:29:48 +08:00
|
|
|
if (!controls) {
|
|
|
|
params.push('controls=0')
|
|
|
|
}
|
|
|
|
|
2022-10-17 23:28:30 +08:00
|
|
|
if (disableKBcontrols) {
|
|
|
|
params.push('disablekb=1')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (enableIFrameApi) {
|
|
|
|
params.push('enablejsapi=1')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (endTime) {
|
|
|
|
params.push(`end=${endTime}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (interfaceLanguage) {
|
|
|
|
params.push(`hl=${interfaceLanguage}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ivLoadPolicy) {
|
|
|
|
params.push(`iv_load_policy=${ivLoadPolicy}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (loop) {
|
|
|
|
params.push('loop=1')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (modestBranding) {
|
|
|
|
params.push('modestbranding=1')
|
|
|
|
}
|
|
|
|
|
|
|
|
if (origin) {
|
|
|
|
params.push(`origin=${origin}`)
|
|
|
|
}
|
|
|
|
|
|
|
|
if (playlist) {
|
|
|
|
params.push(`playlist=${playlist}`)
|
|
|
|
}
|
|
|
|
|
2022-06-17 11:29:48 +08:00
|
|
|
if (startAt) {
|
|
|
|
params.push(`start=${startAt}`)
|
|
|
|
}
|
|
|
|
|
2022-10-17 23:28:30 +08:00
|
|
|
if (progressBarColor) {
|
|
|
|
params.push(`color=${progressBarColor}`)
|
|
|
|
}
|
|
|
|
|
2022-06-17 11:29:48 +08:00
|
|
|
if (params.length) {
|
|
|
|
outputUrl += `?${params.join('&')}`
|
|
|
|
}
|
|
|
|
|
|
|
|
return outputUrl
|
|
|
|
}
|