【GAS】YouTubeプレーヤーとスプレッドシートを連携させる

youtube-on-smartphone プログラミング

Iframe Player APIを使えば、WebアプリにYouTubeプレーヤーを埋め込むことができます。

APIには、読み込む動画を指定するvideoIdというプロパティがあります。これを利用することでWebアプリに、YouTubeの好きな動画を埋め込むことができます。

GASを利用すれば、スプレッドシートと簡単に連携することができます。スプレッドシートに好きな動画のvideoIdを登録しておくことで、Webアプリで動画を選択することも可能です。

今回は、GASを使って、スプレッドシートに登録しているYouTubeの動画を選択し、再生できるWebアプリを作成してみます。

Webアプリの完成形

完成したWebアプリです。

再生する動画は、次の2パターンで再生することができます。

  • videoIdをボックスに直接入力して動画再生
  • スプレッドシートに登録しているvideoIdを選択して動画再生

スプレッドシートからの選択だけでなく、videoIdを入力して再生できるようにもなっています。

YouTubeApp

スプレッドシートは、次のように入力しています。A列に動画のタイトル、B列にその動画のvideoIdを入力しています。

training-sheet

スプレッドシートの「タイトル」と「videoId」を読み込み、Webアプリのプルダウンで、再生する動画を選択できるようになります。

Webアプリは、次の4つのコードで作成しています。基本的な内容については、こちらの記事を参考にしてください。

const doGet = () => {
  return HtmlService.createTemplateFromFile('index')
      .evaluate()
      .setTitle("YouTubeリピート")
      .addMetaTag('viewport', 'width=device-width,initial-scale=1');
};

const getSpreadSheetData = () => {
  //取得するスプレッドシート
  const ss = SpreadsheetApp.openById("スプレッドシートのIDをここに入力");
  const sheet = ss.getSheetByName("シートの名前をここに入力"); 
  //スプレッドシートのデータを返す
  return sheet.getDataRange().getValues();
};
<!DOCTYPE html>
<html>
  <head>
    <base target="_top">
    <?!= HtmlService.createHtmlOutputFromFile("css").getContent(); ?>
    <meta name="viewport" content="width=device-width, intial-scale=1">
  </head>
  <body>
    <h1>youtube再生</h1>
    <div>
      <input id="search-videoId" type="text" placeholder="VideoIdを入力">
      <button id='search-play'>再生</button>
    </div>
    <div>
      <select id='select-videoId'></select>
      <button id='select-play'>再生</button>
    </div>
    <div id="player-container">
      <div id="player"></div>
    </div>
    <?!= HtmlService.createHtmlOutputFromFile("js").getContent(); ?>
  </body>
</html>
<style>
body {
  max-width: 1000px;
}

#player-container {
  position: relative;
  width: 100%;
  height: 0;
  padding-bottom: 56.25%;
  overflow: hidden;
}

#player-container iframe {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 0;
  left: 0;
}
</style>
<script src = "https://www.youtube.com/iframe_api"></script>
<script>
'use strict';
class App {
  constructor() {
    //YouTubePlayerクラスのインスタンスの作成
    this.youTubePlayer = new YouTubePlayer();
  }
  
  mount() {
    const searchPlayElement = document.getElementById("search-play");
    const searchVideoIdElement = document.getElementById("search-videoId");
    //search-playボタンを押したとき
    searchPlayElement.addEventListener("click", () => {
      //search-videoIdのプレイヤーを埋め込み
      this.youTubePlayer.setIframeAPI(searchVideoIdElement.value);
    });
    
    const selectPlayElement = document.getElementById("select-play");
    const selectVideoIdElement = document.getElementById("select-videoId");
    //search-playボタンを押したとき
    selectPlayElement.addEventListener("click", () => {
      //search-videoIdのプレイヤーを埋め込み
      this.youTubePlayer.setIframeAPI(selectVideoIdElement.value);
    });
  }
}

class YouTubePlayer {
  //プレイヤーの埋め込み
  setIframeAPI(videoId) {
    //プレイヤーがすでに埋め込まれている場合
    if(this.player) {
      //埋め込みプレイヤーを削除
      this.player.destroy();
    }
    this.player = new YT.Player("player", {
      videoId: videoId,
      events: {
        "onReady": this.playerPlay
      }
    });
  }
  
  //プレイヤーの再生
  playerPlay(event) {
    event.target.playVideo();
  }
}

//APIのJavaScriptコードが読み込まれると、APIによって呼び出される関数
function onYouTubeIframeAPIReady() {
  //サーバーサイドの関数の呼び出し戻り値を受け取る
  google.script.run.withSuccessHandler(setPlayList).getSpreadSheetData();
  const app = new App();
  app.mount();
}

//プルダウンリストの設置
const setPlayList = (items) => {
  const playList = items;
  //見出しの削除
  playList.shift();
  //select-videoIdに値を設置
  const selectVideoIdElement = document.getElementById("select-videoId");
  playList.forEach((item) => { 
    const option = document.createElement("option");
    option.text = item[0];
    option.value = item[1];
    selectVideoIdElement.appendChild(option);
  });
};
</script>

コード解説

スプレッドシートのデータ取得

コード.gsの次のコードで、スプレッドシートのデータを取得しています。

const getSpreadSheetData = () => {
  //取得するスプレッドシート
  const ss = SpreadsheetApp.openById("スプレッドシートのIDをここに入力");
  const sheet = ss.getSheetByName("シートの名前をここに入力"); 
  //スプレッドシートのデータを返す
  return sheet.getDataRange().getValues();
};

スプレッドシートと連携するために、スプレッドシートのIDとシート名を指定しています。こちらの記事を参考にしてください。

取得したデータは2次元配列で返されます。この配列に、YouTubeの動画タイトルとvideoIdが格納されます。

YouTubePlayerクラス

class YouTubePlayer {
  //プレイヤーの埋め込み
  setIframeAPI(videoId) {
    //プレイヤーがすでに埋め込まれている場合
    if(this.player) {
      //埋め込みプレイヤーを削除
      this.player.destroy();
    }
    this.player = new YT.Player("player", {
      videoId: videoId,
      events: {
        "onReady": this.playerPlay
      }
    });
  }
  
  //プレイヤーの再生
  playerPlay(event) {
    event.target.playVideo();
  }
}

YouTubeを埋め込むためのIFrame Player APIを使用するクラスです。IFrame Player APIについてはこちらの記事を参考にしてください。

ボタンを押されたときに動作するAppクラスのmountメソッド

アプリのボタンを押されたときに動作するのが次のコードです。

  mount() {
    const searchPlayElement = document.getElementById("search-play");
    const searchVideoIdElement = document.getElementById("search-videoId");
    //search-playボタンを押したとき
    searchPlayElement.addEventListener("click", () => {
      //search-videoIdのプレイヤーを埋め込み
      this.youTubePlayer.setIframeAPI(searchVideoIdElement.value);
    });
    
    const selectPlayElement = document.getElementById("select-play");
    const selectVideoIdElement = document.getElementById("select-videoId");
    //search-playボタンを押したとき
    selectPlayElement.addEventListener("click", () => {
      //search-videoIdのプレイヤーを埋め込み
      this.youTubePlayer.setIframeAPI(selectVideoIdElement.value);
    });
  }

addEventListenerでクリックを検知して、YouTubePlayerクラスのsetIframeAPIメソッドを実行しています。その際に、入力ボックス、プルダウンの選択のvideoIDを引数として渡しています。

サーバーサイドの関数を呼び出す

サーバーサイドのコード.gsの関数を呼び出すのが「google.script.run.withSuccessHandler(function)」です。サーバーサイドの関数が正常に実行された場合、指定した関数が実行されます。

//サーバーサイドの関数の呼び出し戻り値を受け取る
google.script.run.withSuccessHandler(setPlayList).getSpreadSheetData();

この場合、サーバサイドのgetSpreadSheetData()を実行し、正常に実行された場合、setPlayList()が実行されます。

サーバーサイドの関数の戻り値は、指定した関数の引数として受け取ることができます。

この場合、スプレッドシートのタイトルとvideoIdの2次元配列を引数として受け取っています。

スプレッドシートの値をプルダウンに設定する

スプレッドシートの値を、プルダウンに設定するのが関数式setPlayListです。

getSpreadSheetData()で取得した2次元配列を引数として受け取ります。

引数として受け取る、2次元配列は次のようになります。

[
  ["タイトル", "videoId"],
  ["プッシュアップチャレンジ", "41N6bKO-NVI"],
  ["腹筋トレーニング", "Ftl1zKQv2nQ"],
  ["7分HIIT", "nJXmwILZmg0"],
  ["5分だけ一緒に筋トレしよう!~脚編~", "WYPr1b2tkuo"],
  ["5分だけ一緒に筋トレしよう!~力こぶ・上腕二頭筋編~", "j2kyXy5R39c"],
  ["5分だけ一緒に筋トレしよう!~肩・三角筋~", "HAuSBCH0gR0"],
  ["5分だけ一緒に筋トレしよう!~胸・大胸筋編~", "FVas15wkIq0"]
]

タイトル行も配列に含まれているので、これを削除します。

//見出しの削除
playList.shift();

shiftメソッドは配列の0番目の要素を取り除きます。取り除いた要素は戻り値として返されます。

const array = [0,1,2,3];
const shifted = array.shift();
console.log(array);   //[1,2,3]
console.log(shifted); //0

実際にプルダウンに設定するのが次のコードです。

playList.forEach((item) => { 
    const option = document.createElement("option");
    option.text = item[0];
    option.value = item[1];
    selectVideoIdElement.appendChild(option);
  });

forEach()は、配列の要素ごとに関数を実行します。itemには、playListに格納されている2次元配列が1つずつ入ります。

まず、item = [“プッシュアップチャレンジ”, “41N6bKO-NVI”]で関数が実行されます。

次は、item = [“腹筋トレーニング”, “Ftl1zKQv2nQ”]で関数が実行され、同様にすべての要素に対して関数が実行されます。

実行される関数については、HTMLのselect要素に、option要素を追加しています。textにタイトル、valueにvideoIdを設定しています。 

タイトルとURLをコピーしました