IframePlayer APIアプリケーション(1)

25250 ワード

簡単にsrcをIframeに入れてYoutubeビデオを見ることができますが、Iframe Player APIを使用すると表示できるだけでなく、Web上でYoutubeビデオプレーヤーを簡単に制御することができます.

スクリプト・ロード・ユーティリティ関数の作成


まず,IframeAPIを使用するためにはロードが必要であるため,scriptを生成してロードする実用的な関数を記述した.
ここでonYouTubeIframeApiready関数はIframeAPIのロードが完了したときに呼び出され、この関数に表示されるプレーヤーオブジェクトを作成する必要があります.
this.onloadがnullの理由はIE 9が働かないため、多くの人がそう書いています.
function load(src: string, cb: (err: Error) => void) {
  const firstScript = document.getElementsByTagName('script')[0];
  const script = document.createElement('script');
  script.src = src;
  script.async = true;

  script.onerror = function () {
    this.onload = null;
    this.onerror = null;
    cb(new Error(`Failed to load ${this.src}`));
  };

  if (firstScript) firstScript.parentNode?.insertBefore(script, firstScript);
  else {
    document.head.appendChild(script);
  }
}

function loadIFrameApi() {
  return new Promise((resolve, reject) => {
    if (typeof window.YT === 'object') {
      resolve(window.YT);
      return;
    }

    const protocol = window.location.protocol === 'http:' ? 'http:' : 'https:';

    load(`${protocol}///www.youtube.com/iframe_api`, (err) => {
      if (err) reject(err);
    });

    window.onYouTubeIframeAPIReady = function () {
      resolve(window.YT);
    };
  });
}

export default loadIFrameApi;

プレーヤーオブジェクトを作成する構成部品を作成するには


前述したユーティリティ関数をロードするには、コンポーネントがマウントされたときに呼び出され、呼び出された関数にプレーヤーオブジェクトが作成される限り、コンポーネントが必要です.
プレイヤーオブジェクトを作成すると、参照したdivタグが<iframe>に置き換えられ、プレイヤーを制御するパラメータを使用して、プレイヤーオブジェクトをプレイヤーという変数に入れることができ、呼び出された親エレメントから直接プレイヤーオブジェクトにアクセスして制御することができる.
this bindingを行わないと、プレーヤーオブジェクトのコールバック関数が見つからないため、コールバック呼び出しの関数をバインドする必要があります.
class Youtube extends Component<Props, State> {
  public player: YT.Player | undefined = undefined;

  constructor(props: Props) {
    super(props);
    this.onPlayerReady = this.onPlayerReady.bind(this);
    this.onPlayerStateChange = this.onPlayerStateChange.bind(this);
  }

  componentDidMount() {
    this.createYoutubePlayer();
  }

  componentDidUpdate(prevProps: Props) {
    // TODO: update 관련 핸들링
  }

  componentWillUnmount() {
    this.player?.destroy();
  }

  onPlayerReady() {
    const {
      customProps: { volume, muted, paused },
    } = this.props;

    if (typeof volume !== 'undefined') this.setVolume(volume);
    if (typeof muted !== 'undefined') this.setMute(muted);
    if (typeof paused !== 'undefined') this.setPaused(paused);
  }

  onPlayerStateChange(event: YT.OnStateChangeEvent) {
    const { stateChangeHandler } = this.props;
    if (stateChangeHandler) stateChangeHandler(event);
  }

  setVolume(volume: number) {
    this.player?.setVolume(volume * 100);
  }

  setMute(isMute: boolean) {
    if (isMute) {
      this.player?.mute();
    } else {
      this.player?.unMute();
    }
  }

  setPaused(isPaused: boolean) {
    if (isPaused) {
      this.player?.pauseVideo();
    } else {
      this.player?.playVideo();
    }
  }

  async createYoutubePlayer() {
    const {
      width = '100',
      height = '100',
      autoplay,
      customProps: { videoId },
    } = this.props;

    try {
      const YT = await loadIFrameApi();

      this.player = new YT.Player('DJ-playlist-player', {
        videoId,
        height,
        width,
        playerVars: {
          autoplay: autoplay ? 1 : 0,
          ...PLAYER_DEFAULT_OPTS,
        },
        events: {
          onReady: this.onPlayerReady,
          onStateChange: this.onPlayerStateChange,
        },
      });
    } catch (err) {
      console.log('Player를 생성할 수 없습니다.');
    }
  }

  render() {
    return <div id="DJ-playlist-player" />;
  }
}

export default Youtube;
レンダリングのたびに関数を再生成して解決するには、useCallbackなどの他の操作を使用する必要があるため、より便利なクラスコンポーネントを作成できます.
ここまで書くと、このコンポーネントを呼び出すと、以下のように自動的に再生されるYouTubeの動画が表示されます.

ただし、基本的に提供されるプレーヤーではなく、커스텀 플레이어を使用するため、変化した状態を操作する必要がある.
したがって、Custom Playerを操作する場合、プレーヤーオブジェクトに対して同じ操作を行う必要がある.
次回...
TODO:
1.カスタムプレイヤーの状態統一化
2.任意のタイプを変更

Reference


  • https://developers.google.com/youtube/iframe_api_reference

  • https://developers.google.com/youtube/player_parameters