【PR】を含みます。

フロントエンド

【JavaScript】YouTubeのIFrame APIで動画を埋め込み・自動再生

JavaScriptでYouTube動画を埋め込み

YouTube動画を自分のWebサイトに埋め込んで、再生・停止・音量調整などを自由にコントロールしたいと思ったことはありませんか?

そんなときに使えるのが「YouTube IFrame Player API」です。本記事では、このAPIを使ってJavaScriptだけでYouTube動画をサイト内に読み込み、操作する方法を解説します。

基本の実装から便利なオプション、再生イベントやメソッドの活用例まで、コピペで動くサンプルコードとあわせて紹介します。

JavaScriptでYouTube動画を読み込む

実装コード

まずは動画を表示するためのHTML・CSSと、APIを読み込むJavaScriptです。プレーヤーを表示したい場所に空の<div>を置き、その要素をAPIが動画プレーヤーに置き換えます。

HTML
Copy
<div class="player-container">
  <div id="player"></div>
</div>
CSS
Copy
.player-container {
  display: flex;
  justify-content: center;
}
JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    videoId: 'VIDEO_ID', // ビデオIDを指定
  });
}

onYouTubeIframeAPIReadyは、APIの読み込みが終わると自動的に呼ばれる関数です。関数名は固定なので変更しないでください。この中でnew YT.Player()を実行すると、指定した要素が動画プレーヤーに置き換わります。

このコードをブラウザで開くと、次のように動画プレーヤーが表示されます。

YouTube IFrame Player APIで埋め込んだ動画プレーヤーの表示例

※ サンプル画像は「YouTube Developers Live」(Google for Developers)を使用しています。

ビデオIDの確認方法

YouTubeのビデオIDは、URL・共有リンク・埋め込みコードなどから確認できます。今回はURLから確認する方法を紹介します。

以下のようなURLの場合、v=xxxxxxxxxxx部分のxxxxxxxxxxxがビデオIDです(英数字11文字で構成されます)。

https://www.youtube.com/watch?v=xxxxxxxxxxx&list=xxxxxxxx&start_radio=1

YouTube動画をレスポンシブに埋め込む(画面幅に合わせる)

YT.Playerが生成するiframeは、初期状態では幅・高さが固定です。スマホとPCで見やすく表示するには、16:9の比率を保ったまま親要素の幅いっぱいに広げるのが定番です。

最近のブラウザなら、CSSのaspect-ratioを使うのが一番シンプルです。プレーヤーの幅・高さを'100%'にして、コンテナ側で比率を指定します。

CSS
Copy
.player-container {
  width: 100%;
  max-width: 720px;  /* 大きくなりすぎないよう上限を設定 */
  margin-inline: auto;  /* 中央寄せ */
  aspect-ratio: 16 / 9;  /* 16:9の比率を維持 */
}
/* APIが生成するiframeをコンテナいっぱいに広げる */
.player-container iframe {
  width: 100%;
  height: 100%;
}

プレーヤー側も幅・高さを'100%'に指定します。

JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    width: '100%',
    height: '100%',
    videoId: 'VIDEO_ID', // ビデオIDを指定
  });
}

aspect-ratioは新しめのブラウザ向けのプロパティです。古い環境にも対応したい場合は、親要素にpadding-top: 56.25%(=9÷16)を指定してiframeをposition: absoluteで重ねる、昔ながらの方法も使えます。

YouTube動画を自動再生する(ミュートが必要な理由)

ページを開いたときに動画を自動再生したい、という場面はよくあります。ただし今のブラウザは「音が出る状態」での自動再生を原則ブロックします。ユーザーが操作していないのに音が鳴るのを防ぐためです。そのため、自動再生させたいときはミュート状態で始めるのが基本です。

具体的には、autoplay: 1を指定したうえで、準備完了(onReady)の中でplayer.mute()を呼んでからplayer.playVideo()します。スマホ(iPhone)でページ内再生したい場合はplaysinline: 1もあわせて指定します。

JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    videoId: 'VIDEO_ID', // ビデオIDを指定
    playerVars: {
      autoplay: 1,    // 自動再生を試みる
      playsinline: 1, // iPhoneでも全画面にせずページ内で再生
    },
    events: {
      'onReady': onPlayerReady,
      'onAutoplayBlocked': onAutoplayBlocked,
    },
  });
  function onPlayerReady(event) {
    player.mute();     // ミュートしないと多くのブラウザで再生がブロックされる
    player.playVideo();
  }
  function onAutoplayBlocked(event) {
    // それでもブロックされた場合(再生ボタンを出すなどの代替策を取る)
    console.log('自動再生がブロックされました');
  }
}
  • 音ありの自動再生は確実にはできません。ミュートで始めて、ユーザーが操作したタイミングでplayer.unMute()する流れが現実的です。
  • ミュートしても再生されないことがあります(端末の省電力設定やブラウザのポリシー次第)。onAutoplayBlockedで検知して、再生ボタンを表示するなどの代替策を用意しておくと安心です。
  • 自動再生の扱いはブラウザのポリシーで決まります。詳しくはChromeの自動再生ポリシー(Chrome for Developers)MDNの自動再生ガイドを参照してください。

YouTube IFrame Player APIの主なオプション一覧

プレーヤーの動作はplayerVarsにオプションを渡して設定します。ここでは代表的なものを紹介します。すべてのパラメータは公式のパラメータ一覧で確認できます。

autoplay
動画の自動再生設定
autoplay: 0(自動再生OFF)またはautoplay: 1(自動再生ON)
※多くのブラウザでは、音声ありの自動再生はブロックされます。自動再生したい場合は、onReady内でplayer.mute()を呼んでミュート状態にしておくと再生されやすくなります。再生がブロックされたかどうかは後述のonAutoplayBlockedイベントで検知できます。
color
プレイヤーの動画進行状況バーの色を指定
color: 'red'(赤)または color: 'white'(白)
controls
プレイヤーのコントロールを表示するか
controls: 0(非表示)または controls: 1(表示)
disablekb
プレイヤーのキーボード操作
disablekb: 0(キーボード操作有効)または disablekb: 1(キーボード操作無効)
enablejsapi
埋め込みプレーヤーをJavaScript(IFrame Player API)から制御できるようにするか
enablejsapi: 0(無効)または enablejsapi: 1(有効)
※本記事のようにnew YT.Player()でプレーヤーを生成する場合は自動的に有効になるので、明示指定は不要です。すでにHTMLに直接書いた<iframe>を後から制御したいときは、そのsrcのURLにenablejsapi=1を付け、あわせてorigin(自サイトのドメイン)を指定します(例: ?enablejsapi=1&origin=https://example.com)。
end
再生終了位置(秒単位)
end: 60
fs
フルスクリーンボタンの表示
fs: 0(非表示)または fs: 1(表示)
loop
動画のループ再生
loop: 0(無効)または loop: 1(有効)
※ループ再生を有効にする場合、playlistに同じビデオIDを指定します
playlist
再生リスト
値: カンマ区切りで複数のビデオIDを指定
playlist: 'VIDEO_ID_1,VIDEO_ID_2'
playsinline
iOSデバイスでのインライン再生
playsinline: 0(フルスクリーン)または playsinline: 1(インライン)
※iPhoneなどで全画面にせずページ内で再生したい場合は1を指定します。
start
再生開始位置(秒単位)
start: 10

【サンプルコード】オプションの使用例

onYouTubeIframeAPIReadyの中で、playerVarsにオプションを追加します。

JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    videoId: 'VIDEO_ID_1', // ビデオIDを指定
    playerVars: {
      controls: 1, // コントロールを表示
      playlist: 'VIDEO_ID_1,VIDEO_ID_2', // 再生リスト
    },
  });
}

YouTube IFrame Player APIの主なイベント

プレーヤーの状態変化はイベントで受け取れます。eventsにコールバック関数を登録します。

onReady
プレイヤーが準備完了したときに発生
使用例: onReady: function(event) { /* コード */ }
onStateChange
プレイヤーの状態が変わったときに発生
使用例: onStateChange: function(event) { /* コード */ }
onPlaybackQualityChange
画質が変わったときに発生
使用例: onPlaybackQualityChange: function(event) { /* コード */ }
onPlaybackRateChange
再生速度が変わったときに発生
使用例: onPlaybackRateChange: function(event) { /* コード */ }
onError
エラーが発生したときに発生
使用例: onError: function(event) { /* コード */ }
event.dataにエラーコードが入ります(2=パラメータ(ビデオIDなど)が不正、5=HTML5プレーヤーで再生できない、100=動画が見つからない/非公開、101/150=埋め込み再生が許可されていない、153=リクエストのRefererが無効・許可されていない)。
onApiChange
プレイヤーAPIが変更されたときに発生
※APIの内部的な変更が発生する可能性がある場合に使用します。
使用例: onApiChange: function(event) { /* コード */ }
onAutoplayBlocked
ブラウザによって自動再生(またはスクリプトからの再生)がブロックされたときに発生
使用例: onAutoplayBlocked: function(event) { /* コード */ }

【サンプルコード】イベントの使用例

eventsに各イベントのハンドラ関数を登録します。

JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    videoId: 'VIDEO_ID', // ビデオIDを指定
    events: {
      'onReady': onPlayerReady,
      'onStateChange': onPlayerStateChange,
      'onPlaybackQualityChange': onPlaybackQualityChange,
      'onPlaybackRateChange': onPlaybackRateChange,
      'onError': onPlayerError,
      'onApiChange': onApiChange,
      'onAutoplayBlocked': onAutoplayBlocked
    }
  });
  function onPlayerReady(event) {
    console.log('プレイヤーの準備が完了しました');
  }
  function onPlayerStateChange(event) {
    console.log('プレイヤーの状態が変わりました: ' + event.data);
  }
  function onPlaybackQualityChange(event) {
    console.log('画質が変わりました: ' + event.data);
  }
  function onPlaybackRateChange(event) {
    console.log('再生速度が変わりました: ' + event.data);
  }
  function onPlayerError(event) {
    console.log('エラーが発生しました: ' + event.data);
  }
  function onApiChange(event) {
    console.log('プレイヤーAPIが変更されました');
  }
  function onAutoplayBlocked(event) {
    console.log('自動再生がブロックされました');
  }
}

読み込んだYouTube動画を操作するための主なメソッド

YouTube IFrame Player APIでメソッド(関数)を使うときは、プレイヤーの準備完了後onReadyイベントなどの中で実行する必要があります。

※プレイヤーの読み込み前に実行すると、エラーになります(メソッドがまだ用意されていないため)。

player.playVideo()
動画を再生する
player.pauseVideo()
動画を一時停止する
player.stopVideo()
動画を停止する
player.seekTo(seconds, allowSeekAhead)
指定した秒数にシークする
引数:
  • seconds: シークする秒数
  • allowSeekAhead: trueの場合、バッファリングを許可
player.mute()
音声をミュートする
player.unMute()
音声のミュートを解除する
player.isMuted()
音声がミュートされているかどうかを確認する
戻り値: true(ミュートされている)、false(ミュートされていない)
player.setVolume(volume)
音量を設定する
引数:
  • volume: 設定する音量(0から100)
player.getVolume()
現在の音量を取得する
戻り値: 音量(0から100)
player.setPlaybackRate(suggestedRate)
再生速度を設定する
引数:
  • suggestedRate: 設定する再生速度
player.getPlaybackRate()
現在の再生速度を取得する
戻り値: 再生速度
player.getAvailablePlaybackRates()
利用可能な再生速度のリストを取得する
戻り値: 再生速度のリスト
player.setSize(width, height)
プレーヤーのサイズを設定する
引数:
  • width: 幅
  • height: 高さ
player.getVideoLoadedFraction()
読み込まれた動画の割合を取得する
戻り値: 読み込まれた割合(0から1)
player.getPlayerState()
プレーヤーの現在の状態を取得する
戻り値:
  • -1: 未開始
  • 0: 終了
  • 1: 再生中
  • 2: 一時停止中
  • 3: バッファリング中
  • 5: 頭出し済み(プレイヤーの準備が完了し、再生可能な状態)
player.getCurrentTime()
動画の現在の再生位置を取得する
戻り値: 再生位置(秒)
player.getDuration()
動画の全体の長さを取得する
戻り値: 長さ(秒)
player.getVideoUrl()
現在再生中の動画のURLを取得する
戻り値: 動画のURL
player.getVideoEmbedCode()
現在再生中の動画の埋め込みコードを取得する
戻り値: 埋め込みコード

【サンプルコード】メソッドの使用例

準備完了後に呼ばれるonReadyの中でメソッド(ここではmute())を実行します。

JavaScript
Copy
// YouTube IFrame Player APIの読み込み
const tag = document.createElement('script');
tag.src = 'https://www.youtube.com/iframe_api';
const firstScriptTag = document.getElementsByTagName('script')[0];
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);
// YouTubeプレーヤーの読み込み
let player;
const targetPlayer = document.getElementById('player');
// APIの読み込み完了後に自動で呼ばれる(関数名は固定)
function onYouTubeIframeAPIReady() {
  player = new YT.Player(targetPlayer, {
    videoId: 'VIDEO_ID', // ビデオIDを指定
    events: {
      'onReady': onPlayerReady,
    }
  });
  function onPlayerReady(event) {
    player.mute(); // 準備完了後に実行する
  }
}

うまく動かないときのチェックポイント

実装してみて動かないとき、つまずきやすいポイントをまとめました。

動画が表示されない
onYouTubeIframeAPIReady関数名が違っていないか確認してください(この名前はAPIが自動で呼ぶため固定です)。あわせて、videoIdが正しいか、プレーヤー用の<div>がJavaScriptより前に存在するかもチェックします。
自動再生されない
多くのブラウザは、音が出る状態での自動再生をブロックします。onReadyの中でplayer.mute()を呼び、ミュート状態にしてからplayer.playVideo()すると再生されやすくなります。ブロックされたかどうかはonAutoplayBlockedイベントで検知できます。
メソッドを呼ぶとエラーになる
player.playVideo()などのメソッドは、プレイヤーの準備が完了してからでないと使えません。onReadyイベントの中、またはそれ以降に呼び出してください。
「動画は所有者により埋め込みが無効…」と出る
動画側で埋め込みが許可されていないケースです(onErrorのコード101/150)。これは視聴側では解決できないため、別の動画を使う必要があります。
「エラー 153/動画プレーヤーの設定エラー」と表示される
作ったHTMLをfile://(ファイルをダブルクリックして直接開く)で表示すると、このエラーが出ることがあります。file://は特殊なオリジン扱いでリクエストにRefererが付かず、APIに拒否されるのが主な原因です(onErrorのコード153)。
Webサーバー経由(http://localhostなど)で開くと解決することが多いです。手軽に確認するなら、HTMLのあるフォルダでpython -m http.serverを実行し、http://localhost:8000/で開く方法があります。
公開後の本番URL(https://〜)では基本的に起きません。
file://で開いたときに表示されるエラー153(動画プレーヤーの設定エラー)の画面

よくある質問(FAQ)

Q. 利用にAPIキーやアカウント登録は必要ですか?

A. 不要です。IFrame Player APIはAPIキーなしで利用できます。ただしYouTubeのAPIサービス利用規約に従う必要があります。

Q. 1つのページに複数の動画を埋め込めますか?

A. できます。プレーヤーごとに別々のidを持つ<div>を用意し、それぞれnew YT.Player()でインスタンスを作成してください。

Q. スマホで画面いっぱいに表示するには?

A. 本記事の「YouTube動画をレスポンシブに埋め込む」で紹介したとおり、CSSのaspect-ratio: 16 / 9とプレーヤーのwidth: '100%'指定で、画面幅に合わせて表示できます。

まとめ

YouTube IFrame Player APIを使うと、JavaScriptだけでWebサイト上の動画を制御できます。今回のポイントは次のとおりです。

  • 空の<div>を置き、onYouTubeIframeAPIReadyの中でnew YT.Player()を実行する
  • 動作のカスタマイズはplayerVars(オプション)で行う
  • 状態の変化はevents(イベント)で受け取る
  • メソッドは準備完了後(onReady以降)に呼ぶ
  • 自動再生はミュート(player.mute())が前提onAutoplayBlockedで代替策も用意する
  • スマホ対応はaspect-ratio: 16 / 9でレスポンシブにする

オプションやメソッドの全一覧は公式リファレンスにまとまっています。本記事のサンプルを土台に、あなたのサイトにもYouTube動画の制御機能を取り入れてみてください。

この記事を書いた人
もみじのアイコン画像

もみじ

現役フリーランスWebエンジニア。フロントエンド開発を中心に、Web制作、WordPress、業務効率化ツール開発、PHPを用いた機能改修に携わってきました。社内SEとして業務ツール開発や運用保守を担当した経験もあります。

実務や学習を通じて得た知見をもとに、初心者がつまずきやすいポイントや、現場で役立つ考え方をわかりやすく発信しています。

詳しいプロフィールはこちら

-フロントエンド
-