Youtubeの動画をバッチダウンロードし、S3にアップロードする方法

## はじめに
Youtubeの動画を、アーカイブ目的でまとめてバッチダウンロード。  
ついでにS3のバケットにアップロードをしたかった。
どうせ、後で氷漬け（glacier漬け）する目的なので、これで十分だろう。

## ポイント
ローカルのストレージを使用していないこと。
仕組みとして、youtube-dlでダウンロードされたものを、パイプでaws cliに渡し、そのままS3バケットにアップロードしている。

## 前提条件
- Ubuntu 18.04LTS
- youtube-dlのインストールとアップデート
- aws s3でバケットを作成済み
- awscliのインストールとセットアップ

今回、youtube-dlは、以下のバージョンを使用した
```
% youtube-dl --version
2020.06.06
```

## 実際のコード
```
#!/bin/bash
LIST_URL="./dl.url.list"
S3_BUCKET="mylist-douga"

while read URL
do
  # fetch
  FORMAT=`youtube-dl -F ${URL} | grep '(best)'`
  CODE=`echo "${FORMAT}" | awk -F' ' '{print $1}'`
  EXT=`echo "${FORMAT}" | awk -F' ' '{print $2}'`
  TITLE=`youtube-dl --get-title ${URL}`

  # download and upload s3
  youtube-dl -f ${CODE} -o - ${URL} | aws s3 cp - "s3://${S3_BUCKET}/${TITLE}.${EXT}"

  # sleep
  sleep 10
done << _EOL
`cat ${LIST_URL}`
_EOL
```

## 実行
自分は`screen`でバックグラウンドで動かして放置しているが、そこは好きにして欲しい。

## 解説

### コーデックについて
`fetch`の部分で、Youtubeより以下のデータを取得している
- 最適なフォーマット、及び拡張子
- 動画のタイトル

`youtube-dl -F ${URL}`では、以下のような出力を得られる
`(best)`を含むものが目的のフォーマットで、
１カラム目がフォーマットのコード、２カラム目が拡張子である。

Youtubeは、アップロードの際に内部的に複数のエンコードで再エンコードしており、プレイヤーに応じて出し分けをしているようだ。
「audio only」「video only」といったものも存在する事が興味深い。

```
format code  extension  resolution note
139          m4a        audio only DASH audio   52k , m4a_dash container, mp4a.40.5@ 48k (22050Hz)
251          webm       audio only DASH audio  121k , webm_dash container, opus @160k (48000Hz)
140          m4a        audio only DASH audio  133k , m4a_dash container, mp4a.40.2@128k (44100Hz)
278          webm       256x144    DASH video   95k , webm_dash container, vp9, 30fps, video only
160          mp4        256x144    DASH video  108k , mp4_dash container, avc1.4d400b, 30fps, video only
242          webm       426x240    DASH video  220k , webm_dash container, vp9, 30fps, video only
134          mp4        640x360    DASH video  239k , mp4_dash container, avc1.4d401e, 30fps, video only
133          mp4        426x240    DASH video  242k , mp4_dash container, avc1.4d400c, 30fps, video only
243          webm       640x360    DASH video  405k , webm_dash container, vp9, 30fps, video only
244          webm       854x480    DASH video  752k , webm_dash container, vp9, 30fps, video only
135          mp4        854x480    DASH video 1155k , mp4_dash container, avc1.4d4014, 30fps, video only
137          mp4        1920x1080  DASH video 1333k , mp4_dash container, avc1.640028, 30fps, video only
247          webm       1280x720   DASH video 1505k , webm_dash container, vp9, 30fps, video only
136          mp4        1280x720   DASH video 2310k , mp4_dash container, avc1.4d4016, 30fps, video only
248          webm       1920x1080  DASH video 2646k , webm_dash container, vp9, 30fps, video only
18           mp4        640x360    360p  305k , avc1.42001E, 30fps, mp4a.40.2@ 96k (44100Hz), 120.43MiB
22           mp4        1280x720   720p  429k , avc1.64001F, 30fps, mp4a.40.2@192k (44100Hz) (best)
```

### 動画タイトルの取得
動画のタイトルそのものは、以下にて取得可能である。
``youtube-dl --get-title ${URL}``

### S3へのアップロード
`aws s3 cp`は、コピー元をパイプから渡す事も可能である。
今回、以下のコードを使い、パイプにより動画ファイルを流し込み、コピー先にてオブジェクト名（ファイル名）を指定する形とした。

```
aws s3 cp - s3://${S3_BUCKET}/${TITLE}.${EXT}
```

今回は、`youtube-dl -o - `を渡す形としたが、パイプで渡せられれば正直なんでもいいので、応用の余地は広いのかも知れない。