21 lines
923 B
TypeScript
21 lines
923 B
TypeScript
/** Only recognized HTTPS YouTube URLs can become players. */
|
|
export function youtubeVideoId(value: string): string | null {
|
|
// Check raw input before URL parsing can normalize whitespace, slashes or dot paths.
|
|
if (typeof value !== 'string' || /[\s\\\u0000-\u001f\u007f]|%(?:0[0-9a-f]|1[0-9a-f]|7f)/i.test(value)) return null
|
|
const match = /^https:\/\/(youtu\.be|(?:www\.)?youtube\.com)(?::443)?(\/[^?#]*)(?:\?[^#]*)?(?:#[^]*)?$/.exec(value)
|
|
if (!match) return null
|
|
try {
|
|
const url = new URL(value)
|
|
if (url.protocol !== 'https:' || url.username || url.password || url.port) return null
|
|
let id: string | null = null
|
|
if (match[1] === 'youtu.be') {
|
|
id = match[2].slice(1)
|
|
} else if (match[2] === '/watch' && url.searchParams.getAll('v').length === 1) {
|
|
id = url.searchParams.get('v')
|
|
}
|
|
return id && /^[A-Za-z0-9_-]{11}$/.test(id) ? id : null
|
|
} catch {
|
|
return null
|
|
}
|
|
}
|