Global Media Controls で Alexa SPA を操作する Chrome 拡張を作った

モチベーション

音楽を聴くときは Amazon Echo のマルチルームオーディオを使っている。 いろんな部屋で同じ曲が流れるのはいい経験だが、曲名を確認したり、曲をスキップしたいときに、声を出さないといけない。 そこで https://alexa.amazon.co.jp/spa/index.html#player (以下 Alexa SPA) を使うと、Web ブラウザから曲名を確認したり、曲をスキップできて便利なので、合わせて使っている。

最近 Chrome 79 で YouTube Music を聴いてたら、Chromeツールバーに音楽のツールバーが表示されるようになったことに気づいた。

f:id:mallowlabs:20200125174732p:plain

調べたら Global Media Controls という言うらしい。Chrome 79 時点では実験的な実装とされている。 これを Alexa SPA でも使いたいと思ったので、 Chrome 拡張で実装してみた

alexa-spa-global-media-controls

github.com

Chrome ストアには上げていないので、試してみたい場合はクローンして、Chrome に読み込んで欲しい。

拡張をインストールした状態で https://alexa.amazon.co.jp/spa/index.html#player にアクセスして、Alexa で音楽を流せばツールバーに以下のように表示される。

f:id:mallowlabs:20200125175129p:plain

実装の話

日本語のドキュメントが余りなかったのと、細かいところで結構ハマったので、ハマりどころをまとめる。 Chrome 79.0.3945.130 時点の話なので、今後改善する可能性は高い。

ツールバーに表示されない

基本的には MediaSession API を以下のように使うだけのはずである。

navigator.mediaSession.metadata = new MediaMetadata({
  title: '曲名',
  artist: 'アーティスト名',
  album: 'アルバム名',
  artwork: [
   { src:' アルバムアートの URL' }
  ]
});

しかし、これを呼び出してもツールバーにボタンが表示されない。 調べてみると実際のタブで video タグや audio タグで実際に音声が再生されている必要があるらしい。 しかも、 5秒以上の音声ファイルを再生している必要があるらしい。 Alexa SPA では実際の音は Amazon Echo から流れるため、タブで音楽を再生することはできない。 そこで、無音の ogg ファイルを用意して、 DOM の状態を見て、再生したり停止するように実装した。

アルバム名の表示位置が変

MediaSession API に素直に album 属性を渡すと、ドメインの横に表示される。 YouTube Music はどうしてるのか見てみたら artist 属性にアルバム名を含めるようにしていた。 なんか釈然としないが、似たような感じで実装した。

f:id:mallowlabs:20200125180157p:plain

navigator.mediaSession.metadata = new MediaMetadata({
  title: '曲名 - アルバム名',
  artist: 'アーティスト名',
  artwork: [
   { src:' アルバムアートの URL' }
  ]
});

アルバムアートが表示されない

アルバムアートの URL に画像の URL を渡しているにも関わらず、画像が表示されない。 どうやら sizes 属性を指定しなければならないらしい。

navigator.mediaSession.metadata = new MediaMetadata({
  title: '曲名 - アルバム名',
  artist: 'アーティスト名',
  artwork: [
   { sizes: '412x412', src:' アルバムアートの URL' }
  ]
});

artwork には type も指定できるが、こっちは不要らしい。

まとめ

Global Media Controls 個人的にはかなりアリなので、普及して欲しい。

参考 URL