From 51229b213786c2567346cfe3782b382db934b76e Mon Sep 17 00:00:00 2001 From: qydysky Date: Sat, 6 Mar 2021 16:24:27 +0800 Subject: [PATCH] =?utf8?q?=E5=91=BD=E4=BB=A4=E8=A1=8C=E6=93=8D=E4=BD=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- F/api.go | 79 +++++++++++++++++++++++++++++++++++++++++++ F/cmd.go | 74 ++++++++++++++++++++++++++++++++++++++++ README.md | 32 ++++++++++++++++++ bili_danmu.go | 93 ++++++++++++++++++++++----------------------------- 4 files changed, 225 insertions(+), 53 deletions(-) create mode 100644 F/cmd.go diff --git a/F/api.go b/F/api.go index 4b58d14..ba7f207 100644 --- a/F/api.go +++ b/F/api.go @@ -1824,4 +1824,83 @@ func save_cookie(Cookies []*http.Cookie){ return true }) CookieSet([]byte(p.Map_2_Cookies_String(Cookie))) +} + +//正在直播主播 +type UpItem struct{ + Uname string `json:"uname"` + Title string `json:"title"` + Roomid int `json:"roomid"` +} +func Feed_list() (Uplist []UpItem) { + apilog := apilog.Base_add(`正在直播主播`).L(`T: `,`获取中`) + //验证cookie + if missKey := CookieCheck([]string{ + `bili_jct`, + `DedeUserID`, + `LIVE_BUVID`, + });len(missKey) != 0 { + apilog.L(`T: `,`Cookie无Key:`,missKey) + return + } + if api_limit.TO() {apilog.L(`E: `,`超时!`);return}//超额请求阻塞,超时将取消 + + Cookie := make(map[string]string) + c.Cookie.Range(func(k,v interface{})(bool){ + Cookie[k.(string)] = v.(string) + return true + }) + + req := p.Req() + for pageNum:=1; true; pageNum+=1 { + if err := req.Reqf(p.Rval{ + Url:`https://api.live.bilibili.com/relation/v1/feed/feed_list?page=`+strconv.Itoa(pageNum)+`&pagesize=10`, + Header:map[string]string{ + `Host`: `api.live.bilibili.com`, + `User-Agent`: `Mozilla/5.0 (X11; Linux x86_64; rv:83.0) Gecko/20100101 Firefox/83.0`, + `Accept`: `application/json, text/plain, */*`, + `Accept-Language`: `zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2`, + `Accept-Encoding`: `gzip, deflate, br`, + `Origin`: `https://t.bilibili.com`, + `Connection`: `keep-alive`, + `Pragma`: `no-cache`, + `Cache-Control`: `no-cache`, + `Referer`:`https://t.bilibili.com/pages/nav/index_new`, + `Cookie`:p.Map_2_Cookies_String(Cookie), + }, + Timeout:3, + Retry:2, + });err != nil { + apilog.L(`E: `,err) + return + } + + var res struct{ + Code int `json:"code"` + Msg string `json:"msg"` + Message string `json:"message"` + Data struct{ + Results int `json:"results"` + List []UpItem `json:"list"` + } `json:"data"` + } + + if e := json.Unmarshal(req.Respon, &res);e != nil{ + apilog.L(`E: `, e) + return + } + + if res.Code != 0{ + apilog.L(`E: `, res.Message) + return + } + + Uplist = append(Uplist, res.Data.List...) + + if pageNum*10 > res.Data.Results {break} + time.Sleep(time.Second) + } + + apilog.L(`T: `,`完成`) + return } \ No newline at end of file diff --git a/F/cmd.go b/F/cmd.go new file mode 100644 index 0000000..25a4e3b --- /dev/null +++ b/F/cmd.go @@ -0,0 +1,74 @@ +package F + +import ( + "os" + "bufio" + "strings" + "strconv" + + p "github.com/qydysky/part" + send "github.com/qydysky/bili_danmu/Send" + c "github.com/qydysky/bili_danmu/CV" +) + +//直播间缓存 +var liveList =make(map[string]int) + +func Cmd() { + + cmdlog := c.Log.Base_add(`命令行操作`).L(`T: `,`回车查看帮助`) + scanner := bufio.NewScanner(os.Stdin) + + for scanner.Scan() { + if inputs := scanner.Text();inputs == `` {//帮助 + cmdlog.L(`I: `, "切换房间->输入数字回车") + cmdlog.L(`I: `, "发送弹幕->输入' 字符串'回车") + cmdlog.L(`I: `, "查看直播中主播->输入' live'回车") + cmdlog.L(`I: `, "其他输出隔断不影响") + } else if inputs[0] == 27 {//屏蔽功能键 + cmdlog.L(`W: `, "不支持功能键") + } else if inputs[0] == 32 {// 开头 + if strings.Contains(inputs, ` live`) {//直播间切换 + if len(inputs) > 5 { + if room,ok := liveList[inputs];ok{ + c.Roomid = room + cmdlog.L(`I: `, "进入房间",room) + c.Danmu_Main_mq.Push_tag(`change_room`,nil) + continue + } + cmdlog.L(`W: `, "输入错误", inputs) + continue + } + for k,v := range Feed_list() { + liveList[` live`+strconv.Itoa(k)] = v.Roomid + cmdlog.L(`I: `, k, v.Uname, v.Title) + } + cmdlog.L(`I: `, "回复' live(序号)'进入直播间") + continue + } + {//弹幕发送 + if len(inputs) < 2 { + cmdlog.L(`W: `, "输入长度过短", inputs) + continue + } + Cookie := make(map[string]string) + c.Cookie.Range(func(k,v interface{})(bool){ + Cookie[k.(string)] = v.(string) + return true + }) + send.Danmu_s(inputs[1:], p.Map_2_Cookies_String(Cookie),c.Roomid) + } + } else if room,err := strconv.Atoi(inputs);err == nil {//直接进入房间 + c.Roomid = room + cmdlog.L(`I: `, "进入房间",room) + c.Danmu_Main_mq.Push_tag(`change_room`,nil) + } else {//其余字符串 + Cookie := make(map[string]string) + c.Cookie.Range(func(k,v interface{})(bool){ + Cookie[k.(string)] = v.(string) + return true + }) + send.Danmu_s(inputs, p.Map_2_Cookies_String(Cookie),c.Roomid) + } + } +} \ No newline at end of file diff --git a/README.md b/README.md index 0596d07..b826fd0 100644 --- a/README.md +++ b/README.md @@ -90,12 +90,44 @@ golang go version go1.15 linux/amd64 - [x] 弹幕自动重连(30s) - [x] 直播流开播自动下载 - [x] 直播流断流再保存 +- [x] 命令行支持房间切换、弹幕发送 - [x] GTK信息窗支持房间切换、弹幕格式化发送、时长统计 - [x] GTK弹幕窗支持自定义人/事件消息停留 ### 说明 本项目使用github action自动构建,构建过程详见[yml](https://github.com/qydysky/bili_danmu/blob/master/.github/workflows/go.yml) +#### 命令行操作 +在准备动作完成(`T: 2021/03/06 16:22:39 命令行操作 [回车查看帮助]`)后,输入回车将显示帮助 +``` +I: 2021/03/06 16:16:17 命令行操作 [切换房间->输入数字回车] +I: 2021/03/06 16:16:17 命令行操作 [发送弹幕->输入' 字符串'回车] +I: 2021/03/06 16:16:17 命令行操作 [查看直播中主播->输入' live'回车] +I: 2021/03/06 16:16:17 命令行操作 [其他输出隔断不影响] +``` +用例: +- 直播间切换 +``` + live +T: 2021/03/06 16:18:48 api 正在直播主播 [获取中] +T: 2021/03/06 16:18:48 api 正在直播主播 [完成] +I: 2021/03/06 16:18:48 命令行操作 [0 奈さま B站第一坑老公] +I: 2021/03/06 16:18:48 命令行操作 [1 古守血遊official 【B】Apex on] +I: 2021/03/06 16:18:48 命令行操作 [2 一米八的坤儿 午饭直播] +I: 2021/03/06 16:18:48 命令行操作 [3 哔哩哔哩英雄联盟赛事 【直播】 LNG vs LGD] +I: 2021/03/06 16:18:48 命令行操作 [回复' live(序号)'进入直播间] + live1 +I: 2021/03/06 16:19:12 命令行操作 [进入房间 8725120] +``` +``` +120 +I: 2021/03/06 16:21:35 命令行操作 [进入 120] +``` +- 发送弹幕 +``` + 1 +I: 2021/03/06 16:21:17 弹幕发送 [发送 1 至 7734200] +``` #### cookie加密 保护cookie.txt diff --git a/bili_danmu.go b/bili_danmu.go index bf0960c..7da312c 100644 --- a/bili_danmu.go +++ b/bili_danmu.go @@ -111,74 +111,61 @@ func Demo(roomid ...int) { <-change_room_chan - //命令行也可切换房间 - go func(){ - for input := ``; true; { - if _,err := fmt.Scanln(&input);err.Error() == `unexpected newline`{ - fmt.Println("输入房间号并回车(其他显示隔断不影响)\n") - room := 0 - if _,err := fmt.Scanln(&room);err != nil { - danmulog.L(`W: `, "房间输入错误", room, err) - } else { - c.Roomid = room - c.Danmu_Main_mq.Push_tag(`change_room`,nil) - } - } - } - }() - //ctrl+c退出 signal.Notify(interrupt, os.Interrupt) - for !exit_sign { - //获取cookies - { - var get_cookie = func(){ - danmulog.L(`I: `, "未检测到cookie.txt,如果需要登录请在本机打开以下网址扫码登录,不需要请忽略") - //获取cookie - F.Get_cookie() - //验证cookie - if missKey := F.CookieCheck([]string{ - `bili_jct`, - `DedeUserID`, - });len(missKey) == 0 { - danmulog.L(`I: `,"你已登录,刷新房间!") - //刷新 - c.Danmu_Main_mq.Push_tag(`change_room`,nil) - } + //获取cookies + { + var get_cookie = func(){ + danmulog.L(`I: `, "未检测到cookie.txt,如果需要登录请在本机打开以下网址扫码登录,不需要请忽略") + //获取cookie + F.Get_cookie() + //验证cookie + if missKey := F.CookieCheck([]string{ + `bili_jct`, + `DedeUserID`, + });len(missKey) == 0 { + danmulog.L(`I: `,"你已登录,刷新房间!") + //刷新 + c.Danmu_Main_mq.Push_tag(`change_room`,nil) } + } + + if !p.Checkfile().IsExist("cookie.txt") {//读取cookie文件 + go get_cookie() + p.Sys().Timeoutf(3) + } else { - if !p.Checkfile().IsExist("cookie.txt") {//读取cookie文件 + cookieString := string(F.CookieGet()) + + if cookieString == `` {//cookie.txt为空 + danmulog.L(`T: `, `cookie.txt为空`) go get_cookie() p.Sys().Timeoutf(3) } else { - - cookieString := string(F.CookieGet()) - - if cookieString == `` {//cookie.txt为空 - danmulog.L(`T: `, `cookie.txt为空`) + for k,v := range p.Cookies_String_2_Map(cookieString){//cookie存入全局变量syncmap + c.Cookie.Store(k, v) + } + if uid,ok := c.Cookie.LoadV(`DedeUserID`).(string);!ok{//cookie中无DedeUserID + danmulog.L(`T: `, `读取cookie错误,无DedeUserID`) + go get_cookie() + p.Sys().Timeoutf(3) + } else if uid,e := strconv.Atoi(uid);e != nil{ + danmulog.L(`E: `, e) go get_cookie() p.Sys().Timeoutf(3) } else { - for k,v := range p.Cookies_String_2_Map(cookieString){//cookie存入全局变量syncmap - c.Cookie.Store(k, v) - } - if uid,ok := c.Cookie.LoadV(`DedeUserID`).(string);!ok{//cookie中无DedeUserID - danmulog.L(`T: `, `读取cookie错误,无DedeUserID`) - go get_cookie() - p.Sys().Timeoutf(3) - } else if uid,e := strconv.Atoi(uid);e != nil{ - danmulog.L(`E: `, e) - go get_cookie() - p.Sys().Timeoutf(3) - } else { - c.Uid = uid - } + c.Uid = uid } } } + } - danmulog.L(`T: `,"准备变量") + //命令行操作 切换房间 发送弹幕 + go F.Cmd() + + for !exit_sign { + danmulog.L(`T: `,"准备") //获取房间相关信息 api := F.New_api(c.Roomid).Get_host_Token().Get_live() c.Roomid = api.Roomid -- 2.39.2