From 4eb3ea8543a64bff0bdac5d4021865a39024a5d1 Mon Sep 17 00:00:00 2001 From: qydysky <32743305+qydysky@users.noreply.github.com> Date: Thu, 19 Jan 2023 01:08:13 +0800 Subject: [PATCH] =?utf8?q?part=E4=BE=9D=E8=B5=96=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit --- CV/Var.go | 2 +- Reply/Reply.go | 2 +- Reply/fmp4Decode.go | 34 +++++++----- Reply/sliceBuf.go | 132 -------------------------------------------- Reply/stream.go | 122 ++++++++++++++++------------------------ demo/go.mod | 2 +- demo/go.sum | 16 ++++++ go.mod | 2 +- go.sum | 16 ++++++ 9 files changed, 103 insertions(+), 225 deletions(-) delete mode 100644 Reply/sliceBuf.go diff --git a/CV/Var.go b/CV/Var.go index 495e47d..b1c5bda 100644 --- a/CV/Var.go +++ b/CV/Var.go @@ -71,7 +71,7 @@ func (t *Common) Init() Common { 80: "流畅", } - t.Danmu_Main_mq = mq.New(200) + t.Danmu_Main_mq = mq.New() t.ReqPool = idpool.New(func() interface{} { return reqf.New() diff --git a/Reply/Reply.go b/Reply/Reply.go index baedf09..0357a31 100644 --- a/Reply/Reply.go +++ b/Reply/Reply.go @@ -1136,7 +1136,7 @@ type Danmu_mq_t struct { m map[string]string //tts参数替换列表 } -var Danmu_mq = mq.New(10) +var Danmu_mq = mq.New() // 消息显示 func Gui_show(m ...string) { diff --git a/Reply/fmp4Decode.go b/Reply/fmp4Decode.go index b409b07..d8ee4f6 100644 --- a/Reply/fmp4Decode.go +++ b/Reply/fmp4Decode.go @@ -6,6 +6,7 @@ import ( "io" F "github.com/qydysky/bili_danmu/F" + slice "github.com/qydysky/part/slice" ) var boxs map[string]bool @@ -57,7 +58,7 @@ func (t *timeStamp) getT() float64 { type Fmp4Decoder struct { traks map[int]trak - buf bufB + buf *slice.Buf[byte] } func (t *Fmp4Decoder) Init_fmp4(buf []byte) (b []byte, err error) { @@ -114,16 +115,19 @@ func (t *Fmp4Decoder) Init_fmp4(buf []byte) (b []byte, err error) { return b, nil } -func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, err error) { +func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *slice.Buf[byte]) (cu int, err error) { if len(t.traks) == 0 { err = errors.New("未初始化traks") return } - t.buf.reset() + if t.buf == nil { + t.buf = slice.New[byte]() + } + t.buf.Reset() var ( haveKeyframe bool - bufModified = t.buf.getModifiedTime() + bufModified = t.buf.GetModified() // maxSequenceNumber int //有时并不是单调增加 maxVT float64 maxAT float64 @@ -206,7 +210,7 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, er if nil != check_set_maxT(ts, func(_ timeStamp) error { return errors.New("skip") }, func(_ timeStamp) error { - t.buf.reset() + t.buf.Reset() haveKeyframe = false cu = m[0].i return errors.New("skip") @@ -219,17 +223,17 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, er //deal frame if keyframeMoof { - if t.buf.hadModified(bufModified) && !t.buf.isEmpty() { - keyframes.append(t.buf.getPureBuf()) + if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() { + keyframes.Append(t.buf.GetPureBuf()) cu = m[0].i - t.buf.reset() + t.buf.Reset() } haveKeyframe = true } else if !haveKeyframe { cu = m[6].e } if haveKeyframe { - t.buf.append(buf[m[0].i:m[6].e]) + t.buf.Append(buf[m[0].i:m[6].e]) } return false }, @@ -254,7 +258,7 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, er if nil != check_set_maxT(ts, func(_ timeStamp) error { return errors.New("skip") }, func(_ timeStamp) error { - t.buf.reset() + t.buf.Reset() haveKeyframe = false cu = m[0].i return errors.New("skip") @@ -273,7 +277,7 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, er if nil != check_set_maxT(ts, func(_ timeStamp) error { return errors.New("skip") }, func(_ timeStamp) error { - t.buf.reset() + t.buf.Reset() haveKeyframe = false cu = m[0].i return errors.New("skip") @@ -290,17 +294,17 @@ func (t *Fmp4Decoder) Seach_stream_fmp4(buf []byte, keyframes *bufB) (cu int, er //deal frame if keyframeMoof { - if t.buf.hadModified(bufModified) && !t.buf.isEmpty() { - keyframes.append(t.buf.getPureBuf()) + if v, e := t.buf.HadModified(bufModified); e == nil && v && !t.buf.IsEmpty() { + keyframes.Append(t.buf.GetPureBuf()) cu = m[0].i - t.buf.reset() + t.buf.Reset() } haveKeyframe = true } else if !haveKeyframe { cu = m[10].e } if haveKeyframe { - t.buf.append(buf[m[0].i:m[10].e]) + t.buf.Append(buf[m[0].i:m[10].e]) } return false }}) diff --git a/Reply/sliceBuf.go b/Reply/sliceBuf.go deleted file mode 100644 index 1831f29..0000000 --- a/Reply/sliceBuf.go +++ /dev/null @@ -1,132 +0,0 @@ -package reply - -import ( - "sync" - "time" -) - -type bufB struct { - bufsize int - modifiedTime time.Time - buf []byte - sync.RWMutex -} - -func (t *bufB) size() int { - t.RLock() - defer t.RUnlock() - - return t.bufsize -} - -func (t *bufB) isEmpty() bool { - t.RLock() - defer t.RUnlock() - - return t.bufsize == 0 -} - -func (t *bufB) reset() { - t.Lock() - defer t.Unlock() - - t.bufsize = 0 -} - -func (t *bufB) append(data []byte) { - t.Lock() - defer t.Unlock() - - if len(t.buf) == 0 { - t.buf = make([]byte, len(data)) - } else { - diff := len(t.buf) - t.bufsize - len(data) - if diff < 0 { - t.buf = append(t.buf, make([]byte, -diff)...) - } else { - t.buf = t.buf[:t.bufsize+len(data)] - } - } - t.bufsize += copy(t.buf[t.bufsize:], data) - t.modifiedTime = time.Now() -} - -func (t *bufB) removeFront(n int) { - if n <= 0 { - return - } - - t.Lock() - defer t.Unlock() - - if t.bufsize == 0 { - return - } else if t.bufsize < n { - panic("尝试移除的数值大于长度") - } else if t.bufsize == n { - t.bufsize = 0 - } else { - t.bufsize = copy(t.buf, t.buf[n:t.bufsize]) - } - - t.modifiedTime = time.Now() -} - -func (t *bufB) removeBack(n int) { - if n <= 0 { - return - } - - t.Lock() - defer t.Unlock() - - if t.bufsize == 0 { - return - } else if t.bufsize < n { - panic("尝试移除的数值大于长度") - } else if t.bufsize == n { - t.bufsize = 0 - } else { - t.bufsize -= n - } - - t.modifiedTime = time.Now() -} - -func (t *bufB) setModifiedTime() { - t.Lock() - defer t.Unlock() - - t.modifiedTime = time.Now() -} - -func (t *bufB) getModifiedTime() time.Time { - t.RLock() - defer t.RUnlock() - - return t.modifiedTime -} - -func (t *bufB) hadModified(mt time.Time) bool { - t.RLock() - defer t.RUnlock() - - return !t.modifiedTime.Equal(mt) -} - -// // 通常情况下使用getCopyBuf替代 -func (t *bufB) getPureBuf() (buf []byte) { - t.RLock() - defer t.RUnlock() - - return t.buf[:t.bufsize] -} - -func (t *bufB) getCopyBuf() (buf []byte) { - t.RLock() - defer t.RUnlock() - - buf = make([]byte, t.bufsize) - copy(buf, t.buf[:t.bufsize]) - return -} diff --git a/Reply/stream.go b/Reply/stream.go index d78ecdf..d578029 100644 --- a/Reply/stream.go +++ b/Reply/stream.go @@ -13,7 +13,6 @@ import ( "path/filepath" "strconv" "strings" - "sync" "time" c "github.com/qydysky/bili_danmu/CV" @@ -25,8 +24,10 @@ import ( idpool "github.com/qydysky/part/idpool" log "github.com/qydysky/part/log" msgq "github.com/qydysky/part/msgq" + pool "github.com/qydysky/part/pool" reqf "github.com/qydysky/part/reqf" signal "github.com/qydysky/part/signal" + slice "github.com/qydysky/part/slice" psync "github.com/qydysky/part/sync" ) @@ -44,16 +45,15 @@ type M4SStream struct { boot_buf [][]byte //快速启动缓冲 boot_buf_size int //快速启动缓冲长度 boot_buf_locker funcCtrl.BlockFunc - last_m4s *m4s_link_item //最后一个切片 - m4s_pool []*m4s_link_item //切片pool - m4s_pool_l sync.Mutex - common c.Common //通用配置副本 - Current_save_path string //明确的直播流保存目录 - Callback_start func(*M4SStream) //实例开始的回调 - Callback_startRec func(*M4SStream) //录制开始的回调 - Callback_stopRec func(*M4SStream) //录制结束的回调 - Callback_stop func(*M4SStream) //实例结束的回调 - reqPool *idpool.Idpool //请求池 + last_m4s *m4s_link_item //最后一个切片 + m4s_pool *pool.Buf[m4s_link_item] //切片pool + common c.Common //通用配置副本 + Current_save_path string //明确的直播流保存目录 + Callback_start func(*M4SStream) //实例开始的回调 + Callback_startRec func(*M4SStream) //录制开始的回调 + Callback_stopRec func(*M4SStream) //录制结束的回调 + Callback_stop func(*M4SStream) //实例结束的回调 + reqPool *idpool.Idpool //请求池 } type M4SStream_Config struct { @@ -109,55 +109,29 @@ func (t *m4s_link_item) getNo() (int, error) { } func (t *M4SStream) getM4s() (p *m4s_link_item) { - t.m4s_pool_l.Lock() - defer t.m4s_pool_l.Unlock() - - for i := 0; i < len(t.m4s_pool); i++ { - if t.m4s_pool[i].pooledTime.After(t.m4s_pool[i].createdTime) && time.Now().After(t.m4s_pool[i].pooledTime.Add(time.Second*10)) { - // fmt.Println("=>", i) - return t.m4s_pool[i].reset() - } + if t.m4s_pool == nil { + t.m4s_pool = pool.New( + func() *m4s_link_item { + return &m4s_link_item{} + }, + func(t *m4s_link_item) bool { + return !t.pooledTime.IsZero() || t.createdTime.After(t.pooledTime) || time.Now().Before(t.pooledTime.Add(time.Second*10)) + }, + func(t *m4s_link_item) *m4s_link_item { + return t.reset() + }, + func(t *m4s_link_item) *m4s_link_item { + t.pooledTime = time.Now() + return t + }, + 50, + ) } - // fmt.Println("=>") - return &m4s_link_item{} + return t.m4s_pool.Get() } func (t *M4SStream) putM4s(ms ...*m4s_link_item) { - t.m4s_pool_l.Lock() - defer t.m4s_pool_l.Unlock() - - for i := 0; i < len(ms); i++ { - if cap(ms[i].data) == 0 { - ms[i] = nil - ms = append(ms[:i], ms[i+1:]...) - i-- - } else if len(ms[i].data) != 0 { - ms[i].pooledTime = time.Now() - if len(t.m4s_pool) < 50 { - t.m4s_pool = append(t.m4s_pool, ms[i]) - } - } - // else { - // fmt.Println("z", cap(ms[i].data)) - // } - } - - for i := 0; i < len(t.m4s_pool); i++ { - if t.m4s_pool[i].pooledTime.After(t.m4s_pool[i].createdTime) && time.Now().After(t.m4s_pool[i].pooledTime.Add(time.Second*30)) { - t.m4s_pool[i].data = nil - } - } - - // for i := 0; i < len(ms); i++ { - // if ms[i].pooledTime.IsZero() { - // fmt.Println("z", cap(ms[i].data)) - // } - // ms[i].pooledTime = time.Now() - // if len(t.m4s_pool) < 50 { - // t.m4s_pool = append(t.m4s_pool, ms[i]) - // } - // } - // fmt.Println("size", len(t.m4s_pool)) + t.m4s_pool.Put(ms...) } func (t *M4SStream) Common() c.Common { @@ -633,12 +607,12 @@ func (t *M4SStream) saveStreamFlv() (e error) { go func() { var ( ticker = time.NewTicker(time.Second) - buff bufB + buff = slice.New[byte]() buf = make([]byte, 1<<16) ) for { n, e := rc.Read(buf) - buff.append(buf[:n]) + buff.Append(buf[:n]) if e != nil { out.Close() t.Stream_msg.Push_tag(`close`, nil) @@ -656,8 +630,8 @@ func (t *M4SStream) saveStreamFlv() (e error) { continue } - if !buff.isEmpty() { - front_buf, keyframe, last_avilable_offset, e := Seach_stream_tag(buff.getCopyBuf()) + if !buff.IsEmpty() { + front_buf, keyframe, last_avilable_offset, e := Seach_stream_tag(buff.GetCopyBuf()) if e != nil { if strings.Contains(e.Error(), `no found available tag`) { continue @@ -679,14 +653,14 @@ func (t *M4SStream) saveStreamFlv() (e error) { } if last_avilable_offset > 1 { // fmt.Println("write Sync") - buff.removeFront(last_avilable_offset - 1) + buff.RemoveFront(last_avilable_offset - 1) out.Sync() } } } buf = nil - buff.reset() + buff.Reset() }() CookieM := make(map[string]string) @@ -752,8 +726,8 @@ func (t *M4SStream) saveStreamM4s() (e error) { // var ( - buf bufB - fmp4KeyFrames bufB + buf = slice.New[byte]() + fmp4KeyFrames = slice.New[byte]() fmp4KeyFramesBuf []byte fmp4Decoder = &Fmp4Decoder{} ) @@ -826,7 +800,7 @@ func (t *M4SStream) saveStreamM4s() (e error) { } if e := r.Reqf(reqConfig); e != nil && !errors.Is(e, io.EOF) { if !reqf.IsTimeout(e) { - t.log.L(`E: `, `hls切片下载失败:`, link.Url, e) + t.log.L(`E: `, `hls切片下载失败:`, link.Url, e, string(r.Respon)) link.tryDownCount = 4 // 设置切片状态为下载失败 } else { link.status = 3 // 设置切片状态为下载失败 @@ -900,12 +874,12 @@ func (t *M4SStream) saveStreamM4s() (e error) { continue } - buf.append(download_seq[k].data) + buf.Append(download_seq[k].data) t.putM4s(download_seq[k]) download_seq = append(download_seq[:k], download_seq[k+1:]...) k -= 1 - last_avilable_offset, err := fmp4Decoder.Seach_stream_fmp4(buf.getPureBuf(), &fmp4KeyFrames) + last_avilable_offset, err := fmp4Decoder.Seach_stream_fmp4(buf.GetPureBuf(), fmp4KeyFrames) if err != nil { if !errors.Is(err, io.EOF) { t.log.L(`E: `, err) @@ -919,9 +893,9 @@ func (t *M4SStream) saveStreamM4s() (e error) { return } //丢弃所有数据 - buf.reset() + buf.Reset() } else { - fmp4KeyFrames.reset() + fmp4KeyFrames.Reset() last_avilable_offset = 0 } } @@ -929,9 +903,9 @@ func (t *M4SStream) saveStreamM4s() (e error) { // no, _ := v.getNo() // fmt.Println(no, "fmp4KeyFrames", fmp4KeyFrames.size(), last_avilable_offset, err) - if !fmp4KeyFrames.isEmpty() { - fmp4KeyFramesBuf = fmp4KeyFrames.getCopyBuf() - fmp4KeyFrames.reset() + if !fmp4KeyFrames.IsEmpty() { + fmp4KeyFramesBuf = fmp4KeyFrames.GetCopyBuf() + fmp4KeyFrames.Reset() t.bootBufPush(fmp4KeyFramesBuf) t.Stream_msg.Push_tag(`data`, fmp4KeyFramesBuf) if out != nil { @@ -940,7 +914,7 @@ func (t *M4SStream) saveStreamM4s() (e error) { } } - buf.removeFront(last_avilable_offset) + buf.RemoveFront(last_avilable_offset) } // 停止录制 @@ -1065,7 +1039,7 @@ func (t *M4SStream) Start() bool { t.reqPool = t.common.ReqPool // 初始化切片消息 - t.Stream_msg = msgq.New(5) + t.Stream_msg = msgq.New() // 初始化快速启动缓冲 if v, ok := t.common.K_v.LoadV(`直播Web缓冲长度`).(float64); ok && v != 0 { diff --git a/demo/go.mod b/demo/go.mod index 7e834ce..7022417 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.20.1 // indirect + github.com/qydysky/part v0.21.7 // 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 diff --git a/demo/go.sum b/demo/go.sum index 61d450e..211d4cc 100644 --- a/demo/go.sum +++ b/demo/go.sum @@ -134,6 +134,22 @@ github.com/qydysky/part v0.20.0 h1:JkAdTrGwXjbL8FJuiinKK8Vrd2HU/rcRD+Bdx4RpGGw= github.com/qydysky/part v0.20.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/qydysky/part v0.20.1 h1:C0VDY/OZHEVRD1SeudG67t/7/0qUMlfJcy8CQQKVZ9A= github.com/qydysky/part v0.20.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.0 h1:a38ZmzaKXrfXoempsLkMhuo4pzxQcZW/GnvkShInqig= +github.com/qydysky/part v0.21.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.1 h1:SmtiTxNL2eYFHFwisx96mIrMTEsMttyoMYPnDOtHAMQ= +github.com/qydysky/part v0.21.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.2 h1:KDPeTRlsjEl8mxn+M/wA0cmmiZisduptmzVjRYVUyoI= +github.com/qydysky/part v0.21.2/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.3 h1:gZ7awiaT2ezvX6Y+H50JSA+vWkQoMYNuN/cl919cwdo= +github.com/qydysky/part v0.21.3/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.4 h1:dIK3O6KQ3TLe6I1lGDlvHhUI9SJss//QnqZ3MJV9UME= +github.com/qydysky/part v0.21.4/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.5 h1:0vEiUFTRLdWcOE+crh6HRXHARJtEK9vZfKfaWo55Dig= +github.com/qydysky/part v0.21.5/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.6 h1:38mEneSgc47gnmPxFXRZcAywTbS+QxMqrwgOyznAokk= +github.com/qydysky/part v0.21.6/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.7 h1:R3x5dv324ZeIYUMjZZ+LNQhT04KSNOQ+h2ahtG0hIfE= +github.com/qydysky/part v0.21.7/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 024ae1a..a42c19d 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.20.1 + github.com/qydysky/part v0.21.7 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 9df4c1b..8299eeb 100644 --- a/go.sum +++ b/go.sum @@ -40,6 +40,22 @@ github.com/qydysky/part v0.20.0 h1:JkAdTrGwXjbL8FJuiinKK8Vrd2HU/rcRD+Bdx4RpGGw= github.com/qydysky/part v0.20.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= github.com/qydysky/part v0.20.1 h1:C0VDY/OZHEVRD1SeudG67t/7/0qUMlfJcy8CQQKVZ9A= github.com/qydysky/part v0.20.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.0 h1:a38ZmzaKXrfXoempsLkMhuo4pzxQcZW/GnvkShInqig= +github.com/qydysky/part v0.21.0/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.1 h1:SmtiTxNL2eYFHFwisx96mIrMTEsMttyoMYPnDOtHAMQ= +github.com/qydysky/part v0.21.1/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.2 h1:KDPeTRlsjEl8mxn+M/wA0cmmiZisduptmzVjRYVUyoI= +github.com/qydysky/part v0.21.2/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.3 h1:gZ7awiaT2ezvX6Y+H50JSA+vWkQoMYNuN/cl919cwdo= +github.com/qydysky/part v0.21.3/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.4 h1:dIK3O6KQ3TLe6I1lGDlvHhUI9SJss//QnqZ3MJV9UME= +github.com/qydysky/part v0.21.4/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.5 h1:0vEiUFTRLdWcOE+crh6HRXHARJtEK9vZfKfaWo55Dig= +github.com/qydysky/part v0.21.5/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.6 h1:38mEneSgc47gnmPxFXRZcAywTbS+QxMqrwgOyznAokk= +github.com/qydysky/part v0.21.6/go.mod h1:BG0tulTKW58jSkC0EZ0MrxDHe+gkPULfGNzksiGCayw= +github.com/qydysky/part v0.21.7 h1:R3x5dv324ZeIYUMjZZ+LNQhT04KSNOQ+h2ahtG0hIfE= +github.com/qydysky/part v0.21.7/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= -- 2.39.2