36 lines
1.4 KiB
TypeScript
36 lines
1.4 KiB
TypeScript
|
|
/**
|
|
* Extracts a YouTube video ID from various URL formats.
|
|
* @param url The YouTube URL.
|
|
* @returns The video ID, or null if not found.
|
|
*/
|
|
const extractYouTubeVideoId = (url: string): string | null => {
|
|
if (!url || typeof url !== 'string') return null;
|
|
|
|
const regExp = /(?:youtube\.com\/(?:[^\/]+\/.+\/|(?:v|e(?:mbed)?)\/|.*[?&]v=|[^\/]+\/(?:live|shorts)\/)|youtu\.be\/)([^"&?\/\s]{11})/;
|
|
const match = url.match(regExp);
|
|
|
|
if (match && match[1]) {
|
|
return match[1];
|
|
}
|
|
return null;
|
|
};
|
|
|
|
/**
|
|
* Generates a YouTube embed URL with common parameters and API support.
|
|
* @param url The original YouTube URL.
|
|
* @returns The embed URL string, or null if the video ID cannot be extracted or URL is invalid.
|
|
*/
|
|
export const getYouTubeEmbedUrl = (url: string): string | null => {
|
|
const videoId = extractYouTubeVideoId(url);
|
|
if (!videoId) {
|
|
return null;
|
|
}
|
|
// Common parameters + enablejsapi for API control + origin for security
|
|
// mute=1 is important for allowing autoplay and programmatic unmuting.
|
|
// The origin parameter MUST match the domain where the iframe is hosted.
|
|
const origin = typeof window !== 'undefined' ? window.location.origin : '';
|
|
const params = `autoplay=1&mute=1&playsinline=1&controls=1&modestbranding=1&rel=0&fs=1&iv_load_policy=3&enablejsapi=1&origin=${encodeURIComponent(origin)}`;
|
|
return `https://www.youtube.com/embed/${videoId}?${params}`;
|
|
};
|