This project is in progress... ?, if you have any questions, please submit an issue. If you find it useful, you can give it a little star to encourage it. Thank you.
If you are interested in the project, you are welcome to join the channel for discussion and submit a PR.
ToDo List: https://github.com/orgs/OrdinaryRoad-Project/projects/1
Change log: https://github.com/OrdinaryRoad-Project/ordinaryroad-live-chat-client/releases
BarrageFly - Let the barrages fly, a barrage forwarding, filtering and processing platform based on this project
*Platform differences exist
- ✅: Platform supported and completed
- ☑️️: Platform supported but not implemented
- : The web version of the platform is not currently supported.
platform | LiveChatClient | Cookies | Short live room id | Send barrages | Like the host | Live broadcast room information* |
---|---|---|---|---|---|---|
Bilibili Station B | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Douyu Betta | ✅ | ✅ | ✅ | ✅ | ✅ | |
Huya Huya | ✅ | ✅ | ✅ | ✅ | ✅ | |
Douyin Douyin* | ✅ | ☑️️ | ✅ | ☑️ | ☑️️ | ✅ |
Kuaishou Kuaishou | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
TikTok* | ✅ | ✅ | ✅ | ☑️ | ☑️ | ✅ |
*Not fully supported yet, (Tiktok is under testing)
*The live broadcast room information currently only supports obtaining the live broadcast room title.
platform | Barrage | Gift | Eye-catching message | Enter the room | Like | status change | Statistics | social news |
---|---|---|---|---|---|---|---|---|
Bilibili Station B | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅(Number of likes, current number of people, cumulative number of viewers) | |
Douyu Betta | ✅ | ✅ | ☑️ | ✅ | ☑️ | |||
Huya Huya | ✅ | ✅ | ✅ (Premium users) | ☑️ | ||||
Douyin Douyin | ✅ | ✅ | ✅ | ✅(Number of likes) | ✅ | ✅(Number of likes, current number of people) | ✅(share, follow) | |
Kuaishou Kuaishou | ✅ | ✅(Incomplete gift information) | ✅(First like) | ✅(Number of likes, current number of people) | ||||
TikTok | ✅ | ✅ | ✅ | ✅(Number of likes) | ✅ | ✅(Number of likes, current number of people) | ✅(share, follow) |
For the built-in methods of the message interface, see https://github.com/OrdinaryRoad-Project/ordinaryroad-live-chat-client/tree/main/live-chat-client-commons/live-chat-client-commons-base/src/ main/java/tech/ordinaryroad/live/chat/client/commons/base/msg
Operation renderings
Capture the browser's WebSocket binary stream, and then analyze and simulate the browser's behavior; the advantage of this method is that it does not require developer certification, but the disadvantage is that there is no official document, the analysis process is time-consuming and laborious, and it needs to adapt to the process changes of different platforms (does not change often)
In the future, we may consider supporting open protocols for the platform
JDK≥8
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-bilibili</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
Note for Gradle users: Since version
0.3.2
, in the client configuration of station B, the compression method defaults toNORMAL_BROTLI
. When using Gradle to introduce it, you also need to introduce the brotli4j native package corresponding to the operating system. For details, see: https://github.com /hyperxpro/Brotli4j?tab=readme-ov-file#gradle
For example:
val liveChatClientBrotliVersion = " 1.16.0 "
// Windows
implementation( " com.aayushatharva.brotli4j:native-windows-x86_64: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-windows-aarch64: $l iveChatClientBrotliVersion " )
// Linux
implementation( " com.aayushatharva.brotli4j:native-linux-armv7: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-linux-aarch64: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-linux-x86_64: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-linux-s390x: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-linux-riscv64: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-linux-ppc64le: $l iveChatClientBrotliVersion " )
// Mac
implementation( " com.aayushatharva.brotli4j:native-osx-aarch64: $l iveChatClientBrotliVersion " )
implementation( " com.aayushatharva.brotli4j:native-osx-x86_64: $l iveChatClientBrotliVersion " )
If it still cannot be used after introduction, please modify the protover configuration item, for example, change it to NORMAL_ZLIB
: BilibiliLiveChatClientConfig.builder().protover(ProtoverEnum.NORMAL_ZLIB).roomId("xxx").build()
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-douyu</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-huya</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-douyin</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-kuaishou</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
The test class contains a variety of samples for reference
You can override onCmdMsg(收到的所有CMD消息)
or onOtherCmdMsg(框架未处理的CMD消息)
callback method to determine the CMD to listen for the CMD type that the framework has defined.
If the message enumeration class you want to listen to is not defined, you can consider overriding onUnknownCmdMsg(未知CMD消息)
method
ICmdMsg type conversion correspondence
@ Override
public void onOtherCmdMsg ( BilibiliCmdEnum cmd , ICmdMsg < BilibiliCmdEnum > cmdMsg ) {
switch ( cmd ) {
case GUARD_BUY : {
// 有人上舰
MessageMsg messageMsg = ( MessageMsg ) cmdMsg ;
...
break ;
}
case SUPER_CHAT_MESSAGE_DELETE : {
// 删除醒目留言
MessageMsg messageMsg = ( MessageMsg ) cmdMsg ;
...
break ;
}
default : {
// ignore
}
}
}
Spring Boot example client-example
If you need to check the effect on other platforms, please change
Bilibili
to English corresponding to other platforms, and modify the function signature of the message callback interface.
public class ClientModeExample {
public static void main ( String [] args ) {
String cookie = System . getenv ( "cookie" );
// 1. 创建配置
BilibiliLiveChatClientConfig config = BilibiliLiveChatClientConfig . builder ()
// TODO 消息转发地址
. forwardWebsocketUri ( "" )
// TODO 浏览器Cookie
. cookie ( cookie )
// TODO 直播间id(支持短id)
. roomId ( 7777 )
. build ();
// 2. 创建Client并传入配置、添加消息回调
BilibiliLiveChatClient client = new BilibiliLiveChatClient ( config , new IBilibiliMsgListener () {
@ Override
public void onDanmuMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , DanmuMsgMsg msg ) {
IBilibiliMsgListener . super . onDanmuMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 收到弹幕 %s %s(%s):%s n " , binaryFrameHandler . getRoomId (), msg . getBadgeLevel () != 0 ? msg . getBadgeLevel () + msg . getBadgeName () : "" , msg . getUsername (), msg . getUid (), msg . getContent ());
}
@ Override
public void onGiftMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , SendGiftMsg msg ) {
IBilibiliMsgListener . super . onGiftMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 收到礼物 %s %s(%s) %s %s(%s)x%s(%s) n " , binaryFrameHandler . getRoomId (), msg . getBadgeLevel () != 0 ? msg . getBadgeLevel () + msg . getBadgeName () : "" , msg . getUsername (), msg . getUid (), msg . getData (). getAction (), msg . getGiftName (), msg . getGiftId (), msg . getGiftCount (), msg . getGiftPrice ());
}
@ Override
public void onSuperChatMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , SuperChatMessageMsg msg ) {
IBilibiliMsgListener . super . onSuperChatMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 收到醒目留言 %s(%s):%s n " , binaryFrameHandler . getRoomId (), msg . getUsername (), msg . getUid (), msg . getContent ());
}
@ Override
public void onEnterRoomMsg ( InteractWordMsg msg ) {
System . out . printf ( "%s %s(%s) 进入直播间n " , msg . getBadgeLevel () != 0 ? msg . getBadgeLevel () + msg . getBadgeName () : "" , msg . getUsername (), msg . getUid ());
}
@ Override
public void onLikeMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , LikeInfoV3ClickMsg msg ) {
IBilibiliMsgListener . super . onLikeMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 收到点赞 %s %s(%s) n " , binaryFrameHandler . getRoomId (), msg . getBadgeLevel () != 0 ? msg . getBadgeLevel () + msg . getBadgeName () : "" , msg . getUsername (), msg . getUid ());
}
@ Override
public void onLiveStatusMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , BilibiliLiveStatusChangeMsg msg ) {
IBilibiliMsgListener . super . onLiveStatusMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 状态变化 %s n " , binaryFrameHandler . getRoomId (), msg . getLiveStatusAction ());
}
@ Override
public void onRoomStatsMsg ( BilibiliBinaryFrameHandler binaryFrameHandler , BilibiliRoomStatsMsg msg ) {
IBilibiliMsgListener . super . onRoomStatsMsg ( binaryFrameHandler , msg );
System . out . printf ( "%s 统计信息 累计点赞数: %s, 当前观看人数: %s, 累计观看人数: %s n " , binaryFrameHandler . getRoomId (), msg . getLikedCount (), msg . getWatchingCount (), msg . getWatchedCount ());
}
});
// 添加客户端连接状态回调
client . addStatusChangeListener (( evt , oldStatus , newStatus ) -> {
if ( newStatus == ClientStatusEnums . CONNECTED ) {
// TODO 要发送的弹幕内容,请注意控制发送频率;框架内置支持设置发送弹幕的最少时间间隔,小于时将忽略该次发送
client . sendDanmu ( "666666" + RandomUtil . randomNumbers ( 1 ));
}
});
// 3. 开始监听直播间
client . connect ();
}
}
void connect(Runnable success, Consumer<Throwable> failed)
void connect(Runnable success)
void connect()
void disconnect(boolean cancelReconnect)
void disconnect()
void destroy()
void send(Object msg, Runnable success, Consumer<Throwable> failed)
void send(Object msg, Runnable success)
void send(Object msg, Consumer<Throwable> failed)
void send(Object msg)
void sendDanmu(Object danmu, Runnable success, Consumer<Throwable> failed)
void sendDanmu(Object danmu, Runnable success)
void sendDanmu(Object danmu, Consumer<Throwable> failed)
void sendDanmu(Object danmu)
void clickLike(int count, Runnable success, Consumer<Throwable> failed)
void clickLike(int count, Runnable success)
void clickLike(int count, Consumer<Throwable> failed)
void clickLike(int count)
boolean addMsgListener(MsgListener msgListener)
boolean addMsgListeners(List<MsgListener> msgListeners)
boolean removeMsgListener(MsgListener msgListener)
boolean removeMsgListeners(List<MsgListener> msgListeners)
ClientStatusEnums getStatus()
void addStatusChangeListener(IClientStatusChangeListener listener)
void removeStatusChangeListener(IClientStatusChangeListener listener)
ReferenceBilibiliHandlerModeExample
Refer to codec-example
Example of station B, other platforms only need to modify bilibili
When using Gradle to introduce the encoding and decoding module of B station, refer to #B station
< dependency >
< groupId >tech.ordinaryroad</ groupId >
< artifactId >live-chat-client-codec-bilibili</ artifactId >
<!-- 参考github release版本,不需要前缀`v` -->
< version >${ordinaryroad-live-chat-client.version}</ version >
</ dependency >
Effective scope: only the project itself, will not affect parent projects that reference the project
Modify Config socks5ProxyHost("127.0.0.1")
, socks5ProxyPort("1080")
in the code
Identity authentication (not tested yet)
socks5ProxyUsername("username")
, socks5ProxyPassword("password")
Scan the QR code to join the QQ/WeChat channel, or click the link to join the QQ channel [OrdinaryRoad]: https://pd.qq.com/s/3id0n7fvs
Open source is not easy, your recognition and support are my biggest motivation to keep updating!
date | Donor | Amount | message | channel |
---|---|---|---|---|
2024-03-06 | **Rui | 88.88 | Come on man | ZFB |
2024-03-10 | **hao | 88.8 | Come on, boss | ZFB |
2024-03-25 | **Wave | 188.8 | / | ZFB |
2024-04-02 | **hao | 30 | / | ZFB |
2024-04-30 | *h | 100 | Boss is awesome | wx |
2024-11-18 | *Lei | 200 | / | wx |
... | ... | ... | ... | ... |
Disclaimer: For academic research use only. The developer is not responsible for any abuse that violates relevant laws and causes harm.
Keywords: barrage crawler barrage crawler barrage crawler