Skip to content

Commit c68db59

Browse files
authored
Test: Add blackbox for HEVC over HLS. (#3356)
1 parent 2cab98a commit c68db59

File tree

1 file changed

+95
-0
lines changed

1 file changed

+95
-0
lines changed

trunk/3rdparty/srs-bench/blackbox/hls_test.go

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
"math/rand"
2929
"os"
3030
"path"
31+
"runtime"
3132
"sync"
3233
"testing"
3334
"time"
@@ -114,3 +115,97 @@ func TestRtmpPublish_HlsPlay_Basic(t *testing.T) {
114115
}
115116
}
116117
}
118+
119+
func TestRtmpPublish_HlsPlay_HEVC_Basic(t *testing.T) {
120+
// This case is run in parallel.
121+
t.Parallel()
122+
123+
// Setup the max timeout for this case.
124+
ctx, cancel := context.WithTimeout(logger.WithContext(context.Background()), time.Duration(*srsTimeout)*time.Millisecond)
125+
defer cancel()
126+
127+
// Only enable for github actions, ignore for darwin.
128+
if runtime.GOOS == "darwin" {
129+
logger.Tf(ctx, "Depends on FFmpeg(HEVC over RTMP), only available for GitHub actions")
130+
return
131+
}
132+
133+
// Check a set of errors.
134+
var r0, r1, r2, r3, r4, r5, r6 error
135+
defer func(ctx context.Context) {
136+
if err := filterTestError(ctx.Err(), r0, r1, r2, r3, r4, r5, r6); err != nil {
137+
t.Errorf("Fail for err %+v", err)
138+
} else {
139+
logger.Tf(ctx, "test done with err %+v", err)
140+
}
141+
}(ctx)
142+
143+
var wg sync.WaitGroup
144+
defer wg.Wait()
145+
146+
// Start SRS server and wait for it to be ready.
147+
svr := NewSRSServer(func(v *srsServer) {
148+
v.envs = []string{
149+
"SRS_HTTP_SERVER_ENABLED=on",
150+
"SRS_VHOST_HLS_ENABLED=on",
151+
}
152+
})
153+
wg.Add(1)
154+
go func() {
155+
defer wg.Done()
156+
r0 = svr.Run(ctx, cancel)
157+
}()
158+
159+
// Start FFmpeg to publish stream.
160+
streamID := fmt.Sprintf("stream-%v-%v", os.Getpid(), rand.Int())
161+
streamURL := fmt.Sprintf("rtmp://localhost:%v/live/%v", svr.RTMPPort(), streamID)
162+
ffmpeg := NewFFmpeg(func(v *ffmpegClient) {
163+
v.args = []string{
164+
"-stream_loop", "-1", "-re", "-i", *srsPublishAvatar, "-acodec", "copy", "-vcodec", "libx265", "-f", "flv", streamURL,
165+
}
166+
})
167+
wg.Add(1)
168+
go func() {
169+
defer wg.Done()
170+
<-svr.ReadyCtx().Done()
171+
r1 = ffmpeg.Run(ctx, cancel)
172+
}()
173+
174+
// Start FFprobe to detect and verify stream.
175+
duration := time.Duration(*srsFFprobeDuration) * time.Millisecond
176+
ffprobe := NewFFprobe(func(v *ffprobeClient) {
177+
v.dvrFile = path.Join(svr.WorkDir(), "objs", fmt.Sprintf("srs-ffprobe-%v.ts", streamID))
178+
v.streamURL = fmt.Sprintf("http://localhost:%v/live/%v.m3u8", svr.HTTPPort(), streamID)
179+
v.duration, v.timeout = duration, time.Duration(*srsFFprobeTimeout)*time.Millisecond
180+
})
181+
wg.Add(1)
182+
go func() {
183+
defer wg.Done()
184+
<-svr.ReadyCtx().Done()
185+
r2 = ffprobe.Run(ctx, cancel)
186+
}()
187+
188+
// Fast quit for probe done.
189+
select {
190+
case <-ctx.Done():
191+
case <-ffprobe.ProbeDoneCtx().Done():
192+
defer cancel()
193+
194+
str, m := ffprobe.Result()
195+
if len(m.Streams) != 2 {
196+
r3 = errors.Errorf("invalid streams=%v, %v, %v", len(m.Streams), m.String(), str)
197+
}
198+
199+
// Note that HLS score is low, so we only check duration. Note that only check part of duration, because we
200+
// might get only some pieces of segments.
201+
if dv := m.Duration(); dv < duration/3 {
202+
r4 = errors.Errorf("short duration=%v < %v, %v, %v", dv, duration/3, m.String(), str)
203+
}
204+
205+
if v := m.Video(); v == nil {
206+
r5 = errors.Errorf("no video %v, %v", m.String(), str)
207+
} else if v.CodecName != "hevc" {
208+
r6 = errors.Errorf("invalid video codec=%v, %v, %v", v.CodecName, m.String(), str)
209+
}
210+
}
211+
}

0 commit comments

Comments
 (0)