youtube.ts 1.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. let apiPromise: Promise<void>;
  2. export function loadYoutubeApi(): Promise<void> {
  3. if (apiPromise) {
  4. return apiPromise;
  5. }
  6. console.time('Loading YouTube API');
  7. apiPromise = new Promise((resolve, _) => {
  8. const tag = document.createElement('script');
  9. tag.src = 'https://www.youtube.com/iframe_api';
  10. window.onYouTubeIframeAPIReady = () => {
  11. console.timeEnd('Loading YouTube API');
  12. resolve();
  13. }
  14. document.body.appendChild(tag);
  15. });
  16. return apiPromise;
  17. }
  18. export async function createPlayer(element: HTMLElement): Promise<YT.Player> {
  19. await loadYoutubeApi();
  20. console.time('Loading YouTube player');
  21. return new Promise((resolve, reject) => {
  22. const player = new YT.Player(element, {
  23. height: '100%',
  24. width: '100%',
  25. events: {
  26. onReady: () => {
  27. console.timeEnd('Loading YouTube player');
  28. resolve(player);
  29. },
  30. onError: ({ data }) => {
  31. reject(data);
  32. }
  33. },
  34. playerVars: {
  35. disablekb: 1,
  36. rel: 0,
  37. iv_load_policy: 3,
  38. fs: 0
  39. }
  40. });
  41. });
  42. }
  43. export function getVideoId(url: string): string | null {
  44. try {
  45. const parsed = new URL(url);
  46. if (!parsed.hostname.endsWith('youtube.com')) {
  47. return null;
  48. }
  49. return parsed.searchParams.get('v');
  50. } catch {
  51. return null;
  52. }
  53. }