代码之家  ›  专栏  ›  技术社区  ›  Noel R.

使用YouTube API和Angular 6(字体脚本)

  •  2
  • Noel R.  · 技术社区  · 6 年前

    我可以让youtube iframe api(不知何故)在Angular6应用程序中工作。但是,我想从我控制的列表中为它提供动态视频ID。我的计划是从播放器中收听事件,然后在播放完当前视频后加载另一个视频。但我似乎无法克服这个问题。我还在学习typescript和angular,我很好奇为什么我从iframe api播放器中调用的任何函数调用的任何方法都会得到未捕获的类型错误:

    这是我的代码:

    import { Component, OnInit, AfterViewInit } from '@angular/core';
    import { Video } from '../shared/model/video.model';
    import { Subscription } from 'rxjs';
    import { VideoPlayerService } from '../shared/services/video-player.service';
    
    @Component({
      selector: 'ntv-video-player',
      templateUrl: './video-player.component.html',
      styleUrls: ['./video-player.component.css']
    })
    export class VideoPlayerComponent implements OnInit, AfterViewInit {
    
      player;
      video: Video;
      videos: Video[];
      videoSubscription: Subscription;
    
      constructor(private videoService: VideoPlayerService) { }
    
      ngAfterViewInit() {
        const doc = (<any>window).document;
        const playerApiScript = doc.createElement('script');
        playerApiScript.type = 'text/javascript';
        playerApiScript.src = 'https://www.youtube.com/iframe_api';
        doc.body.appendChild(playerApiScript);
      }
    
      ngOnInit() {
    
        (<any>window).onYouTubeIframeAPIReady = () => {
          this.player = new (<any>window).YT.Player('player', {
            height: '100%',
            width: '100%',
            // videoId: this.getVideo(),
            events: {
              'onReady': this.onPlayerReady,
              'onStateChange': this.onPlayerStateChange
            },
            playerVars: {
              autoplay: 1,
              controls: 0,
              modestbranding: 1,
              // playlist: 'UG3sfZKtCQI,ALZHF5UqnU4,x9ZkC3OgI78',
              rel: 0,
              showInfo: 0
            }
          });
        };
      }
    
    
    
      // The API calls this function when the player's state changes.
      onPlayerStateChange(event) {
        console.log('onPlayerStateChange');
        console.log(event.data);
      }
    
      // The API will call this function when the video player is ready
      onPlayerReady(event) {
        console.log(event);
    
        const videoId = this.getVideo();
        event.target.cueVideoById({
          'videoId': videoId
        });
        event.target.playVideo();
      }
    
      getVideo() {
        return '60ItHLz5WEA';
      }
    
    }
    

    下面是我得到的错误:

        Uncaught TypeError: Cannot read property 'getVideo' of undefined
        at push../src/app/video-player/video-player.component.ts.VideoPlayerComponent.onPlayerReady (video-player.component.ts:63)
        at M.h.G (www-widgetapi.js:48)
        at Y.h.o (www-widgetapi.js:92)
        at Y.h.H (www-widgetapi.js:105)
        at Wa.g (www-widgetapi.js:81)
        at Oa.f (www-widgetapi.js:70)
        at ZoneDelegate.push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask (zone.js:421)
        at Zone.push../node_modules/zone.js/dist/zone.js.Zone.runTask (zone.js:188)
        at ZoneTask.push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask [as invoke] (zone.js:496)
        at invokeTask (zone.js:1540)
    push../src/app/video-player/video-player.component.ts.VideoPlayerComponent.onPlayerReady    @   video-player.component.ts:63
    h.G @   www-widgetapi.js:48
    h.o @   www-widgetapi.js:92
    h.H @   www-widgetapi.js:105
    Wa.g    @   www-widgetapi.js:81
    Oa.f    @   www-widgetapi.js:70
    push../node_modules/zone.js/dist/zone.js.ZoneDelegate.invokeTask    @   zone.js:421
    push../node_modules/zone.js/dist/zone.js.Zone.runTask   @   zone.js:188
    push../node_modules/zone.js/dist/zone.js.ZoneTask.invokeTask    @   zone.js:496
    invokeTask  @   zone.js:1540
    globalZoneAwareCallback
    

    如果我从“videoid”属性调用它,这个.getvideo()似乎可以工作,但我希望能够调用OnPlayerReady或OnPlayerStateChange,以便使其更具动态性。以前有人做过这个吗?没有很多关于角的文档。

    事先谢谢。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Joel Richman    6 年前

    我认为你的体验是一个范围问题,你的onplayerready函数不是在你的类的范围内执行的,而是在youtube播放器的范围内执行的。我从错误消息“无法读取未定义的属性”getvideo“推断出这一点。在这个执行点上,“这”不是它看起来的样子。

    尝试如下更改事件分配代码:

     events: {
              'onReady': (event) => { this.onPlayerReady(event); },
              'onStateChange': (event) => { this.onPlayerStateChange(event); }
            },
    
        2
  •  0
  •   Noel R.    6 年前

    谢谢乔尔!这有助于我克服这个问题。一开始我确实得到了一个错误,因为我没有传递参数。所以我就这样做了,而且成功了!

    events: { 'onReady': (event) => { this.onPlayerReady(event); }, 
    'onStateChange': (event) => { this.onPlayerStateChange(event); } 
    },
    

    我想我很难理解API的文档并尝试将其转换为typescript。我只是希望他们能在那里添加更多的文档。也做这样的事 (<any>window).onYouTubeIframeAPIReady = () => { 我觉得有点讨厌。有更好的方法吗?

    很抱歉,我还没有足够的重复点,所以无法对您的答案进行投票。