【问题标题】:YouTube IFrame API and Angular 8 Routing IssueYouTube IFrame API 和 Angular 8 路由问题
【发布时间】:2019-12-06 04:56:46
【问题描述】:

我正在尝试将 YouTube IFrame API 添加到我的应用程序中,该应用程序为用户注册的课程提供视频。我已设置好它,以便我可以向我的 Angular 应用程序发送 YouTube 嵌入代码,并且 IFrame API 将当我第一次加载课程页面时正确加载视频(取自另一个 StackOverflow 帖子)。当我使用 router.navigate 转到其他组件然后返回课程组件时出现问题,视频和 IFrame 不再加载。

我认为,当页面最初加载时,它会创建可以访问 onYouTubeIframeAPIReady 方法的文档对象。一旦我改变路线,我认为以前的文档对象丢失了。

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>

即使用户路由到不同的组件,我也希望视频重新渲染或保持渲染状态。如果需要更多信息,请告诉我!

【问题讨论】:

    标签: angular typescript youtube-api youtube-iframe-api


    【解决方案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;
        };
      };
    
    }
    

    【讨论】:

    • 嘿伙计,很好的例子,但是当我将按钮与 this.stopVideo() { this.player.stopVideo(); } .... this.player 未定义.... =S
    • 也许你可以尝试改变播放器类型并初始化它
    【解决方案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>
    

    【讨论】:

    • 请说明您的答案将如何帮助解决问题,只是不要在没有上下文的情况下仅给出代码答案。
    • 如果你想在你的项目中链接 youtube 视频。上面的代码会有所帮助。此代码在 Angular 8 中运行良好。只需从
    【解决方案3】:

    发生这种情况是因为一旦将 youtube 脚本加载到 angular 应用程序,当我们返回时它不会重新初始化脚本。因此,就我而言,我删除了ngOnDestroy 上的这两个脚本,并在组件重新初始化时重新加载了脚本。

    const tag = document.createElement('script');
    tag.src = 'https://www.youtube.com/iframe_api';
    tag.id = 'iframe-api-script';
    
    const tag2 = document.createElement('script');
    tag2.src = 'https://www.youtube.com/s/player/7acefd5d/www-widgetapi.vflset/www-widgetapi.js';
    tag2.id = 'www-widgetapi-script';
    
    const firstScriptTag = document.getElementsByTagName('script')[0];
    if (firstScriptTag && firstScriptTag.parentNode) {
       firstScriptTag.parentNode.insertBefore(tag2, firstScriptTag);
       firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
    }
    

    ...

    ngOnDestroy() {
        document.getElementById('www-widgetapi-script')?.remove();
        document.getElementById('iframe-api-script')?.remove();
    }
    

    【讨论】:

      猜你喜欢
      • 2015-10-27
      • 2014-01-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-14
      • 2020-02-25
      • 2023-03-06
      • 1970-01-01
      相关资源
      最近更新 更多