go_bili_chat

package module
v0.5.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 28, 2023 License: AGPL-3.0 Imports: 8 Imported by: 0

README

Bilibili 直播间弹幕处理库

golang的b站信息流处理 支持近百种消息命令类型 高性能 低占用的信息流处理库,包含弹幕/礼物/大航海/SC等一切你想要的数据

介绍

go-bili-chat 是一个用于处理 Bilibili 直播间信息流库,可以用于开发自己的 Bilibili 直播间信息流处理程序。

b站直播间信息流以Websocket传输并加密, 含有几十个不同的命令, 本项目对其进行了解析, 并提供了一些简单的处理方法, 以便于开发者快速开发自己的程序。

快速使用

信息流处理流程为: 客户端收到信息 -> 解析后由处理器进行分发

因此, 你需要先将命令处理函数绑定到处理器, 再开启直播间进行处理,

1. 一个简单的使用示例:
package main

import (
	"fmt"
	bili "github.com/FishZe/go-bili-chat"
	handle "github.com/FishZe/go-bili-chat/handler"
)

func main() {
	// 新建一个命令处理器
	h := bili.GetNewHandler()
	// 注册一个处理,将该直播间的弹幕消息绑定到这个函数
	h.AddOption(handle.CmdDanmuMsg, 26097368, func(event handle.MsgEvent) {
		// 打印出弹幕消息
		fmt.Printf("[%v] %v: %v\n", event.RoomId, event.DanMuMsg.Data.Sender.Name, event.DanMuMsg.Data.Content)
	})
	// 连接到直播间
	_ = h.AddRoom(26097368)
	// 启动处理器
	h.Run()
}

特殊地, 绑定函数的直播间号为0时,绑定所有房间

2. 也可以先运行命令处理器,再添加房间:
package main

import (
	"fmt"
	bili "github.com/FishZe/go-bili-chat"
	handle "github.com/FishZe/go-bili-chat/handler"
	"time"
)

func main() {
	h := bili.GetNewHandler()
	// 运行处理器
	go h.Run()
	h.AddOption(handle.CmdDanmuMsg, 26097368, func(event handle.MsgEvent) {
		fmt.Printf("[%v] %v: %v\n", event.RoomId, event.DanMuMsg.Data.Sender.Name, event.DanMuMsg.Data.Content)
	})
	_ = h.AddRoom(26097368)
	for {
		time.Sleep(time.Second)
	}
}
3. 当然了,也可以删除房间:
package main

import (
	"fmt"
	bili "github.com/FishZe/go-bili-chat"
	handle "github.com/FishZe/go-bili-chat/handler"
)

func main() {
	h := bili.GetNewHandler()
	h.AddOption(handle.CmdDanmuMsg, 26097368, func(event handle.MsgEvent) {
		fmt.Printf("[%v] %v: %v\n", event.RoomId, event.DanMuMsg.Data.Sender.Name, event.DanMuMsg.Data.Content)
	})
	_ = h.AddRoom(26097368)
	_ = h.DelRoom(26097368)
	h.Run()
}
4. 还可以删除处理函数
package main

import (
	"fmt"
	bili "github.com/FishZe/go-bili-chat"
	handle "github.com/FishZe/go-bili-chat/handler"
)

func main() {
	h := bili.GetNewHandler()
	danmu := h.AddOption(handle.CmdDanmuMsg, 26097368, func(event handle.MsgEvent) {
		fmt.Printf("[%v] %v: %v\n", event.RoomId, event.DanMuMsg.Data.Sender.Name, event.DanMuMsg.Data.Content)
	})
	_ = h.AddRoom(26097368)
	h.DelOption(danmu)
	h.Run()
}
5. 对于连接房间过多的情况, 建议先go h.Run()再添加房间, 否则会阻塞通道造成内存大量占用
go h.Run()
_ = h.AddRoom(26097368)
_ = h.AddRoom(26097369)
_ = h.AddRoom(26097370)
// sth...

关于为什么在处理绑定函数时, 多一个直播间号的参数, 因为考虑到可能会有根据不同的直播间分发处理消息的需求

6. 也可以获得当前的连接房间个数
sum := h.CountRoom()
fmt.Println("当前连接房间数: ", sum)
7. 对于接入的服务器: 程序提供了3个模式:
DefaultPriority: 默认模式, 按照b站提供的顺序进行连接
DelayPriority: 低延迟模式, 将会在连接前计算到所有提供的服务器的延迟, 并选择最低的(连接会慢一些)
NoCDNPriority: 不使用CDN模式, 适合大量连接的情况

默认使用的模式为DefaultPriority, 有需要的可以使用这种方式修改:

bili.SetClientPriorityMode(bili.DelayPriority)
8. 默认使用的Json解析器为sonic, 有需要自定义json解析器的可以使用这种方式:
type Json struct{}

func (j *Json) Unmarshal(data []byte, v interface{}) error {
	return json.Unmarshal(data, v)
}

func (j *Json) Marshal(v interface{}) ([]byte, error) {
    return json.Marshal(v)
}

bili.SetJsonCoder(&Json{})

具体的示例代码可以查看example/main.gp

9. 对于需要查看DEBUG日志的情况, 可以修改日志等级
bili.ChangeLogLevel(log.DebugLevel)

开启DEBUG日志后, 可以看到所有的数据包和分发过程, 如果想要直观的看到分发到的函数名称, 可以在AddOption中写明该函数的备注名

h.AddOption(handle.CmdDanmuMsg, 21545805, func(event handle.MsgEvent) {
    fmt.Printf("[%v][弹幕] %v (%v): %v\n", event.RoomId, event.DanMuMsg.Data.Sender.Name, event.DanMuMsg.Data.Medal.MedalName, event.DanMuMsg.Data.Content)
}, "弹幕处理")

控制台会显示类似如下的日志

[bili-live][02-21 16:42:55][DEBUG]: distribute DANMU_MSG cmd to 弹幕处理
所有支持的消息类型:

这些常量请填入go-bili-chat.GetNewHandler().AddOption()的第一个参数

变量名 命令类型 含义
CmdDanmuMsg "DANMU_MSG" 弹幕消息
CmdLikeInfoV3Click "LIKE_INFO_V3_CLICK" 直播间点赞信息
CmdSuperChatEntrance "SUPER_CHAT_ENTRANCE" 超级留言入口样式
CmdSuperChatMessage "SUPER_CHAT_MESSAGE" 醒目留言消息
CmdSuperChatMessageDelete "SUPER_CHAT_MESSAGE_DELETE" 醒目留言被删除
CmdWatchedChange "WATCHED_CHANGE" 直播间看过人数改变
CmdSendGift "SEND_GIFT" 赠送礼物
CmdComboSend "COMBO_SEND" 礼物连击
CmdSpecialGift "SPECIAL_GIFT" 特殊礼物
CmdOnlineRankCount "ONLINE_RANK_COUNT" 高能榜观众数量
CmdOnlineRankV2 "ONLINE_RANK_V2" 高能榜刷新
CmdOnlineRankTop3 "ONLINE_RANK_TOP3" 高能用户前三名
CmdInteractWord "INTERACT_WORD" 进场或关注消息
CmdStopLiveRoomList "STOP_LIVE_ROOM_LIST" 停止直播的房间列表
CmdLikeInfoV3Update "LIKE_INFO_V3_UPDATE" 直播间点赞数更新
CmdHotRankChange "HOT_RANK_CHANGED" 分区排名变化
CmdHotRankChangedV2 "HOT_RANK_CHANGED_V2" 二级分区排名变化
CmdAreaRankChanged "AREA_RANK_CHANGED" 直播间所在分区的排名改变
CmdNoticeMsg "NOTICE_MSG" 通知消息
CmdRoomRealTimeMessageUpdate "ROOM_REAL_TIME_MESSAGE_UPDATE" 直播间相关信息更新
CmdWidgetBanner "WIDGET_BANNER" 网页端直播间标题下的横幅内容
CmdGuardHonorThousand "GUARD_HONOR_THOUSAND" 千舰推送
CmdGuardAchievementRoom "GUARD_ACHIEVEMENT_ROOM" 舰队规模达成成就
CmdPreparing "PREPARING" 直播准备
CmdLive "LIVE" 开始直播
CmdRoomChange "ROOM_CHANGE" 直播间信息更改
CmdRoomBlockMsg "ROOM_BLOCK_MSG" 禁言消息
CmdSysMsg "SYS_MSG" 系统消息
CmdFullScreenSpecialEffect "FULL_SCREEN_SPECIAL_EFFECT" 全屏特效
CmdCommonNoticeDanmaku "COMMON_NOTICE_DANMAKU" 直播间所在分区排名提升祝福
CmdTradingScore "TRADING_SCORE" 每日任务
CmdGuardBuy "GUARD_BUY" 购买大航海
CmdGiftStarProcess "GIFT_STAR_PROCESS" 礼物星球点亮
CmdWarning "WARNING" 超管警告
CmdCutOff "CUT_OFF" 被切断直播
CmdRoomAdminRevoke "ROOM_ADMIN_REVOKE" 房管撤销
CmdRoomSilentOff "ROOM_SILENT_OFF" 关闭直播间全部禁言
CmdRoomSilentOn "ROOM_SILENT_ON" 开启直播间全部禁言
CmdRoomAdminEntrance "room_admin_entrance" 修改房管的提示语 (只有涉及的用户会提示)
CmdRoomAdmins "ROOM_ADMINS" 房管列表更新
CmdRoomSkinMsg "ROOM_SKIN_MSG" [存疑] 房间皮肤
CmdChangeRoomInfo "CHANGE_ROOM_INFO" [存疑] 直播间背景更换
CmdEntryEffect "ENTRY_EFFECT" 进场特效
CmdUserToastMsg "USER_TOAST_MSG" 上舰提示消息
CmdOfficialRoomEvent "OFFICIAL_ROOM_EVENT" 官方房间事件
CmdHeartBeatReply "HEARTBEAT_REPLY" [自定义] 心跳包回复
CmdPopularityRedPocketStart "POPULARITY_RED_POCKET_START" 直播间发红包
CmdPopularityRedPocketNew "POPULARITY_RED_POCKET_NEW" [存疑] 发出红包
CmdPopularityRedPocketWinnerList "POPULARITY_RED_POCKET_WINNER_LIST" 抢到红包的人的信息
CmdPkBattleProcess "PK_BATTLE_PROCESS" [存疑] PK相关
CmdPkBattleProcessNew "PK_BATTLE_PROCESS_NEW" [存疑] PK相关
CmdPkBattlePreNew "PK_BATTLE_PRE_NEW" [存疑] PK相关
CmdPkBattlePre "PK_BATTLE_PRE" [存疑] PK相关
CmdPkBattleFinalProcess "PK_BATTLE_FINAL_PROCESS" [存疑] PK相关
CmdPkBattleStart "PK_BATTLE_START" [存疑] PK相关
CmdPkBattleStartNew "PK_BATTLE_START_NEW" [存疑] PK相关
CmdPkBattlePunishEnd "PK_BATTLE_PUNISH_END" [存疑] PK相关
CmdPkBattleSettleV2 "PK_BATTLE_SETTLE_V2" [存疑] PK相关
CmdPkBattleSettle "PK_BATTLE_SETTLE" [存疑] PK相关
CmdPkBattleEnd "PK_BATTLE_END" [存疑] PK相关
CmdPkBattleSettleUser "PK_BATTLE_SETTLE_USER" [存疑] PK相关
CmdPkBattleRankChange "PK_BATTLE_RANK_CHANGE" [存疑] PK相关
CmdPkBattleSettleNew "PK_BATTLE_SETTLE_NEW" [存疑] PK相关
CmdPkBattleMatchTimeout "PK_BATTLE_MATCH_TIMEOUT" [存疑] PK相关
CmdPkBattleAbnormal "PK_BATTLE_ABNORMAL" [存疑] PK相关
CmdPkBattleEntrance "PK_BATTLE_ENTRANCE" [存疑] PK相关
CmdPkBattleVideoPunishBegin "PK_BATTLE_VIDEO_PUNISH_BEGIN" [存疑] PK相关
CmdPkBattleVideoPunishEnd "PK_BATTLE_VIDEO_PUNISH_END" [存疑] PK相关
CmdGotoBuyFlow "GOTO_BUY_FLOW" [存疑] 购物车提示消息
CmdShoppingExplainCard "SHOPPING_EXPLAIN_CARD" [存疑] 购物车相关
CmdShoppingCartShow "SHOPPING_CART_SHOW" [存疑] 购物车显示状态
CmdShoppingBubblesStyle "SHOPPING_BUBBLES_STYLE" [存疑] 购物车相关
CmdSelectedGoodsInfo "SELECTED_GOODS_INFO" [存疑] 购物车相关
CmdHotBuyNum "HOT_BUY_NUM" [存疑] 购物车相关
CmdVoiceJoinRoomCountInfo "VOICE_JOIN_ROOM_COUNT_INFO" [存疑] 语音连线相关
CmdVoiceJoinList "VOICE_JOIN_LIST" [存疑] 语音连线相关
CmdVoiceJoinStatus "VOICE_JOIN_STATUS" [存疑] 语音连线相关
CmdVoiceJoinSwitch "VOICE_JOIN_SWITCH" [存疑] 语音连线相关
CmdVideoConnectionJoinStart "VIDEO_CONNECTION_JOIN_START" [存疑] 视频连线相关
CmdVideoConnectionMsg "VIDEO_CONNECTION_MSG" 视频连线提示语
CmdVideoConnectionJoinEnd "VIDEO_CONNECTION_JOIN_END" 视频连线结束
CmdMultiVoiceOperating "MULTI_VOICE_OPERATING" [存疑] 视频连线相关
CmdMultiVoiceApplicationUser "MULTI_VOICE_APPLICATION_USER" 申请视频连线
CmdAnchorLotCheckStatus "ANCHOR_LOT_CHECK_STATUS" [存疑] 天选相关
CmdAnchorLotEnd "ANCHOR_LOT_END" 天选结束
CmdAnchorLotAward "ANCHOR_LOT_AWARD" 天选结果
CmdInteractiveUser "INTERACTIVE_USER" [存疑] 预言玩法相关
CmdUserVirtualMvp "USER_VIRTUAL_MVP" [存疑] 守护圣法师相关
CmdWidgetWishList "WIDGET_WISH_LIST" [存疑] 许愿玩法相关
CmdPlayTogether "PLAY_TOGETHER"
CmdPopularRankChanged "POPULAR_RANK_CHANGED"
CmdDanMuAggregation "DANMU_AGGREGATION"
CmdLiveInteractiveGame "LIVE_INTERACTIVE_GAME"
CmdRecommendCard "RECOMMEND_CARD"
CmdWidgetGiftStarProcess "WIDGET_GIFT_STAR_PROCESS"
CmdAnchorLotStart "ANCHOR_LOT_START"
CmdHotRoomNotify "HOT_ROOM_NOTIFY"
CmdLiveOpenPlatformGame "LIVE_OPEN_PLATFORM_GAME"
CmdLivePanelChangeContent "LIVE_PANEL_CHANGE_CONTENT"
CmdGiftPanelPlan "GIFT_PANEL_PLAN"
CmdRingStatusChange "RING_STATUS_CHANGE"
CmdRingStatusChangeV2 "RING_STATUS_CHANGE_V2"
CmdRoomLock "ROOM_LOCK"
CmdLiveMultiViewChange "LIVE_MULTI_VIEW_CHANGE"
CmdMvRoleChange "MV_ROLE_CHANGE"
CmdMultiVoiceOperatin "MULTI_VOICE_OPERATING"
CmdPanelInteractiveNotifyChange "PANEL_INTERACTIVE_NOTIFY_CHANGE"
CmdCheckSingStatus "CHECK_SING_STATUS"
CmdRoomModuleDisplay "ROOM_MODULE_DISPLAY"
CmdVoiceChatUpdate "VOICE_CHAT_UPDATE"
CmdReenterLiveRoom "REENTER_LIVE_ROOM"
CmdActivityBannerChangeV2 "ACTIVITY_BANNER_CHANGE_V2"
CmdActivityBannerChange "ACTIVITY_BANNER_CHANGE"
CmdVideoConnectionStart "VIDEO_CONNECTION_START"
CmdGuideInfoStatus "GUIDE_INFO_STATUS"
CmdObsShieldStatusUpdate "OBS_SHIELD_STATUS_UPDATE"
CmdAnchorNormalNotify "ANCHOR_NORMAL_NOTIFY"
CmdBlinkStickerTitleRejected "BLINK_STICKER_TITLE_REJECTED"
CmdDanmuTagChanged "DANMU_TAG_CHANGED"
CmdHourRankAwards "HOUR_RANK_AWARDS"
CmdLivePanelChange "LIVE_PANEL_CHANGE"
CmdLiveRoomToastMessage "LIVE_ROOM_TOAST_MESSAGE"
CmdLogInNotice "LOG_IN_NOTICE"
CmdStudioRoomClose "STUDIO_ROOM_CLOSE"
CmdWinActivity "WIN_ACTIVITY"

由于我也不是很明白b站的命令, 所以这里只是列出了我知道的命令, 如果有人知道更多的命令, 请在issue中提出, 我会及时更新。

相信可以通过直译看懂这些命令...

消息处理函数

消息处理函数的原型为:

func someFunc(event MsgEvent)

其中MsgEvent的定义为:

type MsgEvent struct {
	//原始命令 
	Cmd    string
	//直播间号 
	RoomId int
    // 以下为不同的消息类型 
	DanMuMsg *DanMuMsg
	SuperChatMessage *SuperChatMessage
    // 下同, 可参考上方的消息类型, 取消Cmd即为结构体名称...
	...
}

消息结构体

这是弹幕消息的例子

type DanMuMsg struct {
	Cmd  string `json:"cmd"`
	Data struct {
		Sender struct {
			Uid    int64
			Name   string
			RoomId int64
		}
		Medal                    FansMedal
		Content                  string
		SendTimeStamp            int
		SendMillionTimeStamp     int64
		SenderEnterRoomTimeStamp int
	}
}

结构体内容, 请参考go-bili-chat/Handler/template.go中的定义 因为30个实在是太多了, 所以我就不一一列出来了...

在弹幕消息中, 我还没有完全明白每个参数的含义, 强烈欢迎各位PR完善

性能

具体可以参考Issue #24

感谢@XiaoMiku01提供的压测:

上海腾讯云 4C8G 10M Linux

同时连接5.8w个直播中的房间,内存占用 4.5G 左右, CPU 213% (平均 42%)

抽象画

+============================+   +=================+
|        LiveRoom 1          |   |                 |
| goroutine heart beat       |   |                 → → goroutine your function
| goroutine receive msg → → ↓|   |                 |
| goroutine msg handler ← ← ←|   |                 → → goroutine your function
+================|↓|=========+   _                 |
                  → → → → → → → →    goroutine     → → goroutine your function
+============================+   _                 |
|        LiveRoom 1          |   |  msg distribute → → goroutine your function
| goroutine heart beat       |   |                 |
| goroutine receive msg → → ↓|   |                 → → goroutine your function
| goroutine msg handler ← ← ←|   |                 |
+================|↓|=========+   _                 → → goroutine your function
                  → → → → → → → →                  |
                                 _                 → → goroutine your function
                                 +======|↑|========+
                                         ↑
                                         ↑
                                +=======|↑|========+
                                |                  | 
                                |  main goroutine  |
                                |                  |
                                +==================+

Documentation

Index

Constants

View Source
const DefaultClientPriority = 1 << 0
View Source
const DelayClientPriority = 1 << 1
View Source
const NoCDNClientPriority = 1 << 2

Variables

View Source
var ClientPriorityMode = DefaultClientPriority
View Source
var GetRoomFailed = errors.New("get room failed")
View Source
var RoomAlreadyExist = errors.New("room already exist")
View Source
var RoomNotExist = errors.New("room not exist")

Functions

func ChangeLogLevel

func ChangeLogLevel(level log.Level)

func SetClientPriorityMode added in v0.4.0

func SetClientPriorityMode(mode int)

func SetHeader added in v0.5.2

func SetHeader(header http.Header)

func SetJsonCoder

func SetJsonCoder(j jsonCoder)

func SetUID added in v0.5.2

func SetUID(uid int64)

Types

type DefaultJson

type DefaultJson struct {
}

func (*DefaultJson) Marshal

func (d *DefaultJson) Marshal(v interface{}) ([]byte, error)

func (*DefaultJson) Unmarshal

func (d *DefaultJson) Unmarshal(data []byte, v interface{}) error

type Handler

type Handler struct {
	Handler handler.Handler
	// contains filtered or unexported fields
}

func GetNewHandler

func GetNewHandler() *Handler

func (*Handler) AddOption

func (h *Handler) AddOption(Cmd string, RoomId int, Do handler.Do) *handler.Do

func (*Handler) AddRoom

func (h *Handler) AddRoom(RoomId int) error

func (*Handler) CountRoom added in v0.4.0

func (h *Handler) CountRoom() int

func (*Handler) DelOption added in v0.4.0

func (h *Handler) DelOption(f *handler.Do)

func (*Handler) DelRoom

func (h *Handler) DelRoom(RoomId int) error

func (*Handler) Run

func (h *Handler) Run()

type LiveRoom

type LiveRoom struct {
	RoomId int
	Client client.Client
}

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL