あさココを自動でChromecast(or Nest Hub)にキャストして目覚まし代わりにする

###はじめに
最近、Vtuber界で勢いを増しているホロライブ。
アイドル色が強く、メンバー同士のコラボも多いことから、箱推しの機運が高まりがちですが、全員の配信を追うことはかなり厳しいです。
そんなホロライブの情報を入手する手段として、4期生の桐生ココさんが平日朝6時に放送している「あさココLiveニュース」(以下あさココ)があります。
あさココは、前日のホロライブメンバーの配信で起こった事などをピックアップして20分ほどにまとめられており、非常に見やすい配信となっています。
ですが、朝6時という時間の都合上、寝過ごして見逃してしまうことが多々ありました。
そこで、あさココを自動で再生し、目覚まし代わりにすることで、見逃しを減らします。
具体的には、Youtube Data APIで配信予定情報を取得し、配信開始を監視、配信が始まったらChromecastにキャストします。


###動作確認環境
  - Ubuntu 18.04 LTS 64Bit
  - Python 3.6.9
  - Chromecast Ultra
  - Google Nest Hub


###事前準備
  - Youtube Data API
    - APIキーを取得しておきます。取得方法は[ここ](https://developers.google.com/youtube/v3/getting-started?hl=ja)を参照
  - Pythonモジュール
    - Youtube Data API用のクライアントとChromecast制御用のモジュールをインストールしておきます。

```
    pip3 install pychromecast
    pip3 install --upgrade google-api-python-client
```
###詳細手順
ソースは[Github](https://github.com/sleepsleepsheep/asacoco_autocast)に置いてあります。以下はざっくりした説明です。
パス名やファイル名は適宜変更してください。

####配信予定情報を取得する
search:listリクエストを使用して配信予定を探します。配信予定枠が作られていれば、その動画IDを返します。

  ```python:booking.py
def search_videos():
  """あさココの検索結果から配信予定枠を検索して動画IDを返す"""
  # q=検索クエリ
  # part=取得する情報種別(snippet:基本情報)
  # channnelId=検索対象に入れるチャンネルID
  # maxResults=検索結果として返す最大数
  search_response = youtube.search().list(
    q='あさココ',
    part='snippet',
    channelId='UCS9uQI-jC3DE0L4IpXyvr6w',
    maxResults=5
  ).execute()

  video_id = None

  for search_result in search_response.get('items', []):
    if search_result['id']['kind'] == 'youtube#video':
      if search_result['snippet']['liveBroadcastContent'] == 'upcoming':
        # 配信予定枠が見つかったらvideoIdを取得する
        video_id = search_result['id']['videoId']
        break

  return video_id
  ```

配信予定の動画IDが見つかったら、配信開始予定時刻を取得します。
videos:listリクエストを使用します。

```python:booking.py
def get_scheduledtime(video_id):
  """配信予定枠の動画IDから配信開始予定時間を取得しての5分前の時刻をatコマンドのフォーマットで返す"""
  # part=liveStreamingDetails(配信情報)
  # id=動画ID
  videos_response = youtube.videos().list(
    part='liveStreamingDetails',
    id=video_id
  ).execute()

  for search_result in videos_response.get('items', []):
    
    scheduled = datetime.datetime.strptime(search_result['liveStreamingDetails']['scheduledStartTime'], '%Y-%m-%dT%H:%M:%S.%fZ')
    scheduled_jst = scheduled + datetime.timedelta(hours=8, minutes=55)

  return scheduled_jst.strftime('%H:%M %m%d%Y')
```

"scheduledStartTime"が配信開始予定時刻ですが、UTCのため、+9時間した時刻が日本での正しい時刻です。
atコマンドで、配信開始予定時刻の5分前に配信状態監視スクリプトが起動するように設定します。
[pythonからatコマンドで予約](https://conc7996.hatenadiary.org/entry/20080114/1200292107)
 
```python:booking.py
p = subprocess.Popen(['at', start_time], stdin=subprocess.PIPE)
command = '%slivestate.py -i %s' % (EXEC_PATH, video_id)
p.communicate(command.encode('utf-8'))
```

コマンドライン引数として動画IDを渡しておきます。


####配信状態を監視して、配信中であればChromecastにキャストする
atコマンドにより、配信時間5分前になったら、配信状態監視スクリプトが起動します。
コマンドライン引数として渡された動画IDをvideos:listリクエストに渡して配信状態を取得します。

```python:livestate.py
  videos_response = youtube.videos().list(
    part='snippet',
    id=video_id
  ).execute()

  for search_result in videos_response.get('items', []):
      result = search_result['snippet']['liveBroadcastContent']

  return result
```

取得した状態が"upcoming"であればしばらく待って再度取得します。
"live"であれば配信中なので、Chromecastへキャストします。

```python:livestate.py
def cast_device(video_id):
  """指定した動画IDの動画をデバイスにキャストする"""
  chromecasts = pychromecast.get_chromecasts()

  cast = next(cc for cc in chromecasts if cc.device.friendly_name == CAST_DEV_NAME)
  cast.wait()

  yt = YouTubeController()
  cast.register_handler(yt)
  yt.play_video(video_id)
```

参考:[pychromecast/examples/youtube_exapmle.py](https://github.com/balloob/pychromecast/blob/master/examples/youtube_example.py)
**CAST_DEV_NAME**はキャストするデバイスの名前です。Homeアプリで設定したデバイス名を設定しておきます。

####Cronに登録して、自動で開始するようにする
このままだと1回目の放送情報取得は手動で行わなければいけないため、Cronに登録して、指定時間に自動で動くようにします。

```
  $ crontab -e
  # 以下をファイルに追記
  0 0 * * 1-5 Python3 [作業パス]/booking.py
```

これで月～金曜日の0時に初回が起動するようになりました。

####まとめ
Youtube Data APIを使用して配信情報を取得し、配信開始時にChromecastにキャストすることができました。
これを応用すれば、登録チャンネルの配信予定を一覧取得し、視聴予約する というようなことができそうです。
あさココで起きることで、1日のよいスタートが切れそうですね(？)。
最後に、推しの曲を貼ってまとめとさせていただきます。すいちゃんはいいぞ。
[comet](https://youtu.be/3cqV5BKJHyk)
[天球、彗星は夜を跨いで](https://youtu.be/zLak0dxBKpM)