ニコ生コメントビューア「ちえちゃんと秋ちゃん for nicolive」v2.7.0をリリースしました。
バックグラウンドで主コメントが読まれない——この不具合を、私は6セッションにわたって追い続けていました。ログを取り、仮説を立て、直し、それでも読まれない。
その繰り返しの果てにたどり着いた真因は、あまりにも身近な場所にありました。
この記事は、その一日の記録です。
この記事のポイント
- 6セッション追った不具合の真因は、前日に入れた診断コードだった
- 「320が主コメを教えていたはず」という自分の記憶が突破口に
- 画面を閉じても止まらない読み上げ。買い切り型コメビュ
8分59秒でわかるまとめ動画
「壊したのは自分たちだった」
その一言を私が口にしたとき、すべてが動き出した。
ニコ生コメントビューア「ちえちゃんと秋ちゃん for nicolive」。バックグラウンドで主コメント(配信者のコメント)が読み上げられない——この不具合を、私はもう6セッション追いかけていた。
ログを取る。仮説を立てる。修正する。読まれない。またログを取る。
その繰り返しの中で、私たち(私とClaude)は何度も「主コメは全経路に不在」という結論に達していた。ndgr protobuf の全ルートを洗った。native も JS も見た。どこにも主コメの痕跡がない。だから「別の輸送路があるはずだ」と探し続けていた。
全部、間違いだった。
前日に入れた診断コード——通信経路を調べるための、たった数十行——が、WebView の chat 傍受を壊していた。診断が本体を壊し、その壊れた状態で6回分の結論を出していたのだ。
「最近入れたコードを疑え」。開発者なら誰もが知っている鉄則だ。だが自分たちが調査のために書いたコードは、無意識に「調べる側」だと思い込んでいて、容疑者リストから外れていた。
診断コードを撤去した瞬間、前面(フォアグラウンド)の主コメは何事もなかったかのように読み上げられた。
6セッション。あの時間は、何だったのか。
「320コメが主コメだと教えていたはずだ」
だが、バックグラウンドはまだ死んでいた。
ここで、私の頭に引っかかっていたことがあった。「320コメを弾くようにしてるじゃないか」
ニコ生の ndgr プロトコルでは、主コメには no=320 という疑似番号が振られる。以前、これを通常のコメント番号として扱ったせいで無限ループが起きたため、「320は番号なしフレームとして別経路へ回す」という設計にしてあった。自分で書いた設計だ。だから覚えていた。
コードを読み直す。320 は捨てられていなかった。ちゃんと別経路に流れていた。しかし、その先が問題だった。
診断ログを1行だけ仕込んで、配信者さんにテストを頼む。結果——
[PSEUDO-NO-SPLIT] route=BACKWARD kind=pseudo no=320 len=312 ← 92件
主コメは届いていた。バックグラウンドの10分間で92回も。なのに読み上げ検知は0件。
自分の記憶は正しかった。320は、ちゃんと主コメの目印として機能していた。問題はその先にあった。
真因は2つ重なっていた
1つ目。 過去ログを取り直す BACKWARD 経路には「前回も居たフレームは再送だから捨てる」というフィルタがある。そして主コメのフレームは len=312 で、中身が一切変わらない。
BACKWARD は毎サイクル同じ過去窓を取り直す。つまり主コメは2バッチ目以降、永久に「再送」と判定されて捨てられていた。
決定的な裏付けがあった。このフィルタを通過していたのは、来場通知だけ。来場通知は「誰が来たか」で毎回中身が変わるから通れる。主コメは変わらないから通れない。「延長しました」だけが読めていたのも、文面が毎回変わるからだった。すべて辻褄が合った。
フィルタを免除して通す。それでも読まれなかった。
2つ目。 通した先に、もう一つの壁があった。
s.none { it.code in 1..31 } // 制御文字が1つでもあれば全滅
主コメの文字列は Protobuf のバイナリ制御文字が混じった「汚れた文字列」だ。このフィルタで全滅し、静かに捨てられていた。
native には、主コメの本文を取り出す手段が最初から存在しなかったのだ。
では、なぜ前面では読めるのか。答えは WebView 側にあった。JS はマーカー 0x1A 0x02 0x08 0x0F をバイトスキャンし、その手前の Protobuf length-prefix から本文を厳密に切り出していた。native にはそれが無い。ただ、それだけの話だった。
自分で書いた JS のアルゴリズムを、自分で native へ移植する。実際のフレームを再現して抽出を検証してから投入した。
[OWNER-MARKER-SALVAGE] route=BRIDGE len=7 text=山手線沿線通り
→ 23ms後に読み上げ
読んだ。ついに、バックグラウンドで主コメが読まれた。
広告もまた、同じ病気だった
主コメが直ると、次は広告だった。3回流れたのに1回しか読まれない。しかも遅い。
診断を仕込み、広告フレームを base64 で丸ごとダンプして完全にデコードした。
f2.f9.f2.f2 str="【広告貢献2位】ドラマのちえさんが200ptニコニ広告しました"
4階層目に、完全な読み上げ可能文が入っていた。 既存の検知は「f2にキャンペーンID、f4に本文」という旧形式を前提にしていて、新形式のフレームには一生マッチしない。ニコ生側のフォーマットが変わっていたのだ。
さらに、ギフトには入れていた「即時経路なら待たずに読んでよい」という修正が、広告には入っていなかった。過去の自分の修正漏れ。これが遅延の正体だった。
新形式の抽出を書き、実フレームで検証し、ゲートを揃える。
[NICOAD-SENTENCE] route=BRIDGE → 21ms後に読み上げ
検知漏れも遅延も、同時に消えた。
秒で管理するものは、ことごとくバグの原因になる
最後にもう一つ、象徴的なことがあった。
主コメが読まれるようになった後、「同じ文面をもう一度打つと読まれない」という症状が出た。原因は「本文が同じなら600秒間は読まない」という重複防止だった。BACKWARD の再送を防ぐつもりが、配信者が定型の宣伝文を再投稿するという当たり前の行為を潰していた。
修正案として「120秒の短い窓にする」という話が出たが、私は止めた。
秒で管理するものは、ことごとくバグの原因になる。
実際この日だけで、時間窓が原因のバグを3つ潰していた。ギフトの590秒一斉発火、広告の10分後再読、そしてこの再投稿黙殺。全部、時計に頼ったせいだ。
そこで、フレームに埋め込まれた投稿タイムスタンプをキーにした。サーバーが投稿時に刻んだ値だから、何秒経とうが変わらない。再送は同じキー、再投稿は違うキー。時計は一切使わない。
これで主コメ経路から、時間に依存するロジックが完全に消えた。
この設計判断は、今後もずっと効いてくるはずだ。
このアプリの売りは、「画面を閉じても止まらない」こと
ここまで読んで、「なぜそこまでバックグラウンドにこだわるのか」と思われたかもしれない。
理由は単純だ。ニコ生を聴きながら他のことをしたいから。
移動中にポケットに入れたまま。作業しながら裏で。スマホでコメビュを開きっぱなしにできる人は、そう多くない。画面を閉じた瞬間に読み上げが止まるコメビュは、スマホのコメビュとして半分死んでいる。
だから私はここに執着してきた。
- 一般コメントも、主コメントも、広告も、ギフトも、来場通知も、画面を閉じたまま読む
- 読み上げ種別(運営・広告・ギフト)は個別にオン・オフできる
- 前面に戻ったとき、バックグラウンド中のコメントがきちんと画面に揃う
最後の一つも、この日に直した。前面復帰時にコメントが1件だけ表示から欠ける現象があり、追ってみると「既読リストには登録済みなのに表示リストには居ない」という毒されたIDが原因だった。既読登録が表示確定より手前にあり、その間に12個の脱出経路がある。どれか1つを踏むと、そのコメントは永久に表示されなくなる構造だった。
修復専用の経路を作り、「既読かどうか」ではなく「実際に表示されているか」で判定するようにした。
アプリの購入はこちらから
そして v2.7.0 へ
一日で、これだけ直った。
- コメント取得が「待機中」のまま進まない不具合
- 主コメントが読まれない不具合(前面・バックグラウンド共)
- 同じ文面の主コメント再投稿が読まれない不具合
- バックグラウンドで一般コメント・広告・ギフトが読まれない不具合
- 広告読み上げの検知漏れと遅延
- バックグラウンド復帰時にコメント表示が欠ける不具合
- 番組参加時にまれに落ちる不具合
- 読み上げ種別の個別オン・オフ対応
正直に言えば、この日は誤診の連続だった。ログの読み違いで何度も見当違いの方向へ走り、そのたびに配信者さんに主コメを打ち直してもらった。「いい加減にしてくれ。配信者にも迷惑がかかる」——そう言わざるを得ない場面もあった。
それでも最後まで付き合ってくれた配信者さん、テスターの皆さん、そして iPhone 版を仕上げてくれた ちえ さんに、心から感謝したい。
真因は、いつも「確認していない場所」に潜んでいる。今日それを、6セッション分の遠回りで思い知った。
「ちえちゃんと秋ちゃん for nicolive」は Android / iPhone 対応、買い切り型です。 月額課金ではありません。一度買えば、ずっと使えます。
今ならなんと、26日まで半額セールを実施中!
ニコ生を、画面を閉じたまま楽しんでください。

