From: qydysky Date: Tue, 16 Jan 2024 13:01:37 +0000 (+0800) Subject: Fix clear slice的错误使用 X-Git-Tag: v0.12.4~1 X-Git-Url: http://127.0.0.1:8081/?a=commitdiff_plain;h=2f2b4158cefda87902189d36de7329bdbd65ebc0;p=bili_danmu%2F.git Fix clear slice的错误使用 --- diff --git a/CV/Var.go b/CV/Var.go index a2d95c1..4450d66 100644 --- a/CV/Var.go +++ b/CV/Var.go @@ -42,46 +42,46 @@ type StreamType struct { } type Common struct { - PID int `json:"pid"` //进程id - Version string `json:"version"` //版本 - Uid int `json:"-"` //client uid - Live []LiveQn `json:"-"` //直播流链接 - Live_qn int `json:"liveQn"` //当前直播流质量 - Live_want_qn int `json:"-"` //期望直播流质量 - Roomid int `json:"roomid"` //房间ID - Cookie syncmap.Map `json:"-"` //Cookie - Title string `json:"title"` //直播标题 - Uname string `json:"uname"` //主播名 - UpUid int `json:"upUid"` //主播uid - Rev float64 `json:"rev"` //营收 - Renqi int `json:"renqi"` //人气 - Watched int `json:"watched"` //观看人数 - OnlineNum int `json:"onlineNum"` //在线人数 - GuardNum int `json:"guardNum"` //舰长数 - ParentAreaID int `json:"parentAreaID"` //父分区 - AreaID int `json:"areaID"` //子分区 - Locked bool `json:"locked"` //直播间封禁 - Note string `json:"note"` //分区排行 - Live_Start_Time time.Time `json:"liveStartTime"` //直播开始时间 - Liveing bool `json:"liveing"` //是否在直播 - Wearing_FansMedal int `json:"-"` //当前佩戴的粉丝牌 - Token string `json:"-"` //弹幕钥 - WSURL []string `json:"-"` //弹幕链接 - LiveBuvidUpdated time.Time `json:"-"` //LIVE_BUVID更新时间 - Stream_url *url.URL `json:"-"` //直播Web服务 - Proxy string `json:"-"` //全局代理 - AcceptQn map[int]string `json:"-"` //允许的直播流质量 - Qn map[int]string `json:"-"` //全部直播流质量 - StreamType StreamType `json:"streamType"` //当前直播流类型 - AllStreamType map[string]StreamType `json:"-"` //直播流类型 - K_v syncmap.Map `json:"-"` //配置文件 - Log *log.Log_interface `json:"-"` //日志 - Danmu_Main_mq *mq.Msgq `json:"-"` //消息 - ReqPool *pool.Buf[reqf.Req] `json:"-"` //请求池 - SerF *web.WebPath `json:"-"` //web服务处理 - SerLimit *web.Limits `json:"-"` //Web服务连接限制 - StartT time.Time `json:"startT"` //启动时间 - Cache syncmap.Map `json:"-"` //缓存 + PID int `json:"pid"` //进程id + Version string `json:"version"` //版本 + Uid int `json:"-"` //client uid + Live []LiveQn `json:"-"` //直播流链接 + Live_qn int `json:"liveQn"` //当前直播流质量 + Live_want_qn int `json:"-"` //期望直播流质量 + Roomid int `json:"roomid"` //房间ID + Cookie syncmap.Map `json:"-"` //Cookie + Title string `json:"title"` //直播标题 + Uname string `json:"uname"` //主播名 + UpUid int `json:"upUid"` //主播uid + Rev float64 `json:"rev"` //营收 + Renqi int `json:"renqi"` //人气 + Watched int `json:"watched"` //观看人数 + OnlineNum int `json:"onlineNum"` //在线人数 + GuardNum int `json:"guardNum"` //舰长数 + ParentAreaID int `json:"parentAreaID"` //父分区 + AreaID int `json:"areaID"` //子分区 + Locked bool `json:"locked"` //直播间封禁 + Note string `json:"note"` //分区排行 + Live_Start_Time time.Time `json:"liveStartTime"` //直播开始时间 + Liveing bool `json:"liveing"` //是否在直播 + Wearing_FansMedal int `json:"-"` //当前佩戴的粉丝牌 + Token string `json:"-"` //弹幕钥 + WSURL []string `json:"-"` //弹幕链接 + LiveBuvidUpdated time.Time `json:"-"` //LIVE_BUVID更新时间 + Stream_url *url.URL `json:"-"` //直播Web服务 + Proxy string `json:"-"` //全局代理 + AcceptQn map[int]string `json:"-"` //允许的直播流质量 + Qn map[int]string `json:"-"` //全部直播流质量 + // StreamType StreamType `json:"streamType"` //当前直播流类型 + AllStreamType map[string]StreamType `json:"-"` //直播流类型 + K_v syncmap.Map `json:"-"` //配置文件 + Log *log.Log_interface `json:"-"` //日志 + Danmu_Main_mq *mq.Msgq `json:"-"` //消息 + ReqPool *pool.Buf[reqf.Req] `json:"-"` //请求池 + SerF *web.WebPath `json:"-"` //web服务处理 + SerLimit *web.Limits `json:"-"` //Web服务连接限制 + StartT time.Time `json:"startT"` //启动时间 + Cache syncmap.Map `json:"-"` //缓存 } type LiveQn struct { @@ -153,16 +153,16 @@ func (t *Common) Copy() *Common { Proxy: t.Proxy, AcceptQn: syncmap.Copy(t.AcceptQn), Qn: syncmap.Copy(t.Qn), - StreamType: t.StreamType, - AllStreamType: syncmap.Copy(t.AllStreamType), - K_v: t.K_v.Copy(), - Log: t.Log, - Danmu_Main_mq: t.Danmu_Main_mq, - ReqPool: t.ReqPool, - SerF: t.SerF, - SerLimit: t.SerLimit, - StartT: t.StartT, - Cache: t.Cache.Copy(), + // StreamType: t.StreamType, + AllStreamType: syncmap.Copy(t.AllStreamType), + K_v: t.K_v.Copy(), + Log: t.Log, + Danmu_Main_mq: t.Danmu_Main_mq, + ReqPool: t.ReqPool, + SerF: t.SerF, + SerLimit: t.SerLimit, + StartT: t.StartT, + Cache: t.Cache.Copy(), } return &c @@ -432,9 +432,7 @@ func (t *Common) Init() *Common { // 配置直播流类型 if val, exist := t.K_v.Load("直播流类型"); exist { - if st, ok := t.AllStreamType[val.(string)]; ok { - t.StreamType = st - } else { + if _, ok := t.AllStreamType[val.(string)]; !ok { panic("未找到设定类型" + val.(string)) } } diff --git a/F/api.go b/F/api.go index 88afce9..6daec9c 100644 --- a/F/api.go +++ b/F/api.go @@ -326,7 +326,7 @@ func (t *GetFunc) Html() (missKey []string) { if !t.Liveing { t.Live_qn = 0 t.AcceptQn = t.Qn - clear(t.Live) + t.Live = t.Live[:0] return } @@ -366,83 +366,35 @@ func (t *GetFunc) Html() (missKey []string) { // 配置直播流 func (t *GetFunc) configStreamType(sts []J.StreamType) { - var chosenType c.StreamType + var ( + wantTypes []c.StreamType + chosen int = -1 + ) defer func() { apilog := apilog.Base_add(`configStreamType`) + if chosen == -1 { + apilog.L(`E: `, `未能选择到流`) + return + } if _, ok := t.Qn[t.Live_qn]; !ok { apilog.L(`W: `, `未知的清晰度`, t.Live_qn) } - apilog.L(`T: `, fmt.Sprintf("使用直播流 %s %s %s", t.Qn[t.Live_qn], chosenType.Format_name, chosenType.Codec_name)) + apilog.L(`T: `, fmt.Sprintf("使用 %d 条直播流 %s %s %s", len(t.Live), t.Qn[t.Live_qn], wantTypes[chosen].Format_name, wantTypes[chosen].Codec_name)) }() + // 期望类型 if v, ok := t.Common.K_v.LoadV(`直播流类型`).(string); ok { if st, ok := t.AllStreamType[v]; ok { - t.StreamType = st - } - } - - // 查找配置类型是否存在 - for _, v := range sts { - if v.ProtocolName != t.StreamType.Protocol_name { - continue - } - - for _, v := range v.Format { - if v.FormatName != t.StreamType.Format_name { - continue - } - - for _, v := range v.Codec { - if v.CodecName != t.StreamType.Codec_name { - continue - } - - chosenType = t.StreamType - //当前直播流质量 - t.Live_qn = v.CurrentQn - if t.Live_want_qn == 0 { - t.Live_want_qn = v.CurrentQn - } - //允许的清晰度 - { - var tmp = make(map[int]string) - for _, v := range v.AcceptQn { - if s, ok := t.Qn[v]; ok { - tmp[v] = s - } - } - t.AcceptQn = tmp - } - //直播流链接 - clear(t.Live) - for _, v1 := range v.URLInfo { - item := c.LiveQn{ - Url: v1.Host + v.BaseURL + v1.Extra, - } - - if query, e := url.ParseQuery(v1.Extra); e == nil { - if expires, e := strconv.Atoi(query.Get("expires")); e == nil { - item.Expires = expires - } - } - - t.Live = append(t.Live, item) - } - - return - } + wantTypes = append(wantTypes, st) } } + // 默认类型 + wantTypes = append(wantTypes, t.AllStreamType[`fmp4`], t.AllStreamType[`flv`]) - apilog.Base_add(`configStreamType`).L(`W: `, "未找到配置的直播流类型,使用默认flv、fmp4") - - // 默认使用fmp4、flv - for _, streamType := range []c.StreamType{ - t.AllStreamType[`fmp4`], - t.AllStreamType[`flv`], - } { + t.Live = t.Live[:0] + for k, streamType := range wantTypes { for _, v := range sts { if v.ProtocolName != streamType.Protocol_name { continue @@ -458,7 +410,7 @@ func (t *GetFunc) configStreamType(sts []J.StreamType) { continue } - chosenType = streamType + chosen = k //当前直播流质量 t.Live_qn = v.CurrentQn if t.Live_want_qn == 0 { @@ -475,7 +427,6 @@ func (t *GetFunc) configStreamType(sts []J.StreamType) { t.AcceptQn = tmp } //直播流链接 - clear(t.Live) for _, v1 := range v.URLInfo { item := c.LiveQn{ Url: v1.Host + v.BaseURL + v1.Extra, @@ -489,6 +440,9 @@ func (t *GetFunc) configStreamType(sts []J.StreamType) { t.Live = append(t.Live, item) } + + // 已选定并设置好参数 退出 + return } } } @@ -730,7 +684,7 @@ func (t *GetFunc) getRoomPlayInfo() (missKey []string) { if !t.Liveing { t.Live_qn = 0 t.AcceptQn = t.Qn - clear(t.Live) + t.Live = t.Live[:0] return } @@ -825,7 +779,7 @@ func (t *GetFunc) getRoomPlayInfoByQn() (missKey []string) { if !t.Liveing { t.Live_qn = 0 t.AcceptQn = t.Qn - clear(t.Live) + t.Live = t.Live[:0] return } @@ -1544,7 +1498,7 @@ func (c *GetFunc) Get_other_cookie() { return } - if e := save_cookie(r.Response.Cookies()); e != nil { + if e := save_cookie(r.Response.Cookies()); e != nil && !errors.Is(e, ErrNoCookiesSave) { apilog.L(`E: `, e) } } @@ -2261,9 +2215,11 @@ func (t *GetFunc) Silver_2_coin() (missKey []string) { return } +var ErrNoCookiesSave = errors.New("ErrNoCookiesSave") + func save_cookie(Cookies []*http.Cookie) error { if len(Cookies) == 0 { - return errors.New("no cookie") + return ErrNoCookiesSave } for k, v := range reqf.Cookies_List_2_Map(Cookies) { diff --git a/Reply/flvDecode.go b/Reply/flvDecode.go index 9d51843..4d6ae80 100644 --- a/Reply/flvDecode.go +++ b/Reply/flvDecode.go @@ -54,7 +54,7 @@ func Search_stream_tag(buf []byte, keyframe *slice.Buf[byte]) (front_buf []byte, // if sign != 0x00 { // fmt.Printf("front_buf error:%x\n", sign) // } - clear(front_buf) + front_buf = front_buf[:0] } if bufl := keyframe.Size(); confirm_num != bufl { _ = keyframe.RemoveBack(bufl - confirm_num) diff --git a/Reply/fmp4Decode.go b/Reply/fmp4Decode.go index f5f0f2f..c66cc74 100644 --- a/Reply/fmp4Decode.go +++ b/Reply/fmp4Decode.go @@ -428,7 +428,7 @@ func decode(buf []byte, reSyncboxName string) (m []ie, err error) { err = E if reSyncI := bytes.Index(buf[cu:], []byte(reSyncboxName)); reSyncI != -1 { cu += reSyncI - 4 - clear(m) + m = m[:0] continue } err = errors.New(E.Error() + " > 未能reSync") diff --git a/Reply/stream.go b/Reply/stream.go index fd06887..de86003 100644 --- a/Reply/stream.go +++ b/Reply/stream.go @@ -207,7 +207,7 @@ func (t *M4SStream) fetchCheckStream() bool { defer t.reqPool.Put(r) for _, v := range t.common.Live { if nomcdn && strings.Contains(v.Url, ".mcdn.") { - t.common.Live = t.common.Live[1:] + v.Disable(time.Now().Add(time.Hour * 100)) continue } @@ -231,16 +231,18 @@ func (t *M4SStream) fetchCheckStream() bool { Timeout: 5 * 1000, JustResponseCode: true, }); e != nil { - t.log.L(`W: `, e) + t.log.L(`W: `, F.ParseHost(v.Url), e) + v.DisableAuto() + continue } if r.Response == nil { - t.log.L(`W: `, `live响应错误`) - t.common.Live = t.common.Live[1:] + t.log.L(`W: `, `live响应错误`, F.ParseHost(v.Url)) + v.DisableAuto() continue } else if r.Response.StatusCode&200 != 200 { - t.log.L(`W: `, `live响应错误`, r.Response.Status) - t.common.Live = t.common.Live[1:] + t.log.L(`W: `, `live响应错误`, F.ParseHost(v.Url), r.Response.Status) + v.DisableAuto() continue } @@ -248,7 +250,7 @@ func (t *M4SStream) fetchCheckStream() bool { t.log.L(`I: `, `使用流服务器`, F.ParseHost(v.Url)) } - return len(t.common.Live) != 0 + return t.common.ValidLive() != nil } func (t *M4SStream) fetchParseM3U8(fmp4ListUpdateTo float64) (m4s_links []*m4s_link_item, m3u8_addon []byte, e error) { @@ -455,7 +457,7 @@ func (t *M4SStream) fetchParseM3U8(fmp4ListUpdateTo float64) (m4s_links []*m4s_l if index := bytes.Index(m3u8_addon, []byte(m4s_link.Base)); index != -1 { index += len([]byte(m4s_link.Base)) if index == len(m3u8_addon) { - clear(m3u8_addon) + m3u8_addon = m3u8_addon[:0] } else { m3u8_addon = m3u8_addon[index+1:] } @@ -580,7 +582,7 @@ func (t *M4SStream) saveStream() (e error) { t.frameCount = 0 if s, ok := t.common.K_v.LoadV("直播Web服务路径").(string); ok && s != "" { - t.log.L(`I: `, "Web服务地址:", t.common.Stream_url.String()+s) + t.log.L(`I: `, "Web服务地址", t.common.Stream_url.String()+s) } // 录制回调 @@ -803,7 +805,7 @@ func (t *M4SStream) saveStreamFlv() (e error) { buff.Reset() }() - t.log.L(`I: `, `flv下载开始`) + t.log.L(`I: `, `flv下载开始`, F.ParseHost(surl.String())) _ = r.Reqf(reqf.Rval{ Ctx: cancelC, @@ -828,11 +830,13 @@ func (t *M4SStream) saveStreamFlv() (e error) { }) if err := r.Wait(); err != nil && !errors.Is(err, io.EOF) { if reqf.IsCancel(err) { - t.log.L(`I: `, `flv下载停止`) + t.log.L(`I: `, `flv下载停止`, F.ParseHost(surl.String())) return } else if err != nil && !reqf.IsTimeout(err) { e = err - t.log.L(`E: `, `flv下载失败:`, err) + t.log.L(`E: `, `flv下载失败:`, F.ParseHost(surl.String()), err) + } else { + t.log.L(`E: `, `flv下载超时`, F.ParseHost(surl.String())) } } else if err := errCtx.Get(); err != nil && strings.HasPrefix(err.Error(), "[decoder]") { e = err