web-dev-qa-db-ja.com

Angular 6(TypeScript)でYoutubeAPIを使用する

私のAngular 6アプリケーションでYoutubeIframe APIを(どういうわけか)動作させることができます。しかし、私が制御するリストから動的なvideoIdをフィードしたいと思います。私の計画はプレーヤーからのイベントを聞いて、現在のビデオの再生が完了したら別のビデオをロードします。しかし、この問題を乗り越えることができなかったようです。私はまだTypeScriptとAngular and I IFrameAPIプレーヤー内から呼び出す関数から呼び出すメソッドでUncaughtTypeErrorが発生する理由について知りたいです。

これが私のコードです:

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

this.getVideo()は、 'videoId'プロパティから呼び出すと機能するようですが、より動的にするために、onPlayerReadyまたはonPlayerStateChangeのいずれかで呼び出すことができるようにしたいと思います。誰かが以前にこれをしたことがありますか? Angularのドキュメントはそれほど多くありません。

前もって感謝します。

5
Noel R.

Joelに感謝します!これは私が問題を乗り越えるのに役立ちます。パラメータを渡していないため、最初はエラーが発生しました。だから私はこのようにそれをしました、そしてそれはうまくいきました!

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

APIのドキュメントを理解し、それをTypeScriptに変換しようとするのに苦労していると思います。彼らがそこにさらにドキュメントを追加してくれることを願っています。また、このようなことをします(<any>window).onYouTubeIframeAPIReady = () => {私にはちょっとハッキーな感じがします。これを行うためのより良い方法はありますか?

まだ十分な担当者ポイントがないため、回答に賛成できませんでした。

0
Noel R.