【システムアップデートにより使用不可】GASでYouTubeのダイレクトURLを取得

#注意
著作権を守る。

#前書き
動画を取得するライブラリやソフトの仕組みが気になったので試してみた。
動画をローカルに落とすことなくGoogleDriveに直接保存できるのが利点。

#難所
解説しているサイトが少ない。
YouTubeの仕様がよく変わるらしい。

#プログラム
##スプレッドシートの準備
ダイレクトURLだけでなく動画の情報も取得する。
一行目をヘッダーにする。

```javascript
var ss = SpreadsheetApp.openById('').getSheetByName('シート1');
ss.getRange('A:Z').clear();
var header =['bitrate','clen','index','init','itag','lmt','projection_type','type','url','xtags','audio_channels','audio_sample_rate','eotf','fps','primaries','quality_label','size']
ss.getRange(1,1,1,17).setValues([header]);
```

##動画の情報を取得
動画の情報はパラメーターで渡される。
adaptive_fmts=～&までを切り取る。
パラメーターの順番はランダムなのでどこまで切り取るのか注意。
パラメーターの中にパラメーターが入っているのでデコードする必要がある。
最終的にstrには動画の情報が一次配列で入っている。

```javascript
var id = '';
var URL = 'https://www.youtube.com/get_video_info?video_id=' +id;
var str = UrlFetchApp.fetch(URL).getContentText('UTF-8');
var start = str.indexOf('adaptive_fmts=') + 14;
var end = str.indexOf('&',start);
if (end == -1) {
  str = str.slice(start);
}else{
  str = str.slice(start,end);
}
str = decodeURIComponent(str);
str = str.split(',');
```

##動画の情報を抽出
strから抽出してarrに入れていく。
e.parameter.nameやrepleceを使おうとしたが変数をどう使えばいいか分からなかったので文字列を地道に抽出した。
setValuesはarrの範囲に気を付ける必要がある。
例えばarr[0].lengthが17でarr[1].lengthが16だとエラーが出る。

```javascript
var arr = [];
for (var i = 0; i < str.length; i++) 
  arr.push([]);
  for (var j = 0; j < header.length; j++) {
    start = str[i].indexOf(header[j] + '=');
    if (start == -1) {
      arr[i][j] = '';
      continue;
    }
    start += header[j].length + 1;
    end = str[i].indexOf('&',start);
    if (end == -1) {
      arr[i][j] = str[i].slice(start);
    }else{
      arr[i][j] = str[i].slice(start,end);
    }
    arr[i][j] = decodeURIComponent(arr[i][j]);
  }
}
ss.getRange(2,1,i,17).setValues(arr);
```

##全体

```javascript
function get_video_info() {
  var ss = SpreadsheetApp.openById('').getSheetByName('シート1');
  ss.getRange('A:Z').clear();
  var header =['bitrate','clen','index','init','itag','lmt','projection_type','type','url','xtags','audio_channels','audio_sample_rate','eotf','fps','primaries','quality_label','size']
  ss.getRange(1,1,1,17).setValues([header]);
  var id = '';
  var URL = 'https://www.youtube.com/get_video_info?video_id=' +id;
  var str = UrlFetchApp.fetch(URL).getContentText('UTF-8');
  var start = str.indexOf('adaptive_fmts=') + 14;
  var end = str.indexOf('&',start);
  if (end == -1) {
    str = str.slice(start);
  }else{
    str = str.slice(start,end);
  }
  str = decodeURIComponent(str);
  str = str.split(',');
  var arr = [];
  for (var i = 0; i < str.length; i++) {
    arr.push([]);
    for (var j = 0; j < header.length; j++) {
      start = str[i].indexOf(header[j] + '=');
      if (start == -1) {
        arr[i][j] = '';
        continue;
      }
      start += header[j].length + 1;
      end = str[i].indexOf('&',start);
      if (end == -1) {
        arr[i][j] = str[i].slice(start);
      }else{
        arr[i][j] = str[i].slice(start,end);
      }
      arr[i][j] = decodeURIComponent(arr[i][j]);
    }
  }
  ss.getRange(2,1,i,17).setValues(arr);
  Logger.log(arr);
}
```

#後書き
目的は達成したが、何を表しているか分からないパラメーターがいくつかある。
adaptive_fmtsだけでなくurl_encoded_fmt_stream_mapにもダイレクトURLがあるのだが、違いが分からないので無視した。