YouTube IFrame Player API は、手元の Web サイトなどに YouTube 動画を埋め込みできる YouTube 公式のAPIです。
iframe 組み込みの YouTube Player API リファレンス
以下に Iframe Player API のサイトにあるサンプルコードを引用します。
<!DOCTYPE html> <html> <body> <!-- 1. The <iframe> (and video player) will replace this <div> tag. --> <div id="player"></div> <script> // 2. This code loads the IFrame Player API code asynchronously. var tag = document.createElement('script'); tag.src = "https://www.youtube.com/iframe_api"; var firstScriptTag = document.getElementsByTagName('script')[0]; firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); // 3. This function creates an <iframe> (and YouTube player) // after the API code downloads. var player; function onYouTubeIframeAPIReady() { player = new YT.Player('player', { height: '360', width: '640', videoId: 'M7lc1UVf-VE', events: { 'onReady': onPlayerReady, 'onStateChange': onPlayerStateChange } }); } // 4. The API will call this function when the video player is ready. function onPlayerReady(event) { event.target.playVideo(); } // 5. The API calls this function when the player's state changes. // The function indicates that when playing a video (state=1), // the player should play for six seconds and then stop. var done = false; function onPlayerStateChange(event) { if (event.data == YT.PlayerState.PLAYING && !done) { setTimeout(stopVideo, 6000); done = true; } } function stopVideo() { player.stopVideo(); } </script> </body> </html>
Iframe Player API は ESM として実装されていないので、 ESM として実装した Javascript などのコードから利用する場合にはいくらかの工夫が必要になります。
API の紹介サイトでは同 API の初期化終了後にコールバックされる onYouTubeIframeAPIReady() をグローバル名前空間で宣言していますが、これは ESM の名前空間からみれば window.onYouTubeIframeAPIReady() にあたります。また、同 API の初期化が完了すると YT が定義されますが、これは ESM の名前空間からみると window.YT になります。
この考慮点を反映して ESM としてサンプルを再実装したものが下記になります。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<body> | |
<!-- 1. The <iframe> (and video player) will replace this <div> tag. --> | |
<div id="player"></div> | |
<script type="module"> | |
// 2. This code loads the IFrame Player API code asynchronously. | |
var tag = document.createElement('script'); | |
// モジュールのインポートは従来のまま | |
tag.src = "https://www.youtube.com/iframe_api"; | |
var firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
// 3. This function creates an <iframe> (and YouTube player) | |
// after the API code downloads. | |
var player; | |
window.onYouTubeIframeAPIReady = () => { | |
player = new YT.Player('player', { | |
height: '360', | |
width: '640', | |
videoId: 'M7lc1UVf-VE', | |
events: { | |
'onReady': onPlayerReady, | |
'onStateChange': onPlayerStateChange | |
} | |
}); | |
} | |
// 4. The API will call this function when the video player is ready. | |
function onPlayerReady(event) { | |
event.target.playVideo(); | |
} | |
// 5. The API calls this function when the player's state changes. | |
// The function indicates that when playing a video (state=1), | |
// the player should play for six seconds and then stop. | |
var done = false; | |
function onPlayerStateChange(event) { | |
// YT.PlayerState は window.YT.PlayerState として参照する | |
if (event.data == window.YT.PlayerState.PLAYING && !done) { | |
setTimeout(stopVideo, 6000); | |
done = true; | |
} | |
} | |
function stopVideo() { | |
player.stopVideo(); | |
} | |
</script> | |
</body> | |
</html> |
実際には ESM として実装する場合には、クラスとして実装するケースが多いでしょう。下記の例では、埋め込んだプレイヤーからのコールバックをインスタンスのメンバ変数として実装しています。
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<body> | |
<!-- 1. The <iframe> (and video player) will replace this <div> tag. --> | |
<div id="player"></div> | |
<script type="module"> | |
// 2. This code loads the IFrame Player API code asynchronously. | |
var tag = document.createElement('script'); | |
// モジュールのインポートは従来のまま | |
tag.src = "https://www.youtube.com/iframe_api"; | |
var firstScriptTag = document.getElementsByTagName('script')[0]; | |
firstScriptTag.parentNode.insertBefore(tag, firstScriptTag); | |
class MyYouTubePlayer { | |
constructor(videoId) { | |
this.videoId = videoId | |
this.player = null | |
} | |
mount(elementId) { | |
this.player = new YT.Player('player', { | |
height: '360', | |
width: '640', | |
videoId: this.videoId, | |
events: { | |
'onReady': (event) => { this.onPlayerReady(event) }, | |
'onStateChange': (event) => { this.onPlayerStateChange(event) } | |
} | |
}); | |
} | |
// オブジェクト内に標準のイベントハンドラを埋め込んでおく | |
// 今回のクラスは動画の準備ができたら自動再生する仕様とする | |
onPlayerReady(event) { | |
console.log("onPlayerReady", event) | |
this.player.playVideo(); | |
} | |
// 未実装のイベントハンドラ | |
onPlayerStateChange(event) { | |
} | |
} | |
// 呼び出し元の実装 | |
var video; | |
var done = false; | |
// API の初期化が終わったら IFrame API Player を初期化する | |
window.onYouTubeIframeAPIReady = () => { | |
console.log("window.onYouTubeIframeAPIReady") | |
video = new MyYouTubePlayer('M7lc1UVf-VE'); | |
video.mount('player'); | |
// video.onPlayerStateChange にオーバーライドしてプレイヤーの状態変化を | |
// 捕捉する | |
video.onPlayerStateChange = (event) => { | |
console.log("onPlayerStateChange", event) | |
// YT.PlayerState は window.YT.PlayerState として参照する | |
if (event.data == window.YT.PlayerState.PLAYING && !done) { | |
setTimeout(stopVideo, 6000); | |
done = true; | |
} | |
} | |
} | |
function stopVideo() { | |
video.player.stopVideo(); | |
} | |
</script> | |
</body> | |
</html> |
※コード上は動画のロードが完了し次第自動再生するような実装になっていますが、本記事執筆時点ではそのように動作していないようです。これは API のサイトにあるオリジナルのサンプルの問題です。
0 件のコメント:
コメントを投稿