feat(bilibili): 添加视频下载 (#1157)

This commit is contained in:
himawari 2025-04-23 17:33:15 +08:00 committed by GitHub
parent 109b7661b7
commit 4b90a0659b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 85 additions and 10 deletions

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.20
require (
github.com/Baidu-AIP/golang-sdk v1.1.1
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9
github.com/FloatTech/AnimeAPI v1.7.1-0.20250423082452-e16339a3962c
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024
github.com/FloatTech/gg v1.1.3
github.com/FloatTech/imgfactory v0.2.2-0.20230413152719-e101cc3606ef

4
go.sum
View File

@ -1,8 +1,8 @@
github.com/Baidu-AIP/golang-sdk v1.1.1 h1:RQsAmgDSAkiq22I6n7XJ2t3afgzFeqjY46FGhvrx4cw=
github.com/Baidu-AIP/golang-sdk v1.1.1/go.mod h1:bXnGw7xPeKt8aF7UCELKrV6UZ/46spItONK1RQBQj1Y=
github.com/DATA-DOG/go-sqlmock v1.3.3/go.mod h1:f/Ixk793poVmq4qj/V1dPUg2JEAKC73Q5eFN3EC/SaM=
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9 h1:tI9GgG8fdMK2WazFiEbMXAXjwMCckIfDaXbig9B6DdA=
github.com/FloatTech/AnimeAPI v1.7.1-0.20250217140215-4856397458c9/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
github.com/FloatTech/AnimeAPI v1.7.1-0.20250423082452-e16339a3962c h1:bEe8VP2aHLR2NHk1BsBQFtP0XE3cxquvr0tW0CkKcDk=
github.com/FloatTech/AnimeAPI v1.7.1-0.20250423082452-e16339a3962c/go.mod h1:XXG1eBJf+eeWacQx5azsQKL5Gg7jDYTFyyZGIa/56js=
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024 h1:mrvWpiwfRklt9AyiQjKgDGJjf4YL6FZ3yC+ydbkuF2o=
github.com/FloatTech/floatbox v0.0.0-20241106130736-5aea0a935024/go.mod h1:+P3hs+Cvl10/Aj3SNE96TuBvKAXCe+XD1pKphTZyiwk=
github.com/FloatTech/gg v1.1.3 h1:+GlL02lTKsxJQr4WCuNwVxC1/eBZrCvypCIBtxuOFb4=

View File

@ -2,25 +2,31 @@
package bilibili
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"os"
"os/exec"
"regexp"
"strings"
"time"
bz "github.com/FloatTech/AnimeAPI/bilibili"
"github.com/FloatTech/floatbox/file"
"github.com/FloatTech/floatbox/web"
ctrl "github.com/FloatTech/zbpctrl"
"github.com/FloatTech/zbputils/control"
"github.com/FloatTech/zbputils/ctxext"
"github.com/pkg/errors"
zero "github.com/wdvxdr1123/ZeroBot"
"github.com/wdvxdr1123/ZeroBot/message"
)
const (
enableHex = 0x10
unableHex = 0x7fffffff_fffffffd
enableHex = 0x10
unableHex = 0x7fffffff_fffffffd
bilibiliparseReferer = "https://www.bilibili.com"
)
var (
@ -33,6 +39,7 @@ var (
searchDynamicRe = regexp.MustCompile(searchDynamic)
searchArticleRe = regexp.MustCompile(searchArticle)
searchLiveRoomRe = regexp.MustCompile(searchLiveRoom)
cachePath string
)
// 插件主体
@ -42,6 +49,9 @@ func init() {
Brief: "b站链接解析",
Help: "例:- t.bilibili.com/642277677329285174\n- bilibili.com/read/cv17134450\n- bilibili.com/video/BV13B4y1x7pS\n- live.bilibili.com/22603245 ",
})
cachePath = en.DataFolder() + "cache/"
_ = os.RemoveAll(cachePath)
_ = os.MkdirAll(cachePath, 0755)
en.OnRegex(`((b23|acg).tv|bili2233.cn)\\?/[0-9a-zA-Z]+`).SetBlock(true).Limit(limit.LimitByGroup).
Handle(func(ctx *zero.Ctx) {
u := ctx.State["regex_matched"].([]string)[0]
@ -126,6 +136,12 @@ func handleVideo(ctx *zero.Ctx) {
}
}
ctx.SendChain(msg...)
downLoadMsg, err := getVideoDownload(cfg, card, cachePath)
if err != nil {
ctx.SendChain(message.Text("ERROR: ", err))
return
}
ctx.SendChain(downLoadMsg...)
}
func handleDynamic(ctx *zero.Ctx) {
@ -189,3 +205,48 @@ func getVideoSummary(cookiecfg *bz.CookieConfig, card bz.Card) (msg []message.Se
}
return
}
func getVideoDownload(cookiecfg *bz.CookieConfig, card bz.Card, cachePath string) (msg []message.Segment, err error) {
var (
data []byte
videoDownload bz.VideoDownload
stderr bytes.Buffer
)
today := time.Now().Format("20060102")
videoFile := fmt.Sprintf("%s%s%s.mp4", cachePath, card.BvID, today)
if file.IsExist(videoFile) {
msg = append(msg, message.Video("file:///"+file.BOTPATH+"/"+videoFile))
return
}
data, err = web.RequestDataWithHeaders(web.NewDefaultClient(), bz.SignURL(fmt.Sprintf(bz.VideoDownloadURL, card.BvID, card.CID)), "GET", func(req *http.Request) error {
if cookiecfg != nil {
cookie := ""
cookie, err = cookiecfg.Load()
if err != nil {
return err
}
req.Header.Add("cookie", cookie)
}
req.Header.Set("User-Agent", ua)
return nil
}, nil)
if err != nil {
return
}
err = json.Unmarshal(data, &videoDownload)
if err != nil {
return
}
headers := fmt.Sprintf("User-Agent: %s\nReferer: %s", ua, bilibiliparseReferer)
// 限制最多下载8分钟视频
cmd := exec.Command("ffmpeg", "-ss", "0", "-t", "480", "-headers", headers, "-i", videoDownload.Data.Durl[0].URL, "-c", "copy", videoFile)
cmd.Stderr = &stderr
err = cmd.Run()
if err != nil {
err = errors.Errorf("未配置ffmpeg%v", stderr)
return
}
msg = append(msg, message.Video("file:///"+file.BOTPATH+"/"+videoFile))
return
}

View File

@ -2,10 +2,12 @@ package bilibili
import (
"encoding/json"
"fmt"
"time"
bz "github.com/FloatTech/AnimeAPI/bilibili"
"github.com/FloatTech/floatbox/binary"
"github.com/FloatTech/floatbox/web"
"github.com/wdvxdr1123/ZeroBot/message"
)
@ -303,7 +305,10 @@ func liveCard2msg(card bz.RoomCard) (msg []message.Segment) {
// videoCard2msg 视频卡片转消息
func videoCard2msg(card bz.Card) (msg []message.Segment, err error) {
var mCard bz.MemberCard
var (
mCard bz.MemberCard
onlineTotal bz.OnlineTotal
)
msg = make([]message.Segment, 0, 16)
mCard, err = bz.GetMemberCard(card.Owner.Mid)
msg = append(msg, message.Text("标题: ", card.Title, "\n"))
@ -313,16 +318,25 @@ func videoCard2msg(card bz.Card) (msg []message.Segment, err error) {
}
} else {
if err != nil {
err = nil
msg = append(msg, message.Text("UP主: ", card.Owner.Name, "\n"))
} else {
msg = append(msg, message.Text("UP主: ", card.Owner.Name, " 粉丝: ", bz.HumanNum(mCard.Fans), "\n"))
}
}
msg = append(msg, message.Text("播放: ", bz.HumanNum(card.Stat.View), " 弹幕: ", bz.HumanNum(card.Stat.Danmaku)))
msg = append(msg, message.Image(card.Pic))
msg = append(msg, message.Text("\n点赞: ", bz.HumanNum(card.Stat.Like), " 投币: ", bz.HumanNum(card.Stat.Coin), "\n",
"收藏: ", bz.HumanNum(card.Stat.Favorite), " 分享: ", bz.HumanNum(card.Stat.Share), "\n",
data, err := web.GetData(fmt.Sprintf(bz.OnlineTotalURL, card.BvID, card.CID))
if err != nil {
return
}
err = json.Unmarshal(data, &onlineTotal)
if err != nil {
return
}
msg = append(msg, message.Text("👀播放: ", bz.HumanNum(card.Stat.View), " 💬弹幕: ", bz.HumanNum(card.Stat.Danmaku),
"\n👍点赞: ", bz.HumanNum(card.Stat.Like), " 💰投币: ", bz.HumanNum(card.Stat.Coin),
"\n📁收藏: ", bz.HumanNum(card.Stat.Favorite), " 🔗分享: ", bz.HumanNum(card.Stat.Share),
"\n📝简介: ", card.Desc,
"\n🏄 总共 ", onlineTotal.Data.Total, " 人在观看,", onlineTotal.Data.Count, " 人在网页端观看\n",
bz.VURL, card.BvID, "\n\n"))
return
}