Overview
最近、YouTubeでワンピースのアニメが24時間放送されている(参考)。我が家ではテレビで頻繁にこの放送を見ているが、開くのが少し面倒だったので自動化してみた。
- As-Is: リモコンでYouTubeアプリを起動(ショートカットで1ボタンではある) → ログイン(ログイン済みなら不要) → ワンピース動画を探してクリック → 動画再生
- To-Be: 「アレクサ、ワンピースをつけて」 → 動画再生
環境
ハードウェア
この記事の実装で必要なハードウェアは以下。
- アレクサが使えるデバイス
- ローカルにあるサーバ
- webOS搭載のテレビ
- 開発機
我が家で使ったのは以下。
- セールで安く買えた Alexa Echo Pop
- Home Bridgeしか役目ののなかった Raspberry Pi 3
- LGのテレビ 55UN8100PJA
- MacBook
ソフトウェア
- Alexa Echo Pop
- Alexa Skill: Node-RED https://www.amazon.co.jp/Ben-Hardill-Node-RED/dp/B01N0D97FZ
- Raspberry Pi 3
- OS:
Raspbian GNU/Linux 11 (bullseye)
- Node-RED
- Go言語で作成した実行ファイル
- OS:
全体像
使わなかった技術たち
Chrome castや既存のAlexa Skill
フレーズが長くなるのが嫌なので避けた(アレクサ、YouTubeでXXXの動画を再生して 等)
Alexa + Home Bridge
別の選択肢としてAlexa → Home Bridge の連携をできるスキルがあった。しかし、有料化していたので今回は見送った。
After the initial 7 day trial period for new users, a monthly subscription costs $2.00 USD per month or an annual subscription costs $22.00 USD per year. Basically buying me a coffee once a month ( cheaper than a beer ). https://www.homebridge.ca/faq
CMD4 という特定のスクリプトを Home Bridge のアクセサリとして登録できるいいソフトウェアがあったので、Alexa + Home Bridge を使うかHomePodを手にいれることがあれば実践投入したい。 CMD4 https://ztalbot2000.github.io/homebridge-cmd4/autoGenerated/CMD4_AccessoryDescriptions.html
公式のwebOSライブラリ
ライブラリでやることはローカルネットワークにあるテレビのIPアドレスを指定して接続し、WebSocketを通してJSONでwebOSと通信する。ただ、公開されているのはWebSocketのAPIではなく、JSのライブラリとリファレンスっぽい。
- JSライブラリ: https://github.com/webOS-DevRel/webOS.js
- リファレンスJSライブラリ: https://webostv.developer.lge.com/develop/references/webostvjs-webos
最近はGo言語の勉強をしているのでGo言語での実装を見つけて使うことにした。4年ほど更新されていないが動作する。 https://github.com/kaperys/go-webos
スクリプト→webOS上でのYouTube起動の実装
上記のリポジトリそのままだと以下のことが自動化できなかった。
そのため、フォークして一部拡張した。 https://github.com/yoshikipom/go-webos
スクリプト1: Client ID取得
https://github.com/yoshikipom/go-webos/blob/master/cmd/auth/main.go
以下のようにIPアドレスを渡して実行するとテレビにプロンプトが出るのでOKを押せばClient IDが返ってくる。
go run cmd/auth/main.go 192.168.3.10 > client-id
これを次のスクリプトに渡せばプロンプトの表示なしにスクリプトが実行できる。この Client IDは長期間使えるため(具体的な時間は不明)、このスクリプトは一度だけ実行すればよい。
スクリプト2: YouTuvbeで動画を開く
https://github.com/yoshikipom/go-webos/blob/master/cmd/launch_youtube/main.go
以下のように IPアドレス、Client ID、YouTubeのURLを渡せば対象の動画が再生される。
go run cmd/launch_youtube/main.go 192.168.3.10 $(cat client-id) https://www.youtube.com/watch?v=79XaA_4CYj8
main.go
のメイン部分。tv.Command(...
の部分で動画を開くことができる。コマンド実行時のテレビの状態によってはうまく開かなかったりログイン状態で止まったりしてしまうため、追加の処理(tv.OpenApp
やsleep)が入っている。tv.KeyEnter()
はログイン画面から進むため。画面の状態を取得する方法を調べればこの辺は改善できそうだが、不便していないのでこのままにした。
a, err := tv.CurrentApp() if err != nil { fmt.Printf("Error: %+v\n", err) } currentAppIsYoutube := a.AppID == youtubeAppID if !currentAppIsYoutube { tv.OpenApp(youtubeAppID) } _, err = tv.Command(webos.SystemLauncherLaunchCommand, webos.Payload{"id": youtubeAppID, "params": map[string]interface{}{"contentTarget": videoURL}}) if err != nil { fmt.Printf("Error: %+v\n", err) } sleepBeforeLoginClick(currentAppIsYoutube) tv.KeyEnter()
シェルスクリプト
Goに渡す引数が地味に長いのでNode-REDに渡す実行コマンドを短くするためにシェルスクリプトを作っておいた。引数の変更時にいちいちNode-REDの管理画面を開かなくてよいのもメリット。 https://github.com/yoshikipom/go-webos/tree/master/server
ビルドとか
ラズパイ用にビルドして、scpで送った。
GOOS=linux GOARCH=arm GOARM=7 go build -o bin/auth cmd/auth/main.go GOOS=linux GOARCH=arm GOARM=7 go build -o bin/launch_youtube cmd/launch_youtube/main.go scp bin/* ${user}@${ip}:${path_in_server} scp server/command.sh ${user}@${ip}:${path_in_server} scp client-id ${user}@${ip}:${path_in_server}
アレクサ→Node-REDでのスクリプト実行
この記事を参考にさせていただいたところ問題なく動いた。 https://qiita.com/g-iki/items/a5d4d4674a30de7ed124
変えたところ
- このユースケースだと「XXXつけて」しか使わないので Node-REDの switch は is true
側にだけスクリプトに繋げれば十分。
- 管理画面でのデバイス追加も On
だけ使えるようにして Off
は使っていない。
ここまでやったあとに「アレクサ、ワンピースつけて」というと無事再生できた。