はじめに
LGのwebOSテレビのリモコンには、Netflix・Prime Video・Disney+などの専用ボタンが付いています。使っていないサービスのボタンは押すこともなく、もったいないと感じていました。
Netflix/Amazonボタンを別のアプリに割り当てる方法はすでに紹介されています。そこで同じ方法を Disney+ボタン で試したところ、そのままの手順では画面が真っ暗になって動きませんでした。この記事では、その原因と対処方法をまとめます。
仕組み
- リモコンの専用ボタンは、決まったappIdのアプリを起動するだけです。
- そこで純正アプリを削除し、同じappIdを持つ自作アプリ(ランチャー) を開発者モードでインストールします。
- ランチャーは、起動されたらすぐにYouTubeを起動します。
root化やファームウェアの改造はしません。LG公式の開発者モードとCLIだけを使います。
環境
| 項目 | 内容 |
|---|---|
| テレビ | LG 43NANO75JPA |
| webOS | 6.5.3(ファームウェア 03.53.45) |
| PC | macOS |
| webOS TV CLI | @webos-tools/cli 3.2.6 |
| webOSTVjs | 1.2.13 |
事前準備
1. LG開発者アカウントを作る
webOS TV Developer でアカウントを作ります。
2. テレビにDeveloper Modeアプリを入れる
- テレビのLG Content Storeで「Developer Mode」アプリを検索してインストールします。
- 1で作ったアカウントでログインします。
- Dev Mode Status を ON にします(テレビが再起動します)。
- 再起動したら、もう一度アプリを開いて Key Server を ON にします。
- 画面に表示される IPアドレス と Passphrase をメモします。
Key Serverは、時間が経つと勝手にOFFに戻ることがあります。鍵を取得する直前に、ONになっているか確認してください。
3. Disney+アプリを削除する
テレビ側で純正のDisney+アプリを削除しておきます。残っていると、同じappIdのランチャーをインストールできません。
手順
1. CLIをインストールする
npm install -g @webos-tools/cli
ares --version
2. テレビを登録して鍵を取得する
ares-setup-device -a lgtv -i "host=192.168.x.x" -i "port=9922" -i "username=prisoner"
ares-novacom --getkey -d lgtv # パスフレーズを聞かれるので入力する
私の環境(CLI 3.2.6)では、--getkey で鍵ファイルは取得できたのに、パスフレーズがデバイス情報に保存されませんでした。その状態だと、接続しようとしたときに All configured authentication methods failed が出ます。次のコマンドで明示的に登録すると直ります。
ares-setup-device -m lgtv -i "passphrase=XXXXXX" -i "privatekey=lgtv_webos"
接続を確認します。古い記事にある ares-device-info は非推奨になっているので、ares-device -i を使います。
ares-device -i -d lgtv
3. PCからYouTubeを起動できるか確認する
ares-launch -d lgtv youtube.leanback.v4
4. ランチャーアプリを作る
ares-generate -t basic -p "id=com.disney.disneyplus-prod" -p "title=YouTube Launcher" launcher
launcher/appinfo.json に "transparent": true を追加します(文字列ではなく真偽値です)。
{
"id": "com.disney.disneyplus-prod",
"version": "0.0.3",
"vendor": "My Company",
"type": "web",
"main": "index.html",
"title": "YouTube Launcher",
"icon": "icon.png",
"largeIcon": "largeIcon.png",
"transparent": true
}
launcher/index.html を次の内容に置き換えます。webOSTVjs-1.2.13 の部分は、生成されたフォルダの実際の名前に合わせてください。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="webOSTVjs-1.2.13/webOSTV.js" charset="utf-8"></script>
<script src="webOSTVjs-1.2.13/webOSTV-dev.js" charset="utf-8"></script>
<script>
function openApp() {
webOS.service.request("luna://com.webos.applicationManager", {
method: "launch",
parameters: { id: "youtube.leanback.v4" },
onSuccess: function () { window.close(); },
onFailure: function () { window.close(); }
});
}
function handler(e) {
var d = e.detail || {};
var fromRemote = d.storeCaller === "remote" ||
(typeof d.contentTarget === "string" && d.contentTarget.indexOf("placement=partner_remote") !== -1);
if (fromRemote) { openApp(); }
}
document.addEventListener("webOSLaunch", handler, true);
document.addEventListener("webOSRelaunch", handler, true);
</script>
</head>
<body></body>
</html>
リモコンから呼ばれたときだけ YouTubeを起動するのには理由があります。テレビは起動時に、専用ボタンのアプリを先読みで起動することがあります。条件を付けずにYouTubeを開く作りにすると、電源を入れるたびにYouTubeが勝手に起動してしまいます。
5. パッケージ化してインストールする
ares-package launcher
ares-install -d lgtv ./com.disney.disneyplus-prod_0.0.3_all.ipk
これで、リモコンのDisney+ボタンを押すとYouTubeが開くようになります。
ハマったところ:Disney+ボタンでは画面が真っ暗になる
Netflix/Amazonボタン向けの記事では、起動条件は次のようになっています。
if (e.detail && e.detail.storeCaller === "remote") { openApp(); }
この条件のままDisney+ボタンを押すと、「YouTube Launcher」の画面が一瞬出たあと、真っ暗な画面のまま止まりました。
原因の調べ方
起動時に受け取った値を画面に表示するだけの、調査用ランチャーを作りました。appinfo.json の transparent を false にしてインストールします。YouTubeは起動しないので、勝手に起動し続けるループの心配もありません。
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<script src="webOSTVjs-1.2.13/webOSTV.js" charset="utf-8"></script>
<script src="webOSTVjs-1.2.13/webOSTV-dev.js" charset="utf-8"></script>
<style>
body { background: #000; color: #fff; font: 28px monospace; padding: 40px; white-space: pre-wrap; word-break: break-all; }
</style>
<script>
function log(label, value) {
var s;
try { s = typeof value === "string" ? value : JSON.stringify(value); } catch (err) { s = String(value); }
var el = document.getElementById("log");
if (el) { el.textContent += label + ": " + s + "\n"; }
else { (window._pending = window._pending || []).push([label, value]); }
}
log("PalmSystem.launchParams (head)", window.PalmSystem ? window.PalmSystem.launchParams : "no PalmSystem");
function handler(e) {
log(e.type + " detail", e.detail);
}
document.addEventListener("webOSLaunch", handler, true);
document.addEventListener("webOSRelaunch", handler, true);
window.addEventListener("load", function () {
(window._pending || []).forEach(function (p) { log(p[0], p[1]); });
window._pending = [];
});
</script>
</head>
<body><div id="log"></div></body>
</html>
結果
Disney+ボタンを押したときに渡された値は、次のとおりでした。
{
"contentTarget": "page=home&placement=partner_remote&placementDetail=lg_remote&distributionPartner=lg&numberOfRows=17&numberOfColumns=4&placementRow=15&placementColumn=0",
"handledBy": "app"
}
storeCaller はどこにもありませんでした。 代わりに、contentTarget に placement=partner_remote(placementDetail=lg_remote)が入っています。そのため元の条件に当てはまらず、透明な画面のまま止まっていた、というのが真っ暗になった原因です。
対処
起動条件に、contentTarget に placement=partner_remote が含まれている場合を追加しました(上の index.html はこの修正後のものです)。Netflix/Amazonボタン用の storeCaller の判定も残しているので、どのボタンにも使えるはずです。
テレビの電源を入れ直しても、YouTubeが勝手に起動し続けないことを確認しています。
ほかのボタンや機種でも、渡される値が違う可能性があります。うまくいかないときは、上の調査用ランチャーで実際の値を確認してみてください。
元に戻す方法
ares-install -d lgtv -r com.disney.disneyplus-prod
YouTubeが勝手に起動し続けてテレビを操作できなくなった場合も、PCからこのコマンドで削除できます。
注意:開発者モードには期限がある
- Developer Modeアプリには 残り時間(Remaining time) があります。0になると、インストールしたランチャーは自動で削除されます。
- アプリ内の 「Extend」ボタン で残り時間を延長できます。定期的に延長しておきましょう。
- 期限が切れた場合は、開発者モードをもう一度有効にして、
.ipkをインストールし直せば元に戻ります。パスフレーズが変わっている場合は、ares-setup-device -mで登録し直してください。
まとめ
- Disney+ボタン(appId
com.disney.disneyplus-prod)も、Netflix/Amazonボタンと同じ方法で別のアプリに割り当てられます。 - ただし、Disney+ボタンから呼ばれたときは
storeCallerが渡されず、contentTargetにplacement=partner_remoteが入ってきます。起動条件をこれに合わせる必要があります。 - うまく動かないときは、受け取った値を画面に表示する調査用ランチャーを作ると、原因をすぐ特定できます。