typescript - YouTube IFrame API og Angular 8 ruteproblem


Jeg prøver å legge til YouTube IFrame API i applikasjonen min som leverer videoer for et kurs brukeren er påmeldt. Jeg har satt det opp slik at jeg kan sende Angular-applikasjonen min en YouTube-embed-kode, og IFrame API vil laste videoen riktig når jeg først åpner kurs-siden (tatt fra et annet StackOverflow-innlegg). Problemet oppstår når jeg bruker router.navigate for å gå til en annen komponent og deretter kommer tilbake til kurs-komponenten, videoen og IFrame lastes ikke lenger.

Jeg tror at når siden lastes inn først, oppretter den dokumentobjektet som har tilgang til metoden onYouTubeIframeAPIReady. Når jeg bytter ruter, tror jeg at det forrige dokumentobjektet går tapt.

video.component.ts:

    ngAfterViewInit() {
        const doc = (<any>window).document;
        let playerApiScript = doc.createElement('script');
        playerApiScript.type = 'text/javascript';
        playerApiScript.src = 'https://www.youtube.com/iframe_api';
        doc.body.appendChild(playerApiScript);
    }

    ngOnInit() {
        (<any>window).onYouTubeIframeAPIReady = () => {
            console.log('Ready');
            this.player = new (<any>window).YT.Player('player', {
                height: '100%',
                width: '100%',
                videoId: 'Bey4XXJAqS8',
                playerVars: {'autoplay': 0, 'rel': 0, 'controls': 2},
                events: {
                    'onReady': () => {
                    },
                    'onStateChange': () => {
                    }
                }
            });
        };
    }

video.component.html

<div class="embed-responsive embed-responsive-16by9">
    <div id="player" class="embed-responsive-item"></div>
</div>

Jeg vil at videoen skal gjengis på nytt eller forbli gjengitt selv om brukeren navigerer til en annen komponent. Gi meg beskjed hvis mer informasjon er nødvendig!

Svar #1

import {Component, OnInit} from '@angular/core';

@Component({
  selector: 'art-youtube-video',
  templateUrl: './youtube-video-dialog.component.html',
  styleUrls: ['./youtube-video-dialog.component.scss']
})
export class YoutubeVideoDialogComponent implements OnInit {
  public YT: any;
  public video: any;
  public player: any;
  constructor() { }

  init() {
    var tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    var firstScriptTag = document.getElementsByTagName('script')[0];
    firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
  }

ngOnInit() {
    this.init();
    this.video = '1cH2cerUpMQ' //video id

    window['onYouTubeIframeAPIReady'] = (e) => {
      this.YT = window['YT'];
      this.reframed = false;
      this.player = new window['YT'].Player('player', {
        videoId: this.video,
        events: {
          'onStateChange': this.onPlayerStateChange.bind(this),
          'onError': this.onPlayerError.bind(this),
          'onReady': (e) => {
            e.target.playVideo();
          }
        }
      });
    };
  }

  stopVideo() {
    this.player.stopVideo();
  }

  onPlayerStateChange(event) {
    switch (event.data) {
      case window['YT'].PlayerState.PLAYING:
        if (this.cleanTime() == 0) {
          console.log('started ' + this.cleanTime());
        } else {
          console.log('playing ' + this.cleanTime())
        };
        break;
      case window['YT'].PlayerState.PAUSED:
        if (this.player.getDuration() - this.player.getCurrentTime() != 0) {
          console.log('paused' + ' @ ' + this.cleanTime());
        };
        break;
      case window['YT'].PlayerState.ENDED:
        console.log('ended ');
        break;
    };
  };
  //utility
  cleanTime() {
    return Math.round(this.player.getCurrentTime())
  };
  onPlayerError(event) {
    switch (event.data) {
      case 2:
        console.log('' + this.video)
        break;
      case 100:
        break;
      case 101 || 150:
        break;
    };
  };

}

Svar #2

Example link of youtube:https://www.youtube.com/watch?v=11AXUzhXK4E&t=2s
 <iframe
  src="https://www.youtube.com/embed/11AXUzhXK4E"
  frameborder="0"  width="800"  height="800"  allowfullscreen>
</iframe>

Relaterte artikler