概要
ラズパイからYouTube Liveを利用してライブ配信をします
ライブのたびに YouTube Studio の操作が必要になる紹介記事が多いのですが
本記事では YouTube Live Streaming API を利用して、ライブの準備、配信、アーカイブをおこないます
前半は YouTube API (= Google API) を利用できるようになるまで
具体的には Google Cloud Console で プロジェクト を作成するところから
APIへのアクセスに必要な ACCESS TOKEN を入手するところまで
後半は YouTube Live Streaming API を利用して
ライブの準備、配信、アーカイブを行う手順
を紹介します。
補足的に必要な知識として
- ffmpegによるストリーミング
- YouTube Live Streaming API における Broadcasts と Streams の概念とライフサイクル
の話も紹介します
目次
前半 : YouTube API を利用できるように準備する
前半はラズパイもコーディングも不要です
太字はこれから作るものの固有名詞です
とりあえず「あー、そういうものを作るのね」と思っておいてください
APIにアクセスするためのゴールは ACCESS TOKEN なのですが、REFRESH TOKEN さえあれば何度でも生成できます
- [前半-1] プロジェクトを作成する
- [前半-2] YouTube Data APIを有効にする
- [前半-3] 認証情報を作成する
- [前半-4] OAuth同意画面を作成する
- [前半-5] OAuthを実行して code を入手する
- [前半-6] REFRESH TOKENを入手する
- [前半-7] ACCESS TOKENを入手する
後半 : YouTube Live Streaming API を利用してライブ配信する
- [後半-1] まず YouTube Studio を使ってラズパイからライブ配信をしてみる (ffmpegによるストリーミング)
- [後半-2] (座学) YouTube Live Streaming API における Broadcasts と Streams の概念とライフサイクル (飛ばしてもよい)
- [後半-3] YouTube Live Streaming APIでライブ配信をする① (準備)
- [後半-4] YouTube Live Streaming APIでライブ配信をする② (配信)
- [後半-5] YouTube Live Streaming APIでライブ配信をする② (終了、アーカイブ)
目次を見るだけでも「うへ~、ながっ」と思うかもしれませんが
一つ一つ進めていけば大丈夫です
途中で REFRESH_TOKEN が手に入るのですが、
そうすれば Google Cloud Console での煩雑な作業も不要になるので頑張りましょう
手順
前半
1. [前半-1] プロジェクトを作成する
ブラウザで Google Cloud Console を開きます
自分のアカウントでログインしている状態になると思いますが、
そうでない場合は Googleアカウントを作成して、ログインしてください。
左上のプロジェクト名(自分の例ではSidecar
)が表示されているドロップダウンをクリックします
プロジェクトの選択ダイアログが表示されるので、右上の「新しいプロジェクト」をクリックします
プロジェクト名を適当につけて「作成」
しばらく待つと「プロジェクト XXXXX を作成」という通知がきます
2. [前半-2] YouTube Data APIを有効にする
通知の「プロジェクトを選択」をクリックします
プロジェクトが選択された状態になるので、左側のペインから「APIとサービス」>「有効なAPIとサービス」をクリックします
「+APIとサービスの有効化」をクリックします
「YouTube Data API v3」を選択します。Streaming APIもこの中に入っています
「有効にする」をクリックします
API/サービスの詳細の画面に戻って、画面右上に「認証情報を作成する」と出るので、それをクリックします
※ なお、最後のステップで「認証情報を作成する」を押さずに画面を変えてしまった場合でも、
※ 同じ情報は、左のペインの「認証情報」「OAuth同意画面」から入力できます
※ 画面遷移などは多少違いますが、大丈夫です
3. [前半-3] 認証情報を作成する
まえの手順で「認証情報を作成する」を押すと「認証情報の作成」ウィザードが立ち上がります。
① 認証情報の種類 ではユーザデータを選択します。「次へ」で次のステップへ
② OAuth同意画面では、適当にアプリ名をつけます
ユーザーサポートメール、メールアドレスには自分のgmailのメールアドレスを入れておきます
※ 届くメールアドレスならば何でも大丈夫です
③ スコープでは「スコープを追加または削除」をクリックします
すると「選択したスコープの更新」ダイアログが表示されます
フィルタに YouTube
と入力すると補完されるので YouTube Data API v3
を選択
下のリストから
.../auth/youtube
.../auth/youtube.force-ssl
.../auth/youtube.upload
を選択します
④ OAuthクライアントIDではアプリケーションの種類で「デスクトップアプリ」を選び、名前は適当につけます
「作成」をクリックすると、認証情報が作成されます
すこしだけ時間がかかります
⑤ 認証情報画面では作成された認証情報が確認できます
「ダウンロード」を押すとjsonファイルが取得できるので、適当な場所に保存しておきます
jsonファイルの中の client_id と client_secret が後々必要な情報となります
また redirect_uris は http://localhost
になっていると思います
一応覚えておきましょう
ダウンロードされた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同意画面」をクリックし「アプリを編集」をクリックします
いくつかステップがありますが、「保存して次へ」を押して ③テストユーザー まで行きます
「+ ADD USERS」をクリックします
「ユーザを追加」ダイアログで自分のgmailのメールアドレスを追加しておきます
「保存して次へ」をクリックします
最後に確認画面が表示されるので「ダッシュボードに戻る」をクリックします
これで、OAuthを実行して code を入手する準備が整いました
Google Cloud Consoleを利用するのはここまでになります
次の手順以降、各種KEYやIDをコピーペーストで入力していきますので、
もしテキストファイルなどにコピペしていない場合は、コンソールは開きっぱなしがいいと思います
5. [前半-5] OAuthを実行して code を入手する
ブラウザでOAuthを実行します
OAuth完了時にリダイレクトされたURLの一部に code が記載されているのでそれを回収します
まずURLを作ります
書式は
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 で設定した値を使うので
URLは以下になります
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)をクリックします
「続行」をクリック
二つのチェックボックスの両方にチェックを入れて「続行」をクリック
リダイレクトURLで指定したアドレスを開こうとして Not Found になります
これは 期待動作(想定通り) なのでご安心ください
ブラウザに表示されているURLをコピペしてテキストエディタなどにはりつけます
code=
と &scope=
の間の文字列が code になります
※ ちょうど黄緑色で塗りつぶしたところに code が入っています
6. [前半-6] REFRESH TOKENを入手する
ここからは curl
コマンドを利用して、Google APIにアクセスします
Client ID
Client Secret
code
の3つの情報を利用して、以下のように curl
コマンドを実行します
$ 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 が含まれています
絶対なくさないようにメモして保存しておきましょう
これからずっと使います
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
コマンドを実行します
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 が含まれています
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 を使ってラズパイからライブ配信をしてみる (ffmpegによるストリーミング)
まずは YouTube Studio でライブ配信イベントを手動で作成して
ラズパイからライブ配信を行ってみます
YouTube側がライブ配信を受け入れられるときに、ラズパイ側がきちんと送出できるかの確認です
まずブラウザで
YouTube のサイトに行き
画面右上の自分のアイコンをクリックします
表示されるドロップダウンから YouTube Studio をクリックします
YouTube Studio の画面の右上の「作成」をクリックし
表示されたドロップダウンの「ライブ配信を開始」をクリックします
ライブ配信画面で ストリームキー と ストリームURL をコピーします
(右のコピーボタンを押してテキストエディタなどに張り付けておきましょう)
ここからはラズパイでの操作になります
ffmpegをインストールします
$ sudo apt-get install ffmpeg
YouTubeへの配信の際
音が必ず必要になります
今回マイクデバイスを用意しなかったので、無音MP3を代わりに流すことにします
(お気に入りのMP3があればそれを使っても構いません。ただし著作権にはご注意を...)
no_sound-1.mp3 ※右クリックして「名前を付けて保存」してください
※ クリキのキロク様に感謝
ラズパイのコマンドラインからダウンロードしたい場合は curl でダウンロードしましょう
$ 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出力できるカメラから
ストリーミングするのも簡単です (すごいなラズパイ)
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
でエンコードする代わりに、これを使おうと思います
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 から取得した値を入れてください
$ 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 でラズパイから送出されたライブ映像が確認できます
ライブ配信、すごく簡単ですね...
2. [後半-2] (座学) YouTube Live Streaming API における Broadcasts と Streams の概念とライフサイクル (飛ばしてもよい)
ここでは座学ということで
YouTube Live Streaming API の Broadcasts と Streams がどういう概念なのかを
かるーく説明します
Broadcasts は、YouTube の「番組」にあたるものです
放送前だったり、ライブ放送中だったり、ライブ後にアーカイブされた状態だったりと
いくつかの状態を持ちます
Broadcasts には、それぞれIDがつきます。
これは YouTube を使っている方ならおなじみのID(文字列)で
https://www.youtube.com/watch?v=fEvM-OUbaKs
など
いわゆる YouTube URL の fEvM-OUbaKs
の部分になります
Streams は、ラズパイなどのストリーミング送出機器に対する「ストリーム受信窓口」です
ストリームURLとストリームKEYが設定され
RTMP(RTMPS)の送出先URLになります
ffmpegやOBSなどでは、このストリームURLとストリームKEYを送出先として設定して
YouTube の Streams に向けてライブストリーミングを送り出すことになります
Streams は Broadcast に結び付けて初めて視聴可能となります
この作業を Bind と呼びます
本記事では Broadcasts と Streams は以下のように運用します
すなわち
Broadcasts は都度新規作成する
Stremas は常に同じものを使いまわす
理由は、URL + KEY がいちいち変わると設定が面倒くさいから...
※ 以下に示す手順は、上記の運用に従ったものになるので、そう思って読んでいってください
3. [後半-3] YouTube Live Streaming APIでライブ配信をする① (準備)
後半-1 の手順で YouTube Studio を利用して行っていた部分を
YouTube Live Streaming API を使って操作してみたいと思います
● Broadcasts の作成
まずは Broadcasts を作成します
この時 scheduledStartTime
の指定が必要になります
現在時刻から「遠すぎない」未来の時刻の間での指定が必要になるので自動生成しましょう
ACCESS_TOKEN は、前半の手順で取得した ACCESS_TOKEN です
やっと使う時がきました
もし Expire していたら、再度 REFRESH_TOKEN から取得しましょう
$ 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 はこんな感じです
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 が含まれています
メモしておきましょう
この後コマンドの中で頻繁に利用するので環境変数に設定しておきましょう
$ BROADCAST_ID={ Boradcat ID を入力する }
ここからは手順に従って YouTube Live Streaming API のAPIを呼ぶだけなのでどんどん行きます
● Stream IDを調べる
ラズパイからの送出先となる Stremas のIDを調べます
$ 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 が入っています
メモします
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
},
(略)
}
]
}
これも再利用するので環境変数に設定しておきます
$ STREAM_ID={ Stream ID を入力する }
● Broadcats と Streams をバインドする
$ 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 に変更する (ライブ開始の準備の状態にする)
$ 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でライブ配信をする② (配信)
いよいよライブ配信を開始します
● ラズパイからライブ配信を始める (別シェルで実行してください)
$ 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 に変更する (ライブ公開状態にする)
$ 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でライブ配信をする② (終了、アーカイブ)
● ラズパイからのストリーミングを止める
ちょっと強引ですがストリーミングに使っているプロセスを kill
しちゃいます
$ 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 に変更する (ストリーミングを止めて、アーカイブをする)
$ 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 から実施できました
後はスクリプト組むなり、コーディングするなりで自動化しましょう
この記事での手順の紹介はここまでです
お付き合いありがとうございました!
気軽にライブ配信できる世の中を目指して
ではでは
参考になる記事
■ とかい育ち.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