From: qydysky <32743305+qydysky@users.noreply.github.com> Date: Sun, 27 Nov 2022 16:45:20 +0000 (+0800) Subject: fix X-Git-Tag: v0.5.11~64 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=8a20e363378ccf36d4e95755c6c1385912ec95ab;p=bili_danmu%2F.git fix --- diff --git a/Reply/F.go b/Reply/F.go index ac3a4b3..6fc4e9f 100644 --- a/Reply/F.go +++ b/Reply/F.go @@ -545,7 +545,7 @@ var danmuji = Danmuji{ func init() { //初始化反射型弹幕机 bb, err := file.New("config/config_auto_reply.json", 0, true).ReadAll(100, 1<<16) - if err != nil { + if !errors.Is(err, io.EOF) { return } var buf map[string]interface{} diff --git a/Reply/Msg.go b/Reply/Msg.go index 43bf35f..92f4b14 100644 --- a/Reply/Msg.go +++ b/Reply/Msg.go @@ -2,6 +2,8 @@ package reply import ( "encoding/json" + "errors" + "io" c "github.com/qydysky/bili_danmu/CV" file "github.com/qydysky/part/file" @@ -118,7 +120,7 @@ var Msg_map = map[string]func(replyF, string){ func init() { { //加载不需要的消息 bb, err := file.New("config/config_disable_msg.json", 0, true).ReadAll(100, 1<<16) - if err != nil { + if !errors.Is(err, io.EOF) { return } var buf map[string]interface{} diff --git a/Reply/fmp4Decode.go b/Reply/fmp4Decode.go index 192799f..3d2a256 100644 --- a/Reply/fmp4Decode.go +++ b/Reply/fmp4Decode.go @@ -3,6 +3,7 @@ package reply import ( "bytes" "errors" + "fmt" F "github.com/qydysky/bili_danmu/F" ) @@ -17,8 +18,25 @@ type Fmp4Decoder struct { traks map[int]trak } -func (t *Fmp4Decoder) Init_fmp4(buf []byte) error { - var cu int +func (t *Fmp4Decoder) Init_fmp4(buf []byte) ([]byte, error) { + var ( + cu int + lastMoovI int + lastMoovE int + ) + + //ftyp + ftypI := bytes.Index(buf[cu:], []byte("ftyp")) + if ftypI == -1 { + return nil, errors.New("未找到ftyp包") + } + ftypI = cu + ftypI - 4 + ftypE := ftypI + int(F.Btoi(buf, ftypI, 4)) + if ftypE > len(buf) { + return nil, errors.New("ftyp包破损") + } + cu = ftypI + for cu < len(buf) { //moov moovI := bytes.Index(buf[cu:], []byte("moov")) @@ -28,10 +46,13 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) error { moovI = cu + moovI - 4 moovE := moovI + int(F.Btoi(buf, moovI, 4)) if moovE > len(buf) { - return errors.New("moov包破损") + return nil, errors.New("moov包破损") } cu = moovI + lastMoovI = moovI + lastMoovE = moovE + for cu < moovE { //trak trakI := bytes.Index(buf[cu:], []byte("trak")) @@ -41,55 +62,55 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) error { trakI = cu + trakI - 4 trakE := trakI + int(F.Btoi(buf, trakI, 4)) if trakE > moovE { - return errors.New("trak包破损") + return nil, errors.New("trak包破损") } cu = trakI //tkhd tkhdI := bytes.Index(buf[cu:], []byte("tkhd")) if tkhdI == -1 { - return errors.New("未找到tkhd包") + return nil, errors.New("未找到tkhd包") } tkhdI = cu + tkhdI - 4 tkhdE := tkhdI + int(F.Btoi(buf, tkhdI, 4)) if tkhdE > trakE { - return errors.New("tkhd包破损") + return nil, errors.New("tkhd包破损") } cu = tkhdI //mdia mdiaI := bytes.Index(buf[cu:], []byte("mdia")) if mdiaI == -1 { - return errors.New("未找到mdia包") + return nil, errors.New("未找到mdia包") } mdiaI = cu + mdiaI - 4 mdiaE := mdiaI + int(F.Btoi(buf, mdiaI, 4)) if mdiaE > trakE { - return errors.New("mdia包破损") + return nil, errors.New("mdia包破损") } cu = mdiaI //mdhd mdhdI := bytes.Index(buf[cu:], []byte("mdhd")) if mdhdI == -1 { - return errors.New("未找到mdhd包") + return nil, errors.New("未找到mdhd包") } mdhdI = cu + mdhdI - 4 mdhdE := mdhdI + int(F.Btoi(buf, mdhdI, 4)) if mdhdE > mdiaE { - return errors.New("mdhd包破损") + return nil, errors.New("mdhd包破损") } cu = mdhdI //hdlr hdlrI := bytes.Index(buf[cu:], []byte("hdlr")) if hdlrI == -1 { - return errors.New("未找到hdlr包") + return nil, errors.New("未找到hdlr包") } hdlrI = cu + hdlrI - 4 hdlrE := hdlrI + int(F.Btoi(buf, hdlrI, 4)) if hdlrE > mdiaE { - return errors.New("hdlr包破损") + return nil, errors.New("hdlr包破损") } cu = hdlrI @@ -105,9 +126,9 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) error { } } if len(t.traks) == 0 { - return errors.New("未找到trak包") + return nil, errors.New("未找到trak包") } - return nil + return append(buf[ftypI:ftypE], buf[lastMoovI:lastMoovE]...), nil } func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte) (keyframes [][]byte, last_avilable_offset int, err error) { @@ -120,6 +141,7 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte) (keyframes [][]byte, last_av cu int haveKeyframe bool keyframe []byte + frameTime int ) for cu < len(buf) { @@ -235,6 +257,14 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte) (keyframes [][]byte, last_av if !iskeyFrame && buf[trunI+20] == byte(0x02) { iskeyFrame = true } + + if track.handlerType == 'v' { + if timeStamp < frameTime { + err = fmt.Errorf("时间戳异常: (current)%d < (last)%d", timeStamp, frameTime) + break + } + frameTime = timeStamp + } } if err != nil { @@ -291,7 +321,7 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte) (keyframes [][]byte, last_av if cu == 0 { err = errors.New("未找到moof") } - if len(buf) > 1024*1024*20 { + if len(buf)-last_avilable_offset > 1024*1024*20 { err = errors.New("buf超过20M") } return diff --git a/Reply/sliceBuf.go b/Reply/sliceBuf.go new file mode 100644 index 0000000..cf40af7 --- /dev/null +++ b/Reply/sliceBuf.go @@ -0,0 +1,59 @@ +package reply + +// 线程不安全的[]byte操作 +// 需保证append到getSlice的[]byte已被使用之间,对象[]byte未改动 +type bufI struct { + b []int + e []int + size int + buf []byte + useDirect bool //true:直接使用源[]byte,仅适用于连续的append + useBufPool bool //true:使用内部buf,当getSlice调用时,上次getSlice输出[]byte失效 + //useDirect、useBufPool都为false:每次都返回新创建的[]byte +} + +func (t *bufI) reset() { + t.b = []int{} + t.e = []int{} + t.size = 0 +} + +func (t *bufI) append(b, e int) { + if len(t.e) > 0 && t.e[len(t.e)-1] == b { + t.e[len(t.e)-1] = e + } else { + t.b = append(t.b, b) + t.e = append(t.e, e) + } + t.size += e - b +} + +func (t *bufI) getSlice(buf []byte) []byte { + if t.useDirect && len(t.b) == 1 { + return buf[t.b[0]:t.e[0]] + } else if t.useBufPool { + if len(t.buf) == 0 { + t.buf = make([]byte, t.size) + } else if len(t.buf) < t.size { + t.buf = append(t.buf, make([]byte, t.size-len(t.buf))...) + } else if diff := len(t.buf) - t.size; diff > 0 { + t.buf = t.buf[:t.size+diff/2] + } + i := 0 + for k, bi := range t.b { + i += copy(t.buf[i:], buf[bi:t.e[k]]) + } + return t.buf[:i] + } else { + var b = make([]byte, t.size) + if len(t.b) == 1 { + copy(b, buf[t.b[0]:t.e[0]]) + } else { + i := 0 + for k, bi := range t.b { + i += copy(b[i:], buf[bi:t.e[k]]) + } + } + return b + } +} diff --git a/Reply/stream.go b/Reply/stream.go index 5889bd4..7054b67 100644 --- a/Reply/stream.go +++ b/Reply/stream.go @@ -585,10 +585,11 @@ func (t *M4SStream) saveStreamFlv() (e error) { t.log.L(`I: `, `flv下载开始`) - if err := r.Reqf(reqf.Rval{ + r.Reqf(reqf.Rval{ Url: surl.String(), SaveToPipeWriter: rw, NoResponse: true, + Async: true, Proxy: t.common.Proxy, Header: map[string]string{ `Host`: surl.Host, @@ -602,7 +603,8 @@ func (t *M4SStream) saveStreamFlv() (e error) { `Referer`: "https://live.bilibili.com/", `Cookie`: reqf.Map_2_Cookies_String(CookieM), }, - }); err != nil && !errors.Is(err, io.EOF) { + }) + if e := r.Wait(); e != nil && !errors.Is(err, io.EOF) { if reqf.IsCancel(err) { t.log.L(`I: `, `flv下载停止`) } else if !reqf.IsTimeout(err) { @@ -630,13 +632,9 @@ func (t *M4SStream) saveStreamM4s() (e error) { Max: 3, } - var out *os.File + var out *file.File if t.config.save_as_mp4 { - var err error - out, err = os.Create(t.Current_save_path + `0.mp4`) - if err != nil { - out.Close() - } + out = file.New(t.Current_save_path+`0.mp4`, 0, false) defer out.Close() } @@ -656,15 +654,18 @@ func (t *M4SStream) saveStreamM4s() (e error) { // 下载切片 for _, v := range download_seq { + + // 已下载但还未移除的切片 + if v.status == 2 { + download_limit.Block() + download_limit.UnBlock() + continue + } + go func(link *m4s_link_item, path string) { defer download_limit.UnBlock() download_limit.Block() - // 已下载但还未移除的切片 - if link.status == 2 { - return - } - link.status = 1 // 设置切片状态为正在下载 link.tryDownCount += 1 @@ -735,27 +736,38 @@ func (t *M4SStream) saveStreamM4s() (e error) { { for _, v := range download_seq { if v.status == 2 { - download_seq = download_seq[1:] - buf = append(buf, v.data...) - if strings.Contains(v.Base, `h`) { - if e := fmp4Decoder.Init_fmp4(v.data); e != nil { - t.log.L(`E: `, e) + if header, e := fmp4Decoder.Init_fmp4(v.data); e != nil { + t.log.L(`E: `, e, ` 重试!`) + v.status = 3 + break } else { for _, trak := range fmp4Decoder.traks { t.log.L(`T: `, "找到trak:", string(trak.handlerType), trak.trackID, trak.timescale) } + t.first_buf = header + if out != nil { + out.Write(t.first_buf, true) + out.Sync() + } } - t.first_buf = v.data - if t.config.save_as_mp4 { - out.Write(v.data) - } + download_seq = download_seq[1:] + continue + } else if t.first_buf == nil { + download_seq = download_seq[1:] continue } - fmp4KeyFrames, last_avilable_offset, e := fmp4Decoder.Seach_stream_fmp4(buf) - if e != nil { - t.log.L(`E: `, e) + download_seq = download_seq[1:] + buf = append(buf, v.data...) + + fmp4KeyFrames, last_avilable_offset, err := fmp4Decoder.Seach_stream_fmp4(buf) + if err != nil { + t.log.L(`E: `, err) + if err.Error() == "未初始化traks" { + e = err + return + } //丢弃所有数据 last_avilable_offset = len(buf) } @@ -763,8 +775,9 @@ func (t *M4SStream) saveStreamM4s() (e error) { for _, fmp4KeyFrame := range fmp4KeyFrames { t.bootBufPush(fmp4KeyFrame) t.Stream_msg.Push_tag(`data`, fmp4KeyFrame) - if t.config.save_as_mp4 { - out.Write(fmp4KeyFrame) + if out != nil { + out.Write(fmp4KeyFrame, true) + out.Sync() } } @@ -778,9 +791,6 @@ func (t *M4SStream) saveStreamM4s() (e error) { break } } - if t.config.save_as_mp4 { - out.Sync() - } } // 停止录制 diff --git a/Reply/tts.go b/Reply/tts.go index dd3be38..3cdf667 100644 --- a/Reply/tts.go +++ b/Reply/tts.go @@ -7,6 +7,7 @@ import ( "encoding/json" "errors" "fmt" + "io" "net/url" "os/exec" "strings" @@ -78,7 +79,7 @@ func init() { } bb, err := file.New("config/config_tts.json", 0, true).ReadAll(100, 1<<16) - if err != nil { + if !errors.Is(err, io.EOF) { return } var buf map[string]interface{} diff --git a/Send/Send.go b/Send/Send.go index 71763e4..e464db1 100644 --- a/Send/Send.go +++ b/Send/Send.go @@ -2,6 +2,8 @@ package send import ( "encoding/json" + "errors" + "io" "strconv" c "github.com/qydysky/bili_danmu/CV" @@ -19,7 +21,7 @@ var damnu_official = make(map[string]string) // 初始化表情代码 func init() { bb, err := file.New("config/config_danmu_official.json", 0, true).ReadAll(1000, 1<<16) - if err != nil { + if !errors.Is(err, io.EOF) { return } var buf map[string]interface{} diff --git a/demo/config/config_disable_msg.json b/demo/config/config_disable_msg.json index 1e836f5..511d3e6 100644 --- a/demo/config/config_disable_msg.json +++ b/demo/config/config_disable_msg.json @@ -2,5 +2,6 @@ "help":"禁用指定消息类型,false将忽略此类消息,true将显示此类消息的json纯文本", "PK_BATTLE_PRE":false, "LIVE_INTERACTIVE_GAME":false, - "room_admin_entrance":false + "room_admin_entrance":false, + "LIKE_INFO_V3_CLICK":false } \ No newline at end of file diff --git a/demo/go.mod b/demo/go.mod index 299647f..6859a05 100644 --- a/demo/go.mod +++ b/demo/go.mod @@ -15,7 +15,7 @@ require ( github.com/mdp/qrterminal/v3 v3.0.0 // indirect github.com/miekg/dns v1.1.50 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect - github.com/qydysky/part v0.18.19 // indirect + github.com/qydysky/part v0.19.2 // indirect github.com/shirou/gopsutil v3.21.11+incompatible // indirect github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect @@ -35,5 +35,4 @@ require ( replace ( github.com/gotk3/gotk3 v0.5.2 => github.com/qydysky/gotk3 v0.0.0-20210103171910-327affdaaa80 github.com/qydysky/bili_danmu => ../ -//github.com/qydysky/part => ../../part ) diff --git a/demo/go.sum b/demo/go.sum index eb5e374..a2cb305 100644 --- a/demo/go.sum +++ b/demo/go.sum @@ -124,6 +124,12 @@ github.com/qydysky/part v0.10.18 h1:GGHuGBsKI6h41EzzVml3FMbqDS1dh88wSDmQBfq2jtw= github.com/qydysky/part v0.10.18/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/qydysky/part v0.18.19 h1:s4CL+ljiGhySX633x0ohN6NA2c7T/BWg5YVpjm4xo30= github.com/qydysky/part v0.18.19/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.0 h1:H0esXkedZKrYdEEACC76O+DL9TZDkApow67RYLSyT0U= +github.com/qydysky/part v0.19.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.1 h1:3AdjJtm5Q594Jd/My1E1wQIiRPXgmS+KM1DJhofLr1M= +github.com/qydysky/part v0.19.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.2 h1:peR1UBrBgnjB63nv5F100oJ72hRoJnn8cuZPXDiGZOM= +github.com/qydysky/part v0.19.2/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.5+incompatible h1:OloQyEerMi7JUrXiNzy8wQ5XN+baemxSl12QgIzt0jc= github.com/shirou/gopsutil v3.21.5+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= diff --git a/go.mod b/go.mod index 96cf06f..9f42409 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,7 @@ require ( github.com/gofrs/uuid v4.3.0+incompatible github.com/gotk3/gotk3 v0.6.1 github.com/mdp/qrterminal/v3 v3.0.0 - github.com/qydysky/part v0.18.19 + github.com/qydysky/part v0.19.2 github.com/skip2/go-qrcode v0.0.0-20200617195104-da1b6568686e github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 golang.org/x/text v0.3.8 diff --git a/go.sum b/go.sum index 75ef6c4..f2aba98 100644 --- a/go.sum +++ b/go.sum @@ -58,6 +58,12 @@ github.com/qydysky/part v0.10.18 h1:GGHuGBsKI6h41EzzVml3FMbqDS1dh88wSDmQBfq2jtw= github.com/qydysky/part v0.10.18/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/qydysky/part v0.18.19 h1:s4CL+ljiGhySX633x0ohN6NA2c7T/BWg5YVpjm4xo30= github.com/qydysky/part v0.18.19/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.0 h1:H0esXkedZKrYdEEACC76O+DL9TZDkApow67RYLSyT0U= +github.com/qydysky/part v0.19.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.1 h1:3AdjJtm5Q594Jd/My1E1wQIiRPXgmS+KM1DJhofLr1M= +github.com/qydysky/part v0.19.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.19.2 h1:peR1UBrBgnjB63nv5F100oJ72hRoJnn8cuZPXDiGZOM= +github.com/qydysky/part v0.19.2/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/shirou/gopsutil v3.20.12+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA= github.com/shirou/gopsutil v3.21.11+incompatible h1:+1+c1VGhc88SSonWP6foOcLhvnKlUeu/erjjvaPEYiI= github.com/shirou/gopsutil v3.21.11+incompatible/go.mod h1:5b4v6he4MtMOwMlS0TUMTu2PcXUg8+E1lC7eC3UO/RA=