2
2
package bilibili
3
3
4
4
import (
5
+ "bytes"
5
6
"encoding/json"
6
7
"fmt"
7
8
"net/http"
9
+ "os"
10
+ "os/exec"
8
11
"regexp"
9
12
"strings"
10
13
"time"
11
14
12
15
bz "github.com/FloatTech/AnimeAPI/bilibili"
16
+ "github.com/FloatTech/floatbox/file"
13
17
"github.com/FloatTech/floatbox/web"
14
18
ctrl "github.com/FloatTech/zbpctrl"
15
19
"github.com/FloatTech/zbputils/control"
16
20
"github.com/FloatTech/zbputils/ctxext"
21
+ "github.com/pkg/errors"
17
22
zero "github.com/wdvxdr1123/ZeroBot"
18
23
"github.com/wdvxdr1123/ZeroBot/message"
19
24
)
20
25
21
26
const (
22
- enableHex = 0x10
23
- unableHex = 0x7fffffff_fffffffd
27
+ enableHex = 0x10
28
+ unableHex = 0x7fffffff_fffffffd
29
+ bilibiliparseReferer = "https://www.bilibili.com"
24
30
)
25
31
26
32
var (
@@ -42,10 +48,14 @@ func init() {
42
48
Brief : "b站链接解析" ,
43
49
Help : "例:- t.bilibili.com/642277677329285174\n - bilibili.com/read/cv17134450\n - bilibili.com/video/BV13B4y1x7pS\n - live.bilibili.com/22603245 " ,
44
50
})
51
+ cachePath := en .DataFolder () + "cache/"
52
+ _ = os .RemoveAll (cachePath )
53
+ _ = os .MkdirAll (cachePath , 0755 )
45
54
en .OnRegex (`((b23|acg).tv|bili2233.cn)\\?/[0-9a-zA-Z]+` ).SetBlock (true ).Limit (limit .LimitByGroup ).
46
55
Handle (func (ctx * zero.Ctx ) {
47
56
u := ctx .State ["regex_matched" ].([]string )[0 ]
48
57
u = strings .ReplaceAll (u , "\\ " , "" )
58
+ ctx .State ["cache_path" ] = cachePath
49
59
realurl , err := bz .GetRealURL ("https://" + u )
50
60
if err != nil {
51
61
ctx .SendChain (message .Text ("ERROR: " , err ))
@@ -95,10 +105,22 @@ func init() {
95
105
}
96
106
ctx .SendChain (message .Text ("已" , option , "视频总结" ))
97
107
})
98
- en .OnRegex (searchVideo ).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleVideo )
99
- en .OnRegex (searchDynamic ).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleDynamic )
100
- en .OnRegex (searchArticle ).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleArticle )
101
- en .OnRegex (searchLiveRoom ).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleLive )
108
+ en .OnRegex (searchVideo , func (ctx * zero.Ctx ) bool {
109
+ ctx .State ["cache_path" ] = cachePath
110
+ return true
111
+ }).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleVideo )
112
+ en .OnRegex (searchDynamic , func (ctx * zero.Ctx ) bool {
113
+ ctx .State ["cache_path" ] = cachePath
114
+ return true
115
+ }).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleDynamic )
116
+ en .OnRegex (searchArticle , func (ctx * zero.Ctx ) bool {
117
+ ctx .State ["cache_path" ] = cachePath
118
+ return true
119
+ }).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleArticle )
120
+ en .OnRegex (searchLiveRoom , func (ctx * zero.Ctx ) bool {
121
+ ctx .State ["cache_path" ] = cachePath
122
+ return true
123
+ }).SetBlock (true ).Limit (limit .LimitByGroup ).Handle (handleLive )
102
124
}
103
125
104
126
func handleVideo (ctx * zero.Ctx ) {
@@ -126,6 +148,13 @@ func handleVideo(ctx *zero.Ctx) {
126
148
}
127
149
}
128
150
ctx .SendChain (msg ... )
151
+ cachePath := ctx .State ["cache_path" ].(string )
152
+ downLoadMsg , err := getVideoDownload (cfg , card , cachePath )
153
+ if err != nil {
154
+ ctx .SendChain (message .Text ("ERROR: " , err ))
155
+ return
156
+ }
157
+ ctx .SendChain (downLoadMsg ... )
129
158
}
130
159
131
160
func handleDynamic (ctx * zero.Ctx ) {
@@ -189,3 +218,48 @@ func getVideoSummary(cookiecfg *bz.CookieConfig, card bz.Card) (msg []message.Se
189
218
}
190
219
return
191
220
}
221
+
222
+ func getVideoDownload (cookiecfg * bz.CookieConfig , card bz.Card , cachePath string ) (msg []message.Segment , err error ) {
223
+ var (
224
+ data []byte
225
+ videoDownload bz.VideoDownload
226
+ stderr bytes.Buffer
227
+ )
228
+ today := time .Now ().Format ("20060102" )
229
+ videoFile := fmt .Sprintf ("%s%s%s.mp4" , cachePath , card .BvID , today )
230
+ if file .IsExist (videoFile ) {
231
+ msg = append (msg , message .Video ("file:///" + file .BOTPATH + "/" + videoFile ))
232
+ return
233
+ }
234
+ data , err = web .RequestDataWithHeaders (web .NewDefaultClient (), bz .SignURL (fmt .Sprintf (bz .VideoDownloadURL , card .BvID , card .CID )), "GET" , func (req * http.Request ) error {
235
+ if cookiecfg != nil {
236
+ cookie := ""
237
+ cookie , err = cookiecfg .Load ()
238
+ if err != nil {
239
+ return err
240
+ }
241
+ req .Header .Add ("cookie" , cookie )
242
+ }
243
+ req .Header .Set ("User-Agent" , ua )
244
+ return nil
245
+ }, nil )
246
+ if err != nil {
247
+ return
248
+ }
249
+ err = json .Unmarshal (data , & videoDownload )
250
+ if err != nil {
251
+ return
252
+ }
253
+ headers := fmt .Sprintf ("User-Agent: %s\n Referer: %s" , ua , bilibiliparseReferer )
254
+ // 限制最多下载8分钟视频
255
+ cmd := exec .Command ("ffmpeg" , "-ss" , "0" , "-t" , "480" , "-headers" , headers , "-i" , videoDownload .Data .Durl [0 ].URL , "-c" , "copy" , videoFile )
256
+ cmd .Stderr = & stderr
257
+ err = cmd .Run ()
258
+ if err != nil {
259
+ err = errors .Errorf ("未配置ffmpeg,%s" , stderr .String ())
260
+ return
261
+ }
262
+ msg = append (msg , message .Video ("file:///" + file .BOTPATH + "/" + videoFile ))
263
+ return
264
+
265
+ }
0 commit comments