yoshikipom Tech Blog

「アレクサ、XXXをつけて」-> 事前指定したURLのYouTube動画を再生

Overview

最近、YouTubeでワンピースのアニメが24時間放送されている(参考)。我が家ではテレビで頻繁にこの放送を見ているが、開くのが少し面倒だったので自動化してみた。

  • As-Is: リモコンでYouTubeアプリを起動(ショートカットで1ボタンではある) → ログイン(ログイン済みなら不要) → ワンピース動画を探してクリック → 動画再生
  • To-Be: 「アレクサ、ワンピースをつけて」 → 動画再生

環境

ハードウェア

この記事の実装で必要なハードウェアは以下。

  • アレクサが使えるデバイス
  • ローカルにあるサーバ
  • webOS搭載のテレビ
  • 開発機

我が家で使ったのは以下。

  • セールで安く買えた Alexa Echo Pop
  • Home Bridgeしか役目ののなかった Raspberry Pi 3
  • LGのテレビ 55UN8100PJA
  • MacBook

ソフトウェア

全体像

アレクサを使ってテレビでYouTube動画再生

使わなかった技術たち

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のライブラリとリファレンスっぽい。

最近はGo言語の勉強をしているのでGo言語での実装を見つけて使うことにした。4年ほど更新されていないが動作する。 https://github.com/kaperys/go-webos

スクリプト→webOS上でのYouTube起動の実装

上記のリポジトリそのままだと以下のことが自動化できなかった。

  • YouTubeで特定URLを開く (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 は使っていない。

Node-REDのGUI
Node-REDのデバイス追加

ここまでやったあとに「アレクサ、ワンピースつけて」というと無事再生できた。

感想

  • GUIで設定するのに抵抗感があってNode-REDは使ったことがなかったが、シンプルで拡張性も高そうなので良い
  • こういうタスクは保守性が気にならないのでPythonでやったほうがよかった