ての字のブロマガ

ニコ生コメントビューワを作ったメモ

2021/03/10 21:35 投稿

  • タグ:
  • Java
2021/03/09~10にニコ生コメントビューワを作ってみたときのメモです。

■俺がしたいこと、しなくていいこと
・自分の生放送専用(コミュニティ生放送、放送者がプレミアムアカウント)
・コミュ限での放送も動作確認
・コメント投稿機能は不要(運営コメントはブラウザの放送ページで入力する)
・とりあえず、既に流れたコメントは不要。ビューワ起動後の新しいコメントだけ受け取る

■その他したこと
・棒読みちゃんと連携して読み上げを行なう
・アンコちゃんのデータベースの情報で、ID→コテハン変換する

■開発環境
 JDK:Java7 (古い!そのせいもあって以下も諸々古い!)
 追加ライブラリ:
  Jackson 2.12.2
   jackson-core-2.12.2.jar
   jackson-annotations-2.12.2.jar
   jackson-databind-2.12.2.jar
  Eclipse Tyrus
   tyrus-standalone-client-1.9.jar
 IDE:Eclipse Kepler

■プロトコル手順

1-1)放送ページ (https://live2.nicovideo.jp/watch/lv~) の HTML を得る
1-2)broadcastId or reliveProgramId, audienceToken, frontendId を得る
1-3)視聴用WebSocketURIを作る(以下のようになる)
wss://a.live2.nicovideo.jp/unama/wsapi/v2/watch/$broadcastId?audience_token=$audienceToken&frontend_id=$frontendId
2-1)上記WebSocketに接続する。
2-1-1)User-Agent の指定が必要。
//Tyrus使用、ClientEndpointConfig.Configurator 継承クラス
public void beforeRequest(Map<String, List<String>> headers) {
headers.put("User-Agent", Arrays.asList(
"Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:86.0) Gecko/20100101 Firefox/86.0"
));
}
2-2)WebSocketにJSONでリクエストを送る(改行・インデント不要)
{
"type":"startWatching",
"data":{
"stream":{
"quality":"low",
"protocol":"hls",
"latency":"low"
},
"room":{
"protocol":"webSocket",
"commentable":true,
"reconnect":true
}
}
}
2-3)受け取ったJSONデータから、コメント受信用WebSocketURIと、スレッドIDを得る
3-1)コメント受信用WebSocketに接続する。
3-1-1)下記の指定が必要。
//Tyrus使用、ClientEndpointConfig.Configurator 継承クラス
public void beforeRequest(Map<String, List<String>> headers) {
headers.put("Sec-WebSocket-Protocol", Arrays.asList("msg.nicovideo.jp#json"));
}
3-2)WebSocketにJSONリクエストを送る
  ★これで過去コメントがもらえるはずが、ダメ。とりあえずいいんだけど、直したい
[
{"ping":{"content":"rs:0"}},
{"ping":{"content":"ps:0"}},
{
"thread": {
"thread":"$threadId",
"version":"20061206",
"fork":0,
"user_id":"guest",
"res_from":-1000,
"with_global":1,
"scores":1,
"nicoru":0
}
},
{"ping":{"content":"pf:0"}},
{"ping":{"content":"rf:0"}}
]
3-3)受け取ったデータから、ユーザID とコメント本文を得る

あとは適宜表示、および棒読みちゃんに送信する。

<追記>
3-1)で接続した WebSocket には、適宜 ping を送る。数秒間隔ぐらい?
2-1)のほうも、接続者数などのデータをくれるので、必要に応じて送る。
//@OnOpen にしたメソッドとかでループ開始
new Thread(new Runnable() {
public void run() {
  while (! closed) { //@OnClose にしたメソッドで closed = true に
try {
Thread.sleep(3000); //とか
session.getBasicRemote().sendPing(null);
} catch (InterruptedException ex) {
ex.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}
}
}
}).start();

■その他メモ
・以前は Firefox が記憶している Cookie 情報を流用していたが、無くとも動いてる
・ログインも必要ない
・だもんで自分以外の放送もいける、しかもチャンネル生放送でも受信できた

う○ょちさんの放送をコソーリ

コメント

コメントはまだありません
コメントを書き込むにはログインしてください。

いまブロマガで人気の記事