// Copyright 2020, Chef. All rights reserved. // https://github.com/q191201771/lal // // Use of this source code is governed by a MIT-style license // that can be found in the License file. // // Author: Chef (191201771@qq.com) package main import ( "flag" "strconv" "strings" "sync" "time" "github.com/q191201771/lal/pkg/base" "github.com/q191201771/naza/pkg/lru" "github.com/q191201771/naza/pkg/nazahttp" "github.com/q191201771/naza/pkg/nazalog" ) // 分析诊断HLS的时间戳。注意,这个程序还没有完成。 // // TODO chef: 有的代码考虑弄到pkg/hls中 type M3u8PullSession struct { } type frag struct { extinf float64 filename string } func parseM3u8(content string) (ret []frag) { var err error lines := strings.Split(content, "\n") var f frag for _, line := range lines { if strings.HasPrefix(line, "#EXTINF:") { line = strings.TrimPrefix(line, "#EXTINF:") line = strings.TrimSuffix(line, ",") f.extinf, err = strconv.ParseFloat(line, 64) nazalog.Assert(nil, err) } if strings.Index(line, ".ts") != -1 { f.filename = line ret = append(ret, f) } } return } func getTsUrl(m3u8Url string, tsFilename string) string { index := strings.LastIndex(m3u8Url, "/") nazalog.Assert(true, index != -1) path := m3u8Url[:index+1] return path + tsFilename } func main() { _ = nazalog.Init(func(option *nazalog.Option) { option.AssertBehavior = nazalog.AssertFatal }) defer nazalog.Sync() m3u8Url := parseFlag() nazalog.Infof("m3u8 url=%s", m3u8Url) cache := lru.New(1024) var m sync.Mutex var frags []frag go func() { for { content, err := nazahttp.GetHttpFile(m3u8Url, 3000) if err != nil { nazalog.Error(err) return } //nazalog.Debugf("\n-----m3u8-----\n%s", string(content)) currFrags := parseM3u8(string(content)) //nazalog.Debugf("%+v", currFrags) m.Lock() for _, f := range currFrags { if _, exist := cache.Get(f.filename); exist { continue } cache.Put(f.filename, nil) nazalog.Infof("> new frag. filename=%s", f.filename) frags = append(frags, f) } m.Unlock() time.Sleep(100 * time.Millisecond) } }() for { m.Lock() currFrags := frags frags = nil m.Unlock() for _, f := range currFrags { nazalog.Infof("< new frag. filename=%s", f.filename) tsUrl := getTsUrl(m3u8Url, f.filename) nazalog.Debug(tsUrl) content, err := nazahttp.GetHttpFile(tsUrl, 3000) nazalog.Assert(nil, err) nazalog.Debugf("TS len=%d", len(content)) } time.Sleep(100 * time.Millisecond) } } func parseFlag() string { url := flag.String("i", "", "specify m3u8 url") flag.Parse() if *url == "" { flag.Usage() base.OsExitAndWaitPressIfWindows(1) } return *url }