Url string
ReUpTime time.Time
disableCount int
- Expires int //流到期时间
+ Expires time.Time //流到期时间
}
func (t *LiveQn) SetUrl(url string) {
}
// 自动停用机制
-func (t *LiveQn) DisableAuto() {
+func (t *LiveQn) DisableAuto() (hadDisable bool) {
+ if !t.Valid() {
+ return true
+ }
if time.Now().After(t.ReUpTime.Add(time.Minute).Add(time.Second * time.Duration(10*t.disableCount))) {
t.disableCount = 0
}
t.disableCount += 1
t.ReUpTime = time.Now().Add(time.Minute).Add(time.Second * time.Duration(10*t.disableCount))
+ return
}
func (t *LiveQn) Disable(reUpTime time.Time) {
}
// 自动停用机制
-func (t *Common) DisableLiveAuto(host string) {
+func (t *Common) DisableLiveAuto(host string) (hadDisable bool) {
for i := 0; i < len(t.Live); i++ {
if liveUrl, e := url.Parse(t.Live[i].Url); e == nil {
if host == liveUrl.Host {
- t.Live[i].DisableAuto()
- break
+ return t.Live[i].DisableAuto()
}
}
}
+ return
}
func (t *Common) DisableLive(host string, reUpTime time.Time) {
}
}
+func (t *Common) ValidNum() (num int) {
+ for i := 0; i < len(t.Live); i++ {
+ if time.Now().After(t.Live[i].ReUpTime) {
+ num += 1
+ }
+ }
+ return
+}
+
func (t *Common) ValidLive() *LiveQn {
for i := 0; i < len(t.Live); i++ {
if time.Now().Before(t.Live[i].ReUpTime) {
// 默认类型
wantTypes = append(wantTypes, t.AllStreamType[`fmp4`], t.AllStreamType[`flv`])
- t.Live = t.Live[:0]
+ // t.Live = t.Live[:0]
+ for i := 0; i < len(t.Live); i++ {
+ if time.Now().Add(time.Minute).Before(t.Live[i].ReUpTime) {
+ t.Live = append(t.Live[:i], t.Live[i+1:]...)
+ }
+ }
for k, streamType := range wantTypes {
for _, v := range sts {
if query, e := url.ParseQuery(v1.Extra); e == nil {
if expires, e := strconv.Atoi(query.Get("expires")); e == nil {
- item.Expires = expires
+ item.Expires = time.Now().Add(time.Duration(expires * int(time.Second)))
}
}
}
func (t *M4SStream) fetchParseM3U8(lastM4s *m4s_link_item, fmp4ListUpdateTo float64) (m4s_links []*m4s_link_item, e error) {
- if t.common.ValidLive() == nil {
- e = errors.New("全部流服务器发生故障")
- return
+ {
+ n := t.common.ValidNum()
+ if d, ok := t.common.K_v.LoadV("fmp4获取更多服务器").(bool); ok && d && n <= 1 {
+ t.log.L("I: ", "获取更多服务器...")
+ if !t.fetchCheckStream() {
+ e = errors.New("全部流服务器发生故障")
+ return
+ }
+ } else if n == 0 {
+ e = errors.New("全部流服务器发生故障")
+ return
+ }
}
// 开始请求
}
dCount += 1
- done := downloadLimit.Block()
-
// 故障转移
if download_seq[i].status == 3 {
if linkUrl, e := url.Parse(download_seq[i].Url); e == nil {
oldHost := linkUrl.Host
// 将此切片服务器设置停用
- t.common.DisableLiveAuto(oldHost)
+ hadDisable := t.common.DisableLiveAuto(oldHost)
// 从其他服务器获取此切片
if vl := t.common.ValidLive(); vl == nil {
return errors.New(`全部流服务器故障`)
} else {
linkUrl.Host = vl.Host()
- t.log.L(`W: `, `切片下载失败,故障转移`, oldHost, ` -> `, linkUrl.Host)
+ if !hadDisable {
+ t.log.L(`W: `, `切片下载失败,故障转移`, oldHost, ` -> `, linkUrl.Host)
+ }
}
download_seq[i].Url = linkUrl.String()
}
}
+ done := downloadLimit.Block()
go func(link *m4s_link_item) {
defer done()
"flv断流超时s": 5,
"flv断流续接": true,
"fmp4切片下载超时s": 3,
+ "fmp4获取更多服务器": true,
"fmp4列表更新超时s": 7,
"fmp4音视频时间戳容差s-help": "默认0.1,小于默认无效,调大可以允许较差的流,但可能会音画不同步",
"fmp4音视频时间戳容差s": 0.2,