Claude Code でテレビの広告を追いかけ、寝かしつけの音楽をかける
先週、ADB を使って Claude Code とうちのソニーのテレビをつないだ話を書きました。あの記事は準備編です。テレビを見つけて、デバッグをオンにして、地域を直して、アプリを入れるまで。まだの人はそちらからどうぞ。
今回は、つながったままになっていたその接続で、そのあと何をしたかの話です。1 日もたたないうちに 2 回使いました。昨夜は、見るはずのない広告を消すため。今朝は、娘に音楽をかけるため。片方は終わっていて、もう片方はまだ途中です。読んで役に立つのは、たぶん途中のほうです。
お金を払っているアプリに広告が出る
私はスポーツの動画配信アプリにお金を払っています。それでも見逃し配信を開くと、最初に広告が流れます。画面の隅には小さく Ad 1 of 1 の表示。払っているのに広告を見せられるのは、自分でも意外なくらい気になります。そこで Claude に、広告を消してほしいと頼みました。
まず思いつくのはアプリを改造することです。Claude は手を動かす前に、それがそもそも可能かどうかを確かめました。ADB でテレビから APK を取り出し、dex ファイルの中に動画広告でよく使われる仕組みの痕跡がないか探しました。Google IMA、FreeWheel、Yospace、動的広告挿入、VAST と VMAP です。
adb shell pm path <package>
adb pull <path-from-above> app.apk
unzip -o app.apk -d app/
答えはノーでした。このアプリは Cordova の殻だったのです。ネイティブ部分は薄い包みにすぎず、プレーヤーも広告も、アプリの起動時にサービス側のサーバーから JavaScript として届きます。APK をいくら改造しても広告は出続けます。そもそも APK の中にないからです。
この答えには満足しました。数分で分かったおかげで、絶対にうまくいかない作業に一晩使わずにすみました。
DNS で広告を止める
アプリを変えられないなら、テレビがどこにつながれるかを変えればいい。Android TV には、Android スマホと同じ「プライベート DNS」の設定があります。これをフィルタ付きの DNS サーバーに向けると、テレビのすべてのアプリがそのサーバーに住所を問い合わせるようになります。既知の広告サーバーを聞かれたら、フィルタは何も返しません。
テレビのネットワーク設定からでも、ADB からでも設定できます。
adb shell settings put global private_dns_mode hostname
adb shell settings put global private_dns_specifier dns.adguard-dns.com
このホスト名は AdGuard の公開フィルタです。Claude が設定し、既知の広告ドメインがどこにもつながらなくなったのを確認してから、見逃し配信を開きました。広告は普通に流れました。
次の手は、個人用の AdGuard DNS サーバーです。無料アカウントで自分専用のサーバーが持てて、テレビ用のデバイスを登録すると、そのデバイス専用のプライベート DNS のホスト名、クエリログ、カスタムルールが使えます。テレビの切り替えは 1 行です。
adb shell settings put global private_dns_specifier <your-id>.d.adguard-dns.com
わざわざこれをやる理由はクエリログです。公開フィルタは中が見えません。自分のサーバーなら、テレビが問い合わせた先がすべて、順番どおり、リアルタイムで見えます。
変わるのはテレビだけ
最初に聞いたのは、ノートパソコンや家の Wi-Fi に影響が出ないかでした。出ません。プライベート DNS は 1 台の機器の設定です。テレビは暗号化された接続でそのホスト名に問い合わせを送り、ホスト名に入っている ID で、AdGuard はどの機器からの問い合わせかを判断します。Mac はこれまでどおりの DNS を使い続けます。ルーターも、家にあるほかの機器も同じです。
だから元に戻すのも簡単です。これでテレビはネットワークの普通の DNS に戻ります。
adb shell settings put global private_dns_mode opportunistic
広告が 2 回出なくても証拠にはならない
切り替えたあと、見逃し配信を 2 本見ました。どちらも広告なし。ここで勝ったことにするのは簡単でした。
Claude はそうしませんでしたし、それが正解でした。新しいサーバーのブロックリストは、すでに効かなかった公開フィルタとまったく同じだったからです。ブロックの中身は何も変わっていません。広告が出なかった理由として可能性が高いのは、フリークエンシーキャップです。同じ人に何度か広告を見せると、広告サーバーがしばらく出さなくなる仕組みです。一晩テストしたあとに静かな再生が 2 回続くのは、まさにそう見えます。
本当のテストは、もっと地味で時間がかかります。
- テレビのクエリログを開く。
- 新しい見逃し配信を再生し、広告が実際に出るまで流しておく。
- 広告が出る直前の数秒の問い合わせを読み、広告を配信したホストを見つける。
- そのホストにカスタムルールを追加する。たとえば
||ads.example.com^。 - もう一度再生して、2 つを確認する。広告が出ないこと。そして試合そのものはちゃんと再生されること。
最後の確認が大事です。違うホストをブロックすると、広告と一緒に映像まで止まることがあります。
そして、やめるべき地点もあります。サービスによっては、自社のサーバー側で広告を本編と同じ映像ストリームに縫い込んでいます。サーバーサイド広告挿入と呼ばれるやり方です。広告が試合と同じホストから来るなら、DNS には切り分けようがありません。ホストを止めれば両方とも消えます。
このアプリがどちらなのかは、まだ分かりません。それは次の再生で分かります。今あるのは方法と、推測ではなく目で見て確かめられるフィルタです。
寝かしつけのリモコンとしてのテレビ
今朝のほうは簡単でした。Claude Code に英語で 1 行だけ打ちました。
open youtube, piano sleeping disney songs for my daughter
どのテレビか、どのアプリか、どうやるかは言っていません。Claude は ADB の接続がまだ生きているかを確かめ、テレビに入っている YouTube のパッケージを見つけました。それから、まず素直な方法として、検索語をつけた SEARCH インテントを試しました。テレビのアプリはこれを無視しました。
途中で小さな落とし穴がひとつ。最初の試行では、検索語がスペースのところで分かれてしまいました。テレビ側のシェルが、単語ごとに別の引数だと受け取ったからです。am start のコマンド全体を adb shell "..." の引用符で包み、その中で検索語もさらに引用符で囲みます。
次に YouTube のプロフィール選択画面が出ました。Claude は Premium のプロフィールを選びました。子守唄の途中に広告が入らないようにです。
うまくいったのは、普通の YouTube の検索 URL を渡す VIEW インテントでした。テレビのアプリは、それをそのまま検索結果の画面で開きます。
adb shell "am start -a android.intent.action.VIEW \
-d 'https://www.youtube.com/results?search_query=piano+sleeping+disney+songs' \
com.google.android.youtube.tv"
フォーカスは一番上の結果に当たっているので、決定ボタンを 1 回押せば再生が始まります。
adb shell input keyevent KEYCODE_DPAD_CENTER
一番上は、ディズニーの曲をピアノで弾いた、ぐっすり眠るための 6 時間のメドレーでした。これで十分です。
本当に再生されているかを確かめる
私が一番大事だと思っているのはここです。決定ボタンを押しただけでは仕事は終わりません。Claude は結果を 2 つの方法で確かめました。
まず、テレビのメディアセッションを読みました。Android が「今これが再生中」とシステムに伝えるための仕組みです。
adb shell dumpsys media_session | grep -E "state=|description="
ここから再生状態、タイトル、再生位置が分かります。state 3 は再生中という意味です。次に、画面に実際に何が映っているかをスクリーンショットで確認しました。
adb exec-out screencap -p > tv.png
どちらも一致していました。しかも再生位置から、私なら見落としていたことが分かりました。動画は最初からではなく、6 時間 14 分のうち 4 時間 13 分のところから再開していたのです。Claude はそれを伝えてくれて、最初からかけ直すかと聞いてきました。
小さなことに見えますが、寝かしつけを任せられるのはこういうところです。決定ボタンを押すだけのスクリプトなら「成功しました」と言って終わりです。Claude は、テレビに今何が映っているかを、私が確かめなかったはずの部分まで含めて教えてくれました。
同じ接続で、2 つの仕事
どちらも、先週つくった ADB の接続だけで動いています。スマートホームのハブも、テレビに入れる追加のアプリもありません。
振り返ると、2 つの仕事は同じ形をしていました。広告のほうでは、静かな再生が 2 回続いたことを証拠として認めなかった。YouTube のほうでは、ボタンを押したことを再生とは認めなかった。どちらのときも、私に何か言う前に自分で見に行っていました。娘が眠りにつくあいだテレビを動かしてもらうなら、まさにそうしてほしいのです。