80: "流畅",
}
- t.Danmu_Main_mq = mq.New(200)
+ t.Danmu_Main_mq = mq.New()
t.ReqPool = idpool.New(func() interface{} {
return reqf.New()
m map[string]string //tts参数替换列表
}
-var Danmu_mq = mq.New(10)
+var Danmu_mq = mq.New()
// 消息显示
func Gui_show(m ...string) {
"io"
F "github.com/qydysky/bili_danmu/F"
+ slice "github.com/qydysky/part/slice"
)
var boxs map[string]bool
type Fmp4Decoder struct {
traks map[int]trak
- buf bufB
+ buf *slice.Buf[byte]
}
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
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")
//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
},
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")
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")
//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
}})
+++ /dev/null
-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
-}
"path/filepath"
"strconv"
"strings"
- "sync"
"time"
c "github.com/qydysky/bili_danmu/CV"
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"
)
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 {
}
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 {
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)
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
}
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)
//
var (
- buf bufB
- fmp4KeyFrames bufB
+ buf = slice.New[byte]()
+ fmp4KeyFrames = slice.New[byte]()
fmp4KeyFramesBuf []byte
fmp4Decoder = &Fmp4Decoder{}
)
}
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 // 设置切片状态为下载失败
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)
return
}
//丢弃所有数据
- buf.reset()
+ buf.Reset()
} else {
- fmp4KeyFrames.reset()
+ fmp4KeyFrames.Reset()
last_avilable_offset = 0
}
}
// 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 {
}
}
- buf.removeFront(last_avilable_offset)
+ buf.RemoveFront(last_avilable_offset)
}
// 停止录制
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 {
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
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=
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
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=