ラズパイでYouTube APIを使ってライブ配信を行う 

# 概要

ラズパイからYouTube Liveを利用してライブ配信をします

ライブのたびに [YouTube Studio](https://studio.youtube.com) の操作が必要になる紹介記事が多いのですが
本記事では [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) を利用して、ライブの準備、配信、アーカイブをおこないます

前半は YouTube API (= Google API) を利用できるようになるまで
具体的には [Google Cloud Console](https://console.developers.google.com) で **プロジェクト** を作成するところから
APIへのアクセスに必要な **ACCESS TOKEN** を入手するところまで

後半は [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) を利用して
**ライブの準備、配信、アーカイブを行う**手順

を紹介します。

補足的に必要な知識として
* ffmpegによるストリーミング
* YouTube Live Streaming API における Broadcasts と Streams の概念とライフサイクル

の話も紹介します

# 目次

## 前半 : YouTube API を利用できるように準備する

前半はラズパイもコーディングも不要です
**太字**はこれから作るものの固有名詞です
とりあえず「あー、そういうものを作るのね」と思っておいてください
APIにアクセスするためのゴールは **ACCESS TOKEN** なのですが、**REFRESH TOKEN** さえあれば何度でも生成できます

1. [前半-1] **プロジェクト**を作成する
1. [前半-2] YouTube Data APIを有効にする
1. [前半-3] **認証情報**を作成する
1. [前半-4] **OAuth同意画面**を作成する
1. [前半-5] OAuthを実行して **code** を入手する
1. [前半-6] **REFRESH TOKEN**を入手する
1. [前半-7] **ACCESS TOKEN**を入手する

## 後半 : YouTube Live Streaming API を利用してライブ配信する

1. [後半-1] まず [YouTube Studio](https://studio.youtube.com) を使ってラズパイからライブ配信をしてみる (ffmpegによるストリーミング)
1. [後半-2] (座学) [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) における **Broadcasts** と **Streams** の概念とライフサイクル (飛ばしてもよい)
1. [後半-3] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする① (準備)
1. [後半-4] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする② (配信)
1. [後半-5] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする② (終了、アーカイブ)

目次を見るだけでも「うへ～、ながっ」と思うかもしれませんが
一つ一つ進めていけば大丈夫です
途中で **REFRESH_TOKEN** が手に入るのですが、
そうすれば [Google Cloud Console]() での煩雑な作業も不要になるので頑張りましょう

# 手順

## 前半

### 1. [前半-1] **プロジェクト**を作成する

ブラウザで [Google Cloud Console](https://console.cloud.google.com/) を開きます
自分のアカウントでログインしている状態になると思いますが、
そうでない場合は Googleアカウントを作成して、ログインしてください。

左上のプロジェクト名(自分の例では`Sidecar`)が表示されているドロップダウンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/54828502-f996-d7a9-cd8b-6271bb9a266c.png)
プロジェクトの選択ダイアログが表示されるので、右上の「新しいプロジェクト」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/696b92b2-816a-3d44-423d-ad987f802dc3.png)
プロジェクト名を適当につけて「作成」
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/e607cb77-a4a6-4252-7ae3-49018b4b9528.png)
しばらく待つと「プロジェクト XXXXX を作成」という通知がきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/03285238-9cfe-dda5-a953-54bce767d67f.png)

### 2. [前半-2] YouTube Data APIを有効にする

通知の「プロジェクトを選択」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/53b7d477-565a-3bc0-8c7f-e1af2722fb95.png)
プロジェクトが選択された状態になるので、左側のペインから「APIとサービス」>「有効なAPIとサービス」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/5194d727-dbdd-b29d-e2f6-49cc6623000e.png)
「＋APIとサービスの有効化」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/f0c1f6e8-29d7-31b3-632c-06db12d168a7.png)
「YouTube Data API v3」を選択します。Streaming APIもこの中に入っています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/56764ff0-8d82-1bee-4a30-8d99859b9e2d.png)
「有効にする」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/77a905a6-0b66-1346-a179-975d67d067d8.png)
API/サービスの詳細の画面に戻って、画面右上に「認証情報を作成する」と出るので、それをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/334c92be-80e0-cd82-b323-2fccc37c87c5.png)
※ なお、最後のステップで「認証情報を作成する」を押さずに画面を変えてしまった場合でも、
※ 同じ情報は、左のペインの「認証情報」「OAuth同意画面」から入力できます
※ 画面遷移などは多少違いますが、大丈夫です

### 3. [前半-3] **認証情報**を作成する

まえの手順で「認証情報を作成する」を押すと「認証情報の作成」ウィザードが立ち上がります。

① 認証情報の種類 ではユーザデータを選択します。「次へ」で次のステップへ
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/20c551c9-5b2a-d7b6-f80b-16f52810f24b.png)
② OAuth同意画面では、適当にアプリ名をつけます
ユーザーサポートメール、メールアドレスには自分のgmailのメールアドレスを入れておきます
※ 届くメールアドレスならば何でも大丈夫です
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/331dfdee-7295-a069-90cc-5de85f0c4290.png)
③ スコープでは「スコープを追加または削除」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/39399eae-98ef-532c-e659-0819be6ed2bf.png)
すると「選択したスコープの更新」ダイアログが表示されます
フィルタに `YouTube` と入力すると補完されるので `YouTube Data API v3` を選択
下のリストから
* `.../auth/youtube`
* `.../auth/youtube.force-ssl`
* `.../auth/youtube.upload`

を選択します
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/cb499387-a654-927e-ba0d-829836646536.png)
④ OAuthクライアントIDではアプリケーションの種類で「デスクトップアプリ」を選び、名前は適当につけます
「作成」をクリックすると、認証情報が作成されます
すこしだけ時間がかかります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/5e635ba4-d7f3-a8b7-2aac-a49e8f211198.png)
⑤ 認証情報画面では作成された認証情報が確認できます
「ダウンロード」を押すとjsonファイルが取得できるので、適当な場所に保存しておきます
jsonファイルの中の **client_id** と **client_secret** が後々必要な情報となります
また **redirect_uris** は ``http://localhost`` になっていると思います
一応覚えておきましょう
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/95af8c99-9ff1-591b-4a80-cfabb8244570.png)
ダウンロードされたjsonにはこんな情報が含まれています。ご参考まで
```json
{
    "installed":{
        "client_id":"xxxxx.apps.googleusercontent.com",
        "project_id":"test-project-for-qiita",
        "auth_uri":"https://accounts.google.com/o/oauth2/auth",
        "token_uri":"https://oauth2.googleapis.com/token",
        "auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs",
        "client_secret":"xxxxx",
        "redirect_uris":["http://localhost"]
    }
}
```

### 4. [前半-4] **OAuth同意画面**を作成する

左のペインの「OAuth同意画面」をクリックし「アプリを編集」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/90a00542-4a10-f347-4174-790330a23561.png)
いくつかステップがありますが、「保存して次へ」を押して **③テストユーザー** まで行きます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/1f73927d-5595-0af4-4f0b-cae992d71a1a.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/bf400f1e-1dc6-642c-1dd1-e04d4810998f.png)
「+ ADD USERS」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/5ea4c35a-fc1b-df39-f5c4-c017ee0ffd77.png)
「ユーザを追加」ダイアログで自分のgmailのメールアドレスを追加しておきます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/c8bfc579-5523-a466-315b-d80d2c65fdd6.png)
「保存して次へ」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/9daca27c-7cd0-682c-9b04-0cd5c2701c8a.png)
最後に確認画面が表示されるので「ダッシュボードに戻る」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/3bb5a09a-a393-ae26-673e-cab1d2dbf2f3.png)

これで、OAuthを実行して **code** を入手する準備が整いました
[Google Cloud Console](https://console.cloud.google.com/)を利用するのはここまでになります

次の手順以降、各種KEYやIDをコピーペーストで入力していきますので、
もしテキストファイルなどにコピペしていない場合は、コンソールは開きっぱなしがいいと思います

### 5. [前半-5] OAuthを実行して **code** を入手する

ブラウザでOAuthを実行します
OAuth完了時にリダイレクトされたURLの一部に **code** が記載されているのでそれを回収します

まずURLを作ります
書式は
```shell
https://accounts.google.com/o/oauth2/v2/auth? \
    scope={ スコープ }&
    access_type=offline&
    include_granted_scope=true&
    response_tuype=code&
    redirect_url={ リダイレクト先のURL }&
    client_id={ Client ID }
```
です
スコープもリダイレクト先のURLも [Google Cloud Console](https://console.cloud.google.com/) で設定した値を使うので
URLは以下になります
```shell
https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/youtube%20https://www.googleapis.com/auth/youtube.force-ssl&access_type=offline&include_granted_scope=true&response_type=code&redirect_uri=http://localhost&client_id={ Client ID を入力 } となります
```
上記URLをブラウザで開くと、OAuthが始まります
まずはアカウントの選択
自分のアドレス(xxxx@gmail.com)をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/fa2fcbc1-21ab-86f3-bd27-c32ec01a759e.png)
「続行」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/27e030cf-3f96-3183-f98e-9819f23c553b.png)
二つのチェックボックスの両方にチェックを入れて「続行」をクリック
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/274f01ea-388e-8795-db47-0965081044f2.png)
リダイレクトURLで指定したアドレスを開こうとして **Not Found** になります
これは **期待動作(想定通り)** なのでご安心ください
ブラウザに表示されているURLをコピペしてテキストエディタなどにはりつけます
`code=` と `&scope=` の間の文字列が **code** になります
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/25f24b45-e10f-4844-e326-d7c138c4d33d.png)
※ ちょうど黄緑色で塗りつぶしたところに **code** が入っています

### 6. [前半-6] **REFRESH TOKEN**を入手する

ここからは `curl` コマンドを利用して、Google APIにアクセスします

**Client ID**
**Client Secret**
**code**
の3つの情報を利用して、以下のように `curl` コマンドを実行します

```shell
$ curl -d client_id={ Client ID を入力 } -d client_secret={ Client Secret を入力 } -d redirect_uri=http://localhost -d grant_type=authorization_code -d code={ codeを入力 } https://accounts.google.com/o/oauth2/token
```
googleからjsonが返ってきます
このjsonのなかに **refresh_token** が含まれています
**絶対なくさないように**メモして保存しておきましょう
これからずっと使います
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/0d86b13d-4fcf-db4d-78f8-790cdecac1fd.png)
```shell
pi@raspberrypi:~ $ curl -d client_id=XXXXX.apps.googleusercontent.com -d client_secret=XXXXX -d redirect_uri=http://localhost -d grant_type=authorization_code -d code=XXXXX https://accounts.google.com/o/oauth2/token
{
  "access_token": "XXXXX",
  "expires_in": 3599,
  "refresh_token": "XXXXX",
  "scope": "https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtube",
  "token_type": "Bearer"
}
```
じつはお気づきのかたもいるかとは思いますが、
このjsonには **access_token** も含まれています
もちろん使えます
ただ、次の行に `"expres_in": 3599` とあるように、約1時間で有効期限が切れて使えなくなります
その時には次の手順で再度新しい **access_token** を発行します

### 7. [前半-7] **ACCESS TOKEN**を入手する

**Client ID**
**Client Secret**
**REFRESH TOKEN**
の3つの情報を利用して、以下のように `curl` コマンドを実行します

```shell
curl -d refresh_token={ REFRESH_TOKEN を入力 } -d client_id={ Client ID を入力 } -d client_secret={ 
 Client Secret を入力 } -d grant_type=refresh_token https://www.googleapis.com/oauth2/v4/token
```
googleからjsonが返ってきます
このjsonのなかに **access_token** が含まれています
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/d5ee7003-1d7a-120a-b2c2-76387172c4ef.png)
```shell
pi@raspberrypi:~ $ curl -d client_id=XXXXX.apps.googleusercontent.com -d client_secret=XXXXX -d grant_type=refresh_token https://www.googleapis.com/oauth2/v4/token
{
  "access_token": "XXXXX",
  "expires_in": 3599,
  "scope": "https://www.googleapis.com/auth/youtube.force-ssl https://www.googleapis.com/auth/youtube",
  "token_type": "Bearer"
}
```
**refresh_token** から取得した **access_token** も約1時間の有効期限付きです
Expireしたら再度同じ操作で **access_token** を取得してください

ここまでで前半の終了です
お疲れさまでした

## 後半

### 1. [後半-1] まず [YouTube Studio](https://studio.youtube.com) を使ってラズパイからライブ配信をしてみる (ffmpegによるストリーミング)

まずは [YouTube Studio](https://studio.youtube.com/) でライブ配信イベントを手動で作成して
ラズパイからライブ配信を行ってみます
[YouTube](https://www.youtube.com/)側がライブ配信を受け入れられるときに、ラズパイ側がきちんと送出できるかの確認です

まずブラウザで
[YouTube](https://www.youtube.com/) のサイトに行き
画面右上の自分のアイコンをクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/b3af0760-5036-fe13-4543-5d6acff2ad86.png)
表示されるドロップダウンから [YouTube Studio](https://studio.youtube.com/) をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/cf9a0bf8-9ed6-4642-e3ed-2b511e6fb671.png)
[YouTube Studio](https://studio.youtube.com/) の画面の右上の「作成」をクリックし
表示されたドロップダウンの「ライブ配信を開始」をクリックします
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/3a8515c4-0786-7471-524f-7084b3e1bc62.png)
ライブ配信画面で **ストリームキー** と **ストリームURL** をコピーします
(右のコピーボタンを押してテキストエディタなどに張り付けておきましょう)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/67fc6954-b4a0-3fd1-ca5a-e79166084228.png)

**ここからはラズパイでの操作になります**

[ffmpeg](https://ffmpeg.org/)をインストールします
```shell
$ sudo apt-get install ffmpeg
```

[YouTube](https://www.youtube.com/)への配信の際
音が必ず必要になります
今回マイクデバイスを用意しなかったので、無音MP3を代わりに流すことにします
(お気に入りのMP3があればそれを使っても構いません。ただし著作権にはご注意を...)

[no_sound-1.mp3](https://log.mkuriki.com/wp-content/uploads/2022/01/no_sound-1.mp3) ※右クリックして「名前を付けて保存」してください
※ [クリキのキロク](https://log.mkuriki.com/)様に感謝

ラズパイのコマンドラインからダウンロードしたい場合は curl でダウンロードしましょう
```shell
$ curl https://log.mkuriki.com/wp-content/uploads/2022/01/no_sound-1.mp3 --output no_sound-1.mp3
```

次にラズパイに接続されているカメラデバイスを検索します
`$ v4l2-ctl` コマンドを利用します
`mmal service 16.1 (platform:bcm2835-v4l2-0)` がラズパイカメラです
今回はこれを使います。よってデバイス名は `/dev/video0` です

余談ですが、一番下の `UVC Camera (534d:2109): USV Vid (usb-3f980000.usb-1.5):` は
ラズパイに取り付けた HDMI-USB キャプチャです
このようにUVCデバイスを認識してくれるので、WebカメラやHDMI出力できるカメラから
ストリーミングするのも簡単です (すごいなラズパイ)
```shell
pi@raspberrypi:~ $ v4l2-ctl --list-devices
bcm2835-codec-decode (platform:bcm2835-codec):
        /dev/video10
        /dev/video11
        /dev/video12
        /dev/video18

bcm2835-isp (platform:bcm2835-isp):
        /dev/video13
        /dev/video14
        /dev/video15
        /dev/video16

mmal service 16.1 (platform:bcm2835-v4l2-0):
        /dev/video0

UVC Camera (534d:2109): USB Vid (usb-3f980000.usb-1.5):
        /dev/video1
        /dev/video2
```

ちなみに...
ラズパイカメラはコーデックも積んでいます
`/dev/video0` (= `-d 0`) のフォーマットリストを見ると `H264` があります
今回は`ffmpeg`でエンコードする代わりに、これを使おうと思います
```shell
pi@raspberrypi:~ $ v4l2-ctl -d 0 --list-formats
ioctl: VIDIOC_ENUM_FMT
        Type: Video Capture

        [0]: 'YU12' (Planar YUV 4:2:0)
        [1]: 'YUYV' (YUYV 4:2:2)
        [2]: 'RGB3' (24-bit RGB 8-8-8)
        [3]: 'JPEG' (JFIF JPEG, compressed)
        [4]: 'H264' (H.264, compressed)
        [5]: 'MJPG' (Motion-JPEG, compressed)
        [6]: 'YVYU' (YVYU 4:2:2)
        [7]: 'VYUY' (VYUY 4:2:2)
        [8]: 'UYVY' (UYVY 4:2:2)
        [9]: 'NV12' (Y/CbCr 4:2:0)
        [10]: 'BGR3' (24-bit BGR 8-8-8)
        [11]: 'YV12' (Planar YVU 4:2:0)
        [12]: 'NV21' (Y/CrCb 4:2:0)
        [13]: 'RX24' (32-bit XBGR 8-8-8-8)
```

ライブ配信用コマンドラインです
これでライブ配信できます
ストリームURL / ストリームキー に [YouTube Studio](https://studio.youtube.com/) から取得した値を入れてください
```shell
$ raspivid -w 1920 -h 1080 -fps 30 -o - -t 0 -b 2500000 | ffmpeg -re -stream_loop -1 -i no_sound-1.mp3 -f h264 -i - -c:v copy -f flv rtmp://{ ストリームURLを入れる }/{ ストリームキーを入れる }
```
上記コマンドを実行して、しばらく(1分ほど、場合による)待っていると
[YouTube Studio](https://studio.youtube.com/) でラズパイから送出されたライブ映像が確認できます

ライブ配信、すごく簡単ですね...

### 2. [後半-2] (座学) [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) における **Broadcasts** と **Streams** の概念とライフサイクル (飛ばしてもよい)

ここでは座学ということで
[YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) の **Broadcasts** と **Streams** がどういう概念なのかを
かるーく説明します

**Broadcasts** は、[YouTube](https://www.youtube.com) の「番組」にあたるものです
放送前だったり、ライブ放送中だったり、ライブ後にアーカイブされた状態だったりと
いくつかの状態を持ちます
**Broadcasts** には、それぞれIDがつきます。
これは [YouTube](https://www.youtube.com) を使っている方ならおなじみのID(文字列)で
`https://www.youtube.com/watch?v=fEvM-OUbaKs` など
いわゆる **YouTube URL** の `fEvM-OUbaKs` の部分になります

**Streams** は、ラズパイなどのストリーミング送出機器に対する「ストリーム受信窓口」です
ストリームURLとストリームKEYが設定され
RTMP(RTMPS)の送出先URLになります
ffmpegやOBSなどでは、このストリームURLとストリームKEYを送出先として設定して
[YouTube](https://www.youtube.com) の **Streams** に向けてライブストリーミングを送り出すことになります

**Streams** は **Broadcast** に結び付けて初めて視聴可能となります
この作業を **Bind** と呼びます
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/9bb293ac-bdcc-3fe0-182f-b37d53049294.png)

本記事では **Broadcasts** と **Streams** は以下のように運用します
すなわち
**Broadcasts** は都度新規作成する
**Stremas** は常に同じものを使いまわす
理由は、URL + KEY がいちいち変わると設定が面倒くさいから...
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/102797/8eecdd7b-9710-0d4a-b5b8-53485ebdd362.png)
※ 以下に示す手順は、上記の運用に従ったものになるので、そう思って読んでいってください

### 3. [後半-3] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする① (準備)

**後半-1** の手順で [YouTube Studio](https://studio.youtube.com/) を利用して行っていた部分を
[YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) を使って操作してみたいと思います

● **Broadcasts** の作成

まずは **Broadcasts** を作成します
この時 `scheduledStartTime` の指定が必要になります
現在時刻から「遠すぎない」未来の時刻の間での指定が必要になるので自動生成しましょう
**ACCESS_TOKEN** は、前半の手順で取得した **ACCESS_TOKEN** です
やっと使う時がきました
もし Expire していたら、再度 **REFRESH_TOKEN** から取得しましょう
```shell
$ DATE=`TZ=0 date '+%Y-%m-%dT%H:%M:%S.000Z'`
$ ACCESS_TOKEN={ Access Token を入力 }
$ curl --request POST "https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id,snippet,contentDetails,status" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --data '{ "snippet" : { "scheduledStartTime": "'"$DATE"'", "title": "ラズパイ配信テスト" }, "status" : { "privacyStatus": "private" }}' --compressed
```
実際戻ってくる json はこんな感じです
```shell
pi@raspberrypi:~/sidecar/mylinebot $ curl --request POST "https://www.googleapis.com/youtube/v3/liveBroadcasts?part=id,snippet,contentDetails,status" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --data '{ "snippet" : { "scheduledStartTime": "'"$DATE"'", "title": "ラズパイ配信テスト" }, "status" : { "privacyStatus": "private" }}' --compressed
{
  "kind": "youtube#liveBroadcast",
  "etag": "xxxxx",
  "id": " ここに Boradcast ID が入っている ", ★★★
  "snippet": {
    "publishedAt": "2023-03-07T01:15:46Z",
    "channelId": "xxxxx",
    "title": "ラズパイ配信テスト",
    (略)
    },
    "scheduledStartTime": "2023-03-07T01:15:07Z",
    "isDefaultBroadcast": false,
    "liveChatId": "xxxxx"
  },
  (略)
}
```
このコマンドで表示されるjsonに **Broadcast ID** が含まれています
メモしておきましょう
この後コマンドの中で頻繁に利用するので環境変数に設定しておきましょう
```shell
$ BROADCAST_ID={ Boradcat ID を入力する }
```

ここからは手順に従って [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) のAPIを呼ぶだけなのでどんどん行きます

● **Stream ID**を調べる

ラズパイからの送出先となる **Stremas** のIDを調べます
```shell
$ curl --request GET "https://www.googleapis.com/youtube/v3/liveStreams?part=id,snippet,cdn,status&mine=true" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
```
こんな json が返ってきます
`items` の下に `id` があって、ここに **Streams ID** が入っています
メモします
```shell
pi@raspberrypi:~/sidecar/mylinebot $ curl --request GET "https://www.googleapis.com/youtube/v3/liveStreams?part=id,snippet,cdn,status&mine=true" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
{
  "kind": "youtube#liveStreamListResponse",
  "etag": "XXXXX",
  "pageInfo": {
    "totalResults": 1,
    "resultsPerPage": 5
  },
  "items": [
    {
      "kind": "youtube#liveStream",
      "etag": "XXXXX",
      "id": "ここに Stream ID が入っている", ★★★
      "snippet": {
        "publishedAt": "2020-09-07T00:35:06Z",
        "channelId": "XXXXX",
        "title": "Default stream key",
        "description": "Description for default stream key",
        "isDefaultStream": false
      },
      (略)
    }
  ]
}
```
これも再利用するので環境変数に設定しておきます
```shell
$ STREAM_ID={ Stream ID を入力する }
```

● **Broadcats** と **Streams** をバインドする
```shell
$ curl --request POST "https://www.googleapis.com/youtube/v3/liveBroadcasts/bind?id=$BROADCAST_ID&part=id,snippet,contentDetails,status&streamId=$STREAM_ID" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
```

● **Broadcasts** のステータスを testing に変更する (ライブ開始の準備の状態にする)
```shell
$ curl --request POST "https://youtube.googleapis.com/youtube/v3/liveBroadcasts/transition?broadcastStatus=testing&id=$BROADCAST_ID&part=id&part=snippet&part=contentDetails&part=status" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
```

### 4. [後半-4] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする② (配信)

いよいよライブ配信を開始します

● ラズパイからライブ配信を始める (別シェルで実行してください)
```shell
$ raspivid -w 1920 -h 1080 -fps 30 -o - -t 0 -b 2500000 | ffmpeg -re -stream_loop -1 -i no_sound-1.mp3 -f h264 -i - -c:v copy -f flv rtmp://{ ストリームURLを入れる }/{ ストリームキーを入れる }
```

● **Broadcasts** のステータスを live に変更する (ライブ公開状態にする)
```shell
$ curl --request POST "https://youtube.googleapis.com/youtube/v3/liveBroadcasts/transition?broadcastStatus=live&id=$BROADCAST_ID&part=id&part=snippet&part=contentDetails&part=status" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
```

ブラウザで
`https://www.youtube.com/watch?v={ Broadcast ID を入力 }`
を開くと、ラズパイからのライブ配信が見られるはずです

### 5. [後半-5] [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja)でライブ配信をする② (終了、アーカイブ)

● ラズパイからのストリーミングを止める

ちょっと強引ですがストリーミングに使っているプロセスを `kill` しちゃいます
```shell
$ ps aux | grep raspivid | grep -v grep | grep -v bash | awk '{ print "kill -9", $2 }' | sh
$ ps aux | grep ffmpeg | grep -v grep | grep -v bash | awk '{ print "kill -9", $2 }' | sh
```

● **Broadcasts** のステータスを complete に変更する (ストリーミングを止めて、アーカイブをする)
```shell
$ curl --request POST "https://youtube.googleapis.com/youtube/v3/liveBroadcasts/transition?broadcastStatus=complete&id=$BROADCAST_ID&part=id&part=snippet&part=contentDetails&part=status" --header "Authorization: Bearer $ACCESS_TOKEN" --header 'Accept: application/json' --header 'Content-Type: application/json' --compressed
```
YouTubeへライブ配信したストリーミングは自動的にアーカイブされ
**Broadcasts** を明示的に消さないかぎりずっと見られます
URLは
`https://www.youtube.com/watch?v={ Broadcast ID を入力 }`
です

# 終わり

お疲れさまでした
これで、YouTube Live の一連の動作を [YouTube Live Streaming API](https://developers.google.com/youtube/v3/live/docs?hl=ja) から実施できました
後はスクリプト組むなり、コーディングするなりで自動化しましょう

この記事での手順の紹介はここまでです
お付き合いありがとうございました！

気軽にライブ配信できる世の中を目指して
ではでは

# 参考になる記事

■ とかい育ち.com
YouTubeLiveのイベント配信枠をAPIから作成する
https://tokaisodachi.com/archives/2206

■ Qiita
YouTube Data APIを使ってみる
https://qiita.com/comcha/items/5edda78c917bf70adb63

■ 釣りキチ翔平の備忘録
Google OAuthでAccess Tokenを取得する｜Google APIを利用するための準備編
https://poppingcarp.com/google-api_get_access_token/

■ Google公式
YouTube Data APIの概要
https://developers.google.com/youtube/v3/getting-started?hl=ja

EOF