【Google Apps Script】Youtube動画の公開/非公開を切り替える

最近知ったのですが、Google Apps Scriptというのがあって、Googleドライブ上に作成したドキュメントやGoogleの各サービスをjavaScriptペースでハンドリングできるらしい。

【参考】
ASCII.jp:Web制作をちょっと便利にするGoogle Apps Script入門

※わかりやすいですが、ちょっと古い記事なのでメニューの場所などが現在のものと違っていたりします。

ちょうど必要があって、Youtube動画の公開/非公開を切り替えるスクリプトを考えてみました。

まず近そうなもので参考にしたのはこの辺。

【参考】
GoogleAppsScript – 公開されたGASのYouTubeAPIを少し使ってみた。 – Qiita
GoogleAppsScript – GASでYouTubeの自分の再生リストを全て非公開にする。 – Qiita

※参考ページにもありますが、YoutubeのAPIは拡張サービスという位置付けで、YouTube Data APIの有効化と承認が必要になります。

基本的にはYoutube Data APIをそのままJavaScriptの書式で書けばいいということなんですが、リストの取り方が・・・

Channels(チャンネル)
Playlists(再生リスト)
PlaylistItems(再生リストの項目)
Videos(動画)

といくつかあって、公開/非公開の切替は動画IDが必要になるのだけれど、確認した限りでは動画IDを含んだ結果を返すものは、

・PlaylistItems(再生リストの項目)
・Videos(動画)

の2つみたいです。

ただPlaylistItems(再生リストの項目)でのリスト取得も、Videos(動画)でのリスト取得もidまたはplaylistidが必要になります。Playlistは必ず作成するとは限らないし、Channels(チャンネル)から辿っていくのも大変そうだしと思ってAPIを見ていたら、Search(検索)のリスト取得に「forMine」という自分のIDに紐付いたものだけを検索するフィルタがあったので、これを使うことにしました。

とりあえず自分のIDに紐付いた動画idを取得して、スプレッドシートに書き出すのはこんな感じ。

//---自分のvideoを検索する
function searchMyVideos() {
  var nextToken = "";
  var arrayId = [];
  while(nextToken != null) {
    var res = YouTube.Search.list('id,snippet', 
                                     {maxResults: 50,
                                      forMine: true,
                                      order: "date",
                                      type: "video",
                                      pageToken: nextToken});
    
    for(var i = 0; i < res.items.length; i++) {
      var item = res.items[i];
       arrayId.push(item.id.videoId);
    }

    nextToken = (res.nextPageToken == "") ? null :res.nextPageToken;
  }
  
  if (arrayId.length > 0){
    getMyVideoList(arrayId);
  }
 
  Browser.msgBox("動画一覧を取得しました。");
}

//---videoの詳細情報を取得
function getMyVideoList(arrayId) {
  var nextToken = "";
  var id = String(arrayId);
  var arrayStatus = [];
  
  var sheetId = '**********************************';
  var spreadsheet = SpreadsheetApp.openById(sheetId);
  var newsheet = SpreadsheetApp.openById(sheetId).getSheetByName('動画リスト');
  newsheet.getRange(1, 1).setValue('id');
  newsheet.getRange(1, 2).setValue('タイトル');
  newsheet.getRange(1, 3).setValue('作成日');
  newsheet.getRange(1, 4).setValue('公開/非公開/限定公開');
  
  var count = 2;
  
  while(nextToken != null) {
    var playlistResponse = YouTube.Videos.list('snippet, status',{id:id});

    for(var i = 0; i < playlistResponse.items.length; i++) {
      var item = playlistResponse.items[i];
);
      
      arrayStatus.push(item.snippet.title + ";" + item.status.privacyStatus);
      
      newsheet.getRange(count, 1).setValue(item.id);
      newsheet.getRange(count, 2).setValue(item.snippet.title);
      newsheet.getRange(count, 3).setValue(item.snippet.publishedAt);
      newsheet.getRange(count, 4).setValue(item.status.privacyStatus);
      count++;
    }

    nextToken = playlistResponse.nextPageToken;

  }
}

検索で取得できるリストの項目数は最大50件で、続きがある場合は「nextPageToken」に何かしらの値が入ってくるようなので、値がある場合は処理を繰り返しています。で、リストを取得するごとに配列(arrayId)に動画id(item.id.videoId)を保存しておいて、検索が終わったらまとめてスプレッドシートに書き出しています。

また「var sheetId = ‘**********************************’;」にはスプレッドシートのidを指定するのですが、これは・・・

function checkId(){
  Logger.log(SpreadsheetApp.getActiveSpreadsheet().getId());
}

を実行してログの出力結果から取得するか、スプレッドシートのURLの・・・

https://docs.google.com/spreadsheets/d/**********/edit#gid=xxxxxxxx

「**********」の部分から取得できます。この例だと「**********」というidのスプレッドシートの「動画リスト」という名前のタブのシートを指定していることになります。

続いて、動画を全部非公開にするのはこんな感じ。

//---自分のvideoを非公開にする
function setPrivateMyVideos() {
  var nextToken = "";
  var arrayId = [];
  while(nextToken != null) {
    var res = YouTube.Search.list('id,snippet', 
                                     {maxResults: 50,
                                      forMine: true,
                                      order: "date",
                                      type: "video",
                                      pageToken: nextToken});
    
    for(var i = 0; i < res.items.length; i++) {
      var item = res.items[i];
       arrayId.push(item.id.videoId);
    }

    nextToken = (res.nextPageToken == "") ? null :res.nextPageToken;
  }
  
  if (arrayId.length > 0){
    updatePrivacyStatus_private(arrayId);
  }
  Browser.msgBox("全ての動画を非公開にしました。");
}

//---VideoのprivacyStatusをprivateに変更する
function updatePrivacyStatus_private(arrayId) {
  var nextToken = "";
  var id = String(arrayId);
  while(nextToken != null) {
    var playlistResponse = YouTube.Videos.list('snippet, status',{id:id});

    for(var i = 0; i < playlistResponse.items.length; i++) {
      var item = playlistResponse.items[i];
      if(item.status.privacyStatus != "private") {
        item.status.privacyStatus = "private";
        var updateRes = YouTube.Videos.update(item, "status,snippet");
      }

    }

    nextToken = playlistResponse.nextPageToken;

  }
}

スプレッドシートに書き出す代わりに、ステータス(item.status.privacyStatus)が非公開(private)でないものを非公開に更新しています。

最後に全て公開するにはこうします。

//---自分のvideoを公開する
function setPublicMyVideos() {
  var nextToken = "";
  var arrayId = [];
  while(nextToken != null) {
    var res = YouTube.Search.list('id,snippet', 
                                     {maxResults: 50,
                                      forMine: true,
                                      order: "date",
                                      type: "video",
                                      pageToken: nextToken});
    
    for(var i = 0; i < res.items.length; i++) {
      var item = res.items[i];
       arrayId.push(item.id.videoId);
    }

    nextToken = (res.nextPageToken == "") ? null :res.nextPageToken;
  }
  
  if (arrayId.length > 0){
    updatePrivacyStatus_public(arrayId);
  }
  Browser.msgBox("全ての動画を公開しました。");
}

//---VideoのprivacyStatusをpublicに変更する
function updatePrivacyStatus_public(arrayId) {
  var nextToken = "";
  var id = String(arrayId);
  while(nextToken != null) {
    var playlistResponse = YouTube.Videos.list('snippet, status',{id:id});

    for(var i = 0; i < playlistResponse.items.length; i++) {
      var item = playlistResponse.items[i];

      if(item.status.privacyStatus != "public") {
        item.status.privacyStatus = "public";
        var updateRes = YouTube.Videos.update(item, "status,snippet");
      }

    }

    nextToken = playlistResponse.nextPageToken;

  }
}

こちらではステータス(item.status.privacyStatus)が公開(public)でないものを公開に更新しています。

ちなみに処理が終わったのを確認するために「Browser.msgBox();」でポップアップを表示しているのですが、これを処理の途中で挟むと、処理が途中までしか実行されないということがありました。原因はよくわからないですが、あくまで確認用ということで余り使わない方がいいかも。

それからログ書きだし(Logger.log())はAPIの呼び出しごとにリセットされるようで、スクリプトエディタの表示>ログで確認しても最後のAPIの分しか書き出されていません。ASのtrace()やJSのconsole.log()のイメージで使うには、一回変数に入れてから最後に書き出すしかなさそうです。

「【Google Apps Script】Youtube動画の公開/非公開を切り替える」への6件のフィードバック

  1. 非公開のユーザー指定は、GASで出来るんでしょうか?

  2. ご回答ありがとうございました。
    やはり、という答えで少し安心しました、変な話ですが。

  3. ご無沙汰しています。
    以前、質問させていただいた者です。今回は別件で質問させていただきたく再度投稿させていただきます。

    【質問】
    スプレッドシート上に、「自分のYouTube動画のID」がリスト化されており、それを利用して、YouTubeの動画タイトルを更新したいのですが、そういう事は可能でしょうか?もし可能なら、どうGASで書けばよいでしょうか?

    YouTube data APIのVideos、updataで実現できそうという事は何となく感じているのですが、中々、参考にできる情報がありませんで。ド素人なので、リファレンスだけではコード入力まではいたらず困っている状況です。
    何かアドバイスを頂けたら大変たすかります。

  4. 上記の「YouTube data APIでのVideos、updata」、色んな方のコードを参考にしていたらうまくいきました!!
    ありがとうございました!!

コメントは停止中です。