|
|
|
@ -9,7 +9,6 @@
|
|
|
|
|
package innertest
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"bytes"
|
|
|
|
|
"fmt"
|
|
|
|
|
"io/ioutil"
|
|
|
|
|
"net/http"
|
|
|
|
@ -17,6 +16,9 @@ import (
|
|
|
|
|
"testing"
|
|
|
|
|
"time"
|
|
|
|
|
|
|
|
|
|
"github.com/q191201771/naza/pkg/nazabytes"
|
|
|
|
|
"github.com/q191201771/naza/pkg/nazalog"
|
|
|
|
|
|
|
|
|
|
"github.com/q191201771/lal/pkg/httpts"
|
|
|
|
|
"github.com/q191201771/naza/pkg/filebatch"
|
|
|
|
|
|
|
|
|
@ -53,16 +55,11 @@ import (
|
|
|
|
|
// - 加上relay pull
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
tt *testing.T
|
|
|
|
|
t *testing.T
|
|
|
|
|
|
|
|
|
|
mode int // 0 正常 1 输入只有音频 2 输入只有视频
|
|
|
|
|
confFile = "../../testdata/lalserver.conf.json"
|
|
|
|
|
rFlvFileName = "../../testdata/test.flv"
|
|
|
|
|
wRtmpPullFileName = "../../testdata/rtmppull.flv"
|
|
|
|
|
wFlvPullFileName = "../../testdata/flvpull.flv"
|
|
|
|
|
wPlaylistM3u8FileName string
|
|
|
|
|
wRecordM3u8FileName string
|
|
|
|
|
wHlsTsFilePath string
|
|
|
|
|
//wRtspPullFileName = "../../testdata/rtsppull.flv"
|
|
|
|
|
|
|
|
|
|
pushUrl string
|
|
|
|
|
httpflvPullUrl string
|
|
|
|
@ -70,9 +67,17 @@ var (
|
|
|
|
|
rtmpPullUrl string
|
|
|
|
|
rtspPullUrl string
|
|
|
|
|
|
|
|
|
|
wRtmpPullFileName string
|
|
|
|
|
wFlvPullFileName string
|
|
|
|
|
wPlaylistM3u8FileName string
|
|
|
|
|
wRecordM3u8FileName string
|
|
|
|
|
wHlsTsFilePath string
|
|
|
|
|
wTsPullFileName string
|
|
|
|
|
|
|
|
|
|
fileTagCount int
|
|
|
|
|
httpflvPullTagCount nazaatomic.Uint32
|
|
|
|
|
rtmpPullTagCount nazaatomic.Uint32
|
|
|
|
|
httptsSize nazaatomic.Uint32
|
|
|
|
|
rtspSdpCtx sdp.LogicContext
|
|
|
|
|
rtspPullAvPacketCount nazaatomic.Uint32
|
|
|
|
|
|
|
|
|
@ -99,7 +104,20 @@ func (r RtspPullObserver) OnAvPacket(pkt base.AvPacket) {
|
|
|
|
|
rtspPullAvPacketCount.Increment()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func Entry(t *testing.T) {
|
|
|
|
|
func Entry(tt *testing.T) {
|
|
|
|
|
t = tt
|
|
|
|
|
|
|
|
|
|
mode = 0
|
|
|
|
|
entry()
|
|
|
|
|
|
|
|
|
|
mode = 1
|
|
|
|
|
entry()
|
|
|
|
|
|
|
|
|
|
mode = 2
|
|
|
|
|
entry()
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func entry() {
|
|
|
|
|
if _, err := os.Lstat(confFile); err != nil {
|
|
|
|
|
Log.Warnf("lstat %s error. err=%+v", confFile, err)
|
|
|
|
|
return
|
|
|
|
@ -109,22 +127,26 @@ func Entry(t *testing.T) {
|
|
|
|
|
return
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
httpflvPullTagCount.Store(0)
|
|
|
|
|
rtmpPullTagCount.Store(0)
|
|
|
|
|
httptsSize.Store(0)
|
|
|
|
|
hls.Clock = mock.NewFakeClock()
|
|
|
|
|
hls.Clock.Set(time.Date(2022, 1, 16, 23, 24, 25, 0, time.Local))
|
|
|
|
|
hls.Clock.Set(time.Date(2022, 1, 16, 23, 24, 25, 0, time.UTC))
|
|
|
|
|
httpts.SubSessionWriteChanSize = 0
|
|
|
|
|
|
|
|
|
|
tt = t
|
|
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
|
|
|
|
|
sm := logic.NewServerManager(confFile)
|
|
|
|
|
go sm.RunLoop()
|
|
|
|
|
time.Sleep(200 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
config := sm.Config()
|
|
|
|
|
|
|
|
|
|
//Log.Init(func(option *nazalog.Option) {
|
|
|
|
|
// option.Level = nazalog.LevelLogNothing
|
|
|
|
|
//})
|
|
|
|
|
_ = os.RemoveAll(config.HlsConfig.OutPath)
|
|
|
|
|
|
|
|
|
|
go sm.RunLoop()
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
getAllHttpApi(config.HttpApiConfig.Addr)
|
|
|
|
|
|
|
|
|
|
pushUrl = fmt.Sprintf("rtmp://127.0.0.1%s/live/innertest", config.RtmpConfig.Addr)
|
|
|
|
@ -132,12 +154,32 @@ func Entry(t *testing.T) {
|
|
|
|
|
httptsPullUrl = fmt.Sprintf("http://127.0.0.1%s/live/innertest.ts", config.HttpflvConfig.HttpListenAddr)
|
|
|
|
|
rtmpPullUrl = fmt.Sprintf("rtmp://127.0.0.1%s/live/innertest", config.RtmpConfig.Addr)
|
|
|
|
|
rtspPullUrl = fmt.Sprintf("rtsp://127.0.0.1%s/live/innertest", config.RtspConfig.Addr)
|
|
|
|
|
|
|
|
|
|
wRtmpPullFileName = "../../testdata/rtmppull.flv"
|
|
|
|
|
wFlvPullFileName = "../../testdata/flvpull.flv"
|
|
|
|
|
wTsPullFileName = fmt.Sprintf("../../testdata/tspull_%d.ts", mode)
|
|
|
|
|
wPlaylistM3u8FileName = fmt.Sprintf("%sinnertest/playlist.m3u8", config.HlsConfig.OutPath)
|
|
|
|
|
wRecordM3u8FileName = fmt.Sprintf("%sinnertest/record.m3u8", config.HlsConfig.OutPath)
|
|
|
|
|
wHlsTsFilePath = fmt.Sprintf("%sinnertest/", config.HlsConfig.OutPath)
|
|
|
|
|
|
|
|
|
|
tags, err := httpflv.ReadAllTagsFromFlvFile(rFlvFileName)
|
|
|
|
|
var tags []httpflv.Tag
|
|
|
|
|
originTags, err := httpflv.ReadAllTagsFromFlvFile(rFlvFileName)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
if mode == 0 {
|
|
|
|
|
tags = originTags
|
|
|
|
|
} else if mode == 1 {
|
|
|
|
|
for _, tag := range originTags {
|
|
|
|
|
if tag.Header.Type == base.RtmpTypeIdMetadata || tag.Header.Type == base.RtmpTypeIdAudio {
|
|
|
|
|
tags = append(tags, tag)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
} else if mode == 2 {
|
|
|
|
|
for _, tag := range originTags {
|
|
|
|
|
if tag.Header.Type == base.RtmpTypeIdMetadata || tag.Header.Type == base.RtmpTypeIdVideo {
|
|
|
|
|
tags = append(tags, tag)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
fileTagCount = len(tags)
|
|
|
|
|
|
|
|
|
|
err = httpFlvWriter.Open(wFlvPullFileName)
|
|
|
|
@ -160,7 +202,7 @@ func Entry(t *testing.T) {
|
|
|
|
|
func(msg base.RtmpMsg) {
|
|
|
|
|
tag := remux.RtmpMsg2FlvTag(msg)
|
|
|
|
|
err := rtmpWriter.WriteTag(*tag)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
rtmpPullTagCount.Increment()
|
|
|
|
|
})
|
|
|
|
|
Log.Assert(nil, err)
|
|
|
|
@ -169,6 +211,7 @@ func Entry(t *testing.T) {
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
var flvErr error
|
|
|
|
|
httpflvPullSession = httpflv.NewPullSession(func(option *httpflv.PullSessionOption) {
|
|
|
|
|
option.ReadTimeoutMs = 10000
|
|
|
|
|
})
|
|
|
|
@ -178,19 +221,17 @@ func Entry(t *testing.T) {
|
|
|
|
|
httpflvPullTagCount.Increment()
|
|
|
|
|
})
|
|
|
|
|
Log.Assert(nil, err)
|
|
|
|
|
err = <-httpflvPullSession.WaitChan()
|
|
|
|
|
Log.Debug(err)
|
|
|
|
|
flvErr = <-httpflvPullSession.WaitChan()
|
|
|
|
|
Log.Debug(flvErr)
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
go func() {
|
|
|
|
|
//nazalog.Info("CHEFGREPME >")
|
|
|
|
|
b, err := httpGet(httptsPullUrl)
|
|
|
|
|
assert.Equal(t, 2216332, len(b))
|
|
|
|
|
assert.Equal(t, "03f8eac7d2c3d5d85056c410f5fcc756", nazamd5.Md5(b))
|
|
|
|
|
Log.Infof("CHEFGREPME %+v", err)
|
|
|
|
|
b, _ := getHttpts()
|
|
|
|
|
_ = ioutil.WriteFile(wTsPullFileName, b, 0666)
|
|
|
|
|
assert.Equal(t, goldenHttptsLenList[mode], len(b))
|
|
|
|
|
assert.Equal(t, goldenHttptsMd5List[mode], nazamd5.Md5(b))
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
time.Sleep(200 * time.Millisecond)
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
// TODO(chef): [test] [2021.12.25] rtsp sub测试 由于rtsp sub不支持没有pub时sub,只能sub失败后重试,所以没有验证收到的数据
|
|
|
|
|
// TODO(chef): [perf] [2021.12.25] rtmp推rtsp拉的性能。开启rtsp pull后,rtmp pull的总时长增加了
|
|
|
|
@ -210,9 +251,11 @@ func Entry(t *testing.T) {
|
|
|
|
|
}
|
|
|
|
|
}()
|
|
|
|
|
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
|
|
|
|
|
pushSession = rtmp.NewPushSession(func(option *rtmp.PushSessionOption) {
|
|
|
|
|
option.WriteBufSize = 4096
|
|
|
|
|
option.WriteChanSize = 1024
|
|
|
|
|
//option.WriteChanSize = 1024
|
|
|
|
|
})
|
|
|
|
|
err = pushSession.Push(pushUrl)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
@ -221,7 +264,7 @@ func Entry(t *testing.T) {
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
chunks := remux.FlvTag2RtmpChunks(tag)
|
|
|
|
|
//Log.Debugf("rtmp push: %d", fileTagCount.Load())
|
|
|
|
|
err = pushSession.Write(chunks)
|
|
|
|
|
err := pushSession.Write(chunks)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
}
|
|
|
|
|
err = pushSession.Flush()
|
|
|
|
@ -229,21 +272,25 @@ func Entry(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
getAllHttpApi(config.HttpApiConfig.Addr)
|
|
|
|
|
|
|
|
|
|
// 注意,先释放push,触发pub释放,从而刷新hls的结束时切片逻辑
|
|
|
|
|
pushSession.Dispose()
|
|
|
|
|
|
|
|
|
|
for {
|
|
|
|
|
if httpflvPullTagCount.Load() == uint32(fileTagCount) &&
|
|
|
|
|
rtmpPullTagCount.Load() == uint32(fileTagCount) {
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
rtmpPullTagCount.Load() == uint32(fileTagCount) &&
|
|
|
|
|
httptsSize.Load() == uint32(goldenHttptsLenList[mode]) {
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
time.Sleep(10 * time.Millisecond)
|
|
|
|
|
nazalog.Debugf("%d(%d, %d) %d(%d)",
|
|
|
|
|
fileTagCount, httpflvPullTagCount.Load(), rtmpPullTagCount.Load(), goldenHttptsLenList[mode], httptsSize.Load())
|
|
|
|
|
time.Sleep(100 * time.Millisecond)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Log.Debug("[innertest] start dispose.")
|
|
|
|
|
|
|
|
|
|
pushSession.Dispose()
|
|
|
|
|
httpflvPullSession.Dispose()
|
|
|
|
|
rtmpPullSession.Dispose()
|
|
|
|
|
//rtspPullSession.Dispose()
|
|
|
|
|
rtspPullSession.Dispose()
|
|
|
|
|
|
|
|
|
|
httpFlvWriter.Dispose()
|
|
|
|
|
rtmpWriter.Dispose()
|
|
|
|
@ -260,34 +307,28 @@ func Entry(t *testing.T) {
|
|
|
|
|
|
|
|
|
|
func compareFile() {
|
|
|
|
|
r, err := ioutil.ReadFile(rFlvFileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
Log.Debugf("%s filesize:%d", rFlvFileName, len(r))
|
|
|
|
|
|
|
|
|
|
// 检查httpflv
|
|
|
|
|
w, err := ioutil.ReadFile(wFlvPullFileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
Log.Debugf("%s filesize:%d", wFlvPullFileName, len(w))
|
|
|
|
|
res := bytes.Compare(r, w)
|
|
|
|
|
assert.Equal(tt, 0, res)
|
|
|
|
|
//err = os.Remove(wFlvPullFileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
assert.Equal(t, goldenHttpflvLenList[mode], len(w))
|
|
|
|
|
assert.Equal(t, goldenHttpflvMd5List[mode], nazamd5.Md5(w))
|
|
|
|
|
|
|
|
|
|
// 检查rtmp
|
|
|
|
|
w2, err := ioutil.ReadFile(wRtmpPullFileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
Log.Debugf("%s filesize:%d", wRtmpPullFileName, len(w2))
|
|
|
|
|
res = bytes.Compare(r, w2)
|
|
|
|
|
assert.Equal(tt, 0, res)
|
|
|
|
|
//err = os.Remove(wRtmpPullFileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
w, err = ioutil.ReadFile(wRtmpPullFileName)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
assert.Equal(t, goldenRtmpLenList[mode], len(w))
|
|
|
|
|
assert.Equal(t, goldenRtmpMd5List[mode], nazamd5.Md5(w))
|
|
|
|
|
|
|
|
|
|
// 检查hls的m3u8文件
|
|
|
|
|
playListM3u8, err := ioutil.ReadFile(wPlaylistM3u8FileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(tt, goldenPlaylistM3u8, string(playListM3u8))
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
assert.Equal(t, goldenPlaylistM3u8List[mode], string(playListM3u8))
|
|
|
|
|
recordM3u8, err := ioutil.ReadFile(wRecordM3u8FileName)
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(tt, []byte(goldenRecordM3u8), recordM3u8)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
assert.Equal(t, goldenRecordM3u8List[mode], string(recordM3u8))
|
|
|
|
|
|
|
|
|
|
// 检查hls的ts文件
|
|
|
|
|
var allContent []byte
|
|
|
|
@ -301,11 +342,11 @@ func compareFile() {
|
|
|
|
|
fileNum++
|
|
|
|
|
return nil
|
|
|
|
|
})
|
|
|
|
|
assert.Equal(tt, nil, err)
|
|
|
|
|
assert.Equal(t, nil, err)
|
|
|
|
|
allContentMd5 := nazamd5.Md5(allContent)
|
|
|
|
|
assert.Equal(tt, 8, fileNum)
|
|
|
|
|
assert.Equal(tt, 2219152, len(allContent))
|
|
|
|
|
assert.Equal(tt, "48db6251d40c271fd11b05650f074e0f", allContentMd5)
|
|
|
|
|
assert.Equal(t, goldenHlsTsNumList[mode], fileNum)
|
|
|
|
|
assert.Equal(t, goldenHlsTsLenList[mode], len(allContent))
|
|
|
|
|
assert.Equal(t, goldenHlsTsMd5List[mode], allContentMd5)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getAllHttpApi(addr string) {
|
|
|
|
@ -339,6 +380,30 @@ func getAllHttpApi(addr string) {
|
|
|
|
|
Log.Debugf("%s", string(b))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func getHttpts() ([]byte, error) {
|
|
|
|
|
resp, err := http.DefaultClient.Get(httptsPullUrl)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
defer resp.Body.Close()
|
|
|
|
|
|
|
|
|
|
var buf nazabytes.Buffer
|
|
|
|
|
buf.ReserveBytes(goldenHttptsLenList[mode])
|
|
|
|
|
for {
|
|
|
|
|
n, err := resp.Body.Read(buf.WritableBytes())
|
|
|
|
|
if n > 0 {
|
|
|
|
|
buf.Flush(n)
|
|
|
|
|
httptsSize.Add(uint32(n))
|
|
|
|
|
}
|
|
|
|
|
if err != nil {
|
|
|
|
|
return buf.Bytes(), err
|
|
|
|
|
}
|
|
|
|
|
if buf.Len() == goldenHttptsLenList[mode] {
|
|
|
|
|
return buf.Bytes(), nil
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
// TODO(chef): refactor 移入naza中
|
|
|
|
@ -363,48 +428,175 @@ func httpPost(url string, info interface{}) ([]byte, error) {
|
|
|
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------------------------------------------
|
|
|
|
|
|
|
|
|
|
var goldenPlaylistM3u8 = `#EXTM3U
|
|
|
|
|
var (
|
|
|
|
|
goldenRtmpLenList = []int{2120047, 504722, 1615715}
|
|
|
|
|
goldenRtmpMd5List = []string{
|
|
|
|
|
"7d68f0e2ab85c1992f70740479c8d3db",
|
|
|
|
|
"b889f690e07399c8c8353a3b1dba7efb",
|
|
|
|
|
"b5a9759455039761b6d4dd3ed8e97634",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goldenHttpflvLenList = []int{2120047, 504722, 1615715}
|
|
|
|
|
goldenHttpflvMd5List = []string{
|
|
|
|
|
"7d68f0e2ab85c1992f70740479c8d3db",
|
|
|
|
|
"b889f690e07399c8c8353a3b1dba7efb",
|
|
|
|
|
"b5a9759455039761b6d4dd3ed8e97634",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goldenHlsTsNumList = []int{8, 10, 8}
|
|
|
|
|
goldenHlsTsLenList = []int{2219152, 525648, 1696512}
|
|
|
|
|
goldenHlsTsMd5List = []string{
|
|
|
|
|
"48db6251d40c271fd11b05650f074e0f",
|
|
|
|
|
"2eb19ad498688dadf950b3e749985922",
|
|
|
|
|
"2d1e5c1a3ca385e0b55b2cff2f52b710",
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
goldenHttptsLenList = []int{2216332, 522264, 1693880}
|
|
|
|
|
goldenHttptsMd5List = []string{
|
|
|
|
|
"03f8eac7d2c3d5d85056c410f5fcc756",
|
|
|
|
|
"0d102b6fb7fc3134e56a07f00292e888",
|
|
|
|
|
"651a2b5c93370738d81995f8fd49af4d",
|
|
|
|
|
}
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var goldenPlaylistM3u8List = []string{
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-ALLOW-CACHE:NO
|
|
|
|
|
#EXT-X-TARGETDURATION:5
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:2
|
|
|
|
|
|
|
|
|
|
#EXTINF:3.333,
|
|
|
|
|
innertest-1642346665000-2.ts
|
|
|
|
|
innertest-1642375465000-2.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-3.ts
|
|
|
|
|
innertest-1642375465000-3.ts
|
|
|
|
|
#EXTINF:4.867,
|
|
|
|
|
innertest-1642346665000-4.ts
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.133,
|
|
|
|
|
innertest-1642346665000-5.ts
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-6.ts
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:2.621,
|
|
|
|
|
innertest-1642346665000-7.ts
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`,
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-ALLOW-CACHE:NO
|
|
|
|
|
#EXT-X-TARGETDURATION:3
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:4
|
|
|
|
|
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:3.089,
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-8.ts
|
|
|
|
|
#EXTINF:2.113,
|
|
|
|
|
innertest-1642375465000-9.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`
|
|
|
|
|
`,
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-ALLOW-CACHE:NO
|
|
|
|
|
#EXT-X-TARGETDURATION:5
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:2
|
|
|
|
|
|
|
|
|
|
var goldenRecordM3u8 = `#EXTM3U
|
|
|
|
|
#EXTINF:3.333,
|
|
|
|
|
innertest-1642375465000-2.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-3.ts
|
|
|
|
|
#EXTINF:4.867,
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.133,
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:2.600,
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var goldenRecordM3u8List = []string{
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-TARGETDURATION:5
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:0
|
|
|
|
|
|
|
|
|
|
#EXT-X-DISCONTINUITY
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-0.ts
|
|
|
|
|
innertest-1642375465000-0.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-1.ts
|
|
|
|
|
innertest-1642375465000-1.ts
|
|
|
|
|
#EXTINF:3.333,
|
|
|
|
|
innertest-1642346665000-2.ts
|
|
|
|
|
innertest-1642375465000-2.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-3.ts
|
|
|
|
|
innertest-1642375465000-3.ts
|
|
|
|
|
#EXTINF:4.867,
|
|
|
|
|
innertest-1642346665000-4.ts
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.133,
|
|
|
|
|
innertest-1642346665000-5.ts
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642346665000-6.ts
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:2.621,
|
|
|
|
|
innertest-1642346665000-7.ts
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`
|
|
|
|
|
`,
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-TARGETDURATION:3
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:0
|
|
|
|
|
|
|
|
|
|
#EXT-X-DISCONTINUITY
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-0.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-1.ts
|
|
|
|
|
#EXTINF:3.089,
|
|
|
|
|
innertest-1642375465000-2.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-3.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:3.089,
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXTINF:3.088,
|
|
|
|
|
innertest-1642375465000-8.ts
|
|
|
|
|
#EXTINF:2.113,
|
|
|
|
|
innertest-1642375465000-9.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`,
|
|
|
|
|
`#EXTM3U
|
|
|
|
|
#EXT-X-VERSION:3
|
|
|
|
|
#EXT-X-TARGETDURATION:5
|
|
|
|
|
#EXT-X-MEDIA-SEQUENCE:0
|
|
|
|
|
|
|
|
|
|
#EXT-X-DISCONTINUITY
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-0.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-1.ts
|
|
|
|
|
#EXTINF:3.333,
|
|
|
|
|
innertest-1642375465000-2.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-3.ts
|
|
|
|
|
#EXTINF:4.867,
|
|
|
|
|
innertest-1642375465000-4.ts
|
|
|
|
|
#EXTINF:3.133,
|
|
|
|
|
innertest-1642375465000-5.ts
|
|
|
|
|
#EXTINF:4.000,
|
|
|
|
|
innertest-1642375465000-6.ts
|
|
|
|
|
#EXTINF:2.600,
|
|
|
|
|
innertest-1642375465000-7.ts
|
|
|
|
|
#EXT-X-ENDLIST
|
|
|
|
|
`,
|
|
|
|
|
}
|
|
|
|
|