]> 127.0.0.1 Git - bili_danmu/.git/commitdiff
fix
authorqydysky <32743305+qydysky@users.noreply.github.com>
Sun, 27 Nov 2022 16:45:20 +0000 (00:45 +0800)
committerqydysky <32743305+qydysky@users.noreply.github.com>
Sun, 27 Nov 2022 16:45:20 +0000 (00:45 +0800)
12 files changed:
Reply/F.go
Reply/Msg.go
Reply/fmp4Decode.go
Reply/sliceBuf.go [new file with mode: 0644]
Reply/stream.go
Reply/tts.go
Send/Send.go
demo/config/config_disable_msg.json
demo/go.mod
demo/go.sum
go.mod
go.sum

index ac3a4b3ca76f5188013251c05b33635904bc60e6..6fc4e9f1a172d8f924e4b7404aa7d863966071e2 100644 (file)
@@ -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{}
index 43bf35f95066eae84ab351e29e556705b49d8352..92f4b14631ca7978af8c00d8c442b1316ce91ebf 100644 (file)
@@ -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{}
index 192799fe9ed6eeeb4a28d97324e5e46df613d5c4..3d2a2567d1f7379a73827102b2b0c6c02bb2fe23 100644 (file)
@@ -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 (file)
index 0000000..cf40af7
--- /dev/null
@@ -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
+       }
+}
index 5889bd4780545c0d6feb8c00d42159ef1eb0103a..7054b6708e9de47317c67021844369b98735429d 100644 (file)
@@ -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()
-                       }
                }
 
                // 停止录制
index dd3be381f4815d01fb611a2b2fc23b0ff7b4ac61..3cdf667830f32383a5fc8ca61c2b1a40b8555b87 100644 (file)
@@ -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{}
index 71763e40ddc2b9bbd0658603bab0c5faeb16a3cc..e464db1a926c1be74e23612c847bca4a76299e37 100644 (file)
@@ -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{}
index 1e836f5e46e3f1a44900a517c5fb1ee0fd2b424f..511d3e65c5841740802098d0a9751017371b0fb3 100644 (file)
@@ -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
index 299647fd319ca9ceba1be4a2cf7972593493514f..6859a058c98c9f52cc7a71f1a5dd59dfc0d1a7a0 100644 (file)
@@ -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
 )
index eb5e374f59c948a7bf94cc1d3ec7ab69c3cc88e0..a2cb305a2f0ba6c8684d54df8268642d05dc45e7 100644 (file)
@@ -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 96cf06f39303b33d8565b41385f86d1d22a22b18..9f4240924964a1f11d763c94b02360c98d575287 100644 (file)
--- 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 75ef6c4fc82fece9b3acad2c5fc80704becbc90e..f2aba98a6cb69eb92930c8c5b86afd11a29b3fc5 100644 (file)
--- 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=