mirror of
https://github.com/aler9/rtsp-simple-server
synced 2025-09-27 03:56:15 +08:00
139 lines
3.4 KiB
Go
139 lines
3.4 KiB
Go
package hls
|
|
|
|
import (
|
|
"context"
|
|
"net"
|
|
"net/http"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/bluenviron/gohlslib/v2"
|
|
"github.com/bluenviron/gortsplib/v5/pkg/description"
|
|
"github.com/bluenviron/gortsplib/v5/pkg/format"
|
|
"github.com/bluenviron/mediacommon/v2/pkg/formats/mpegts"
|
|
"github.com/bluenviron/mediamtx/internal/stream"
|
|
"github.com/bluenviron/mediamtx/internal/test"
|
|
"github.com/bluenviron/mediamtx/internal/unit"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
func TestToStreamNoSupportedCodecs(t *testing.T) {
|
|
_, err := ToStream(nil, []*gohlslib.Track{}, nil)
|
|
require.Equal(t, ErrNoSupportedCodecs, err)
|
|
}
|
|
|
|
// this is impossible to test since currently we support all gohlslib.Tracks.
|
|
// func TestToStreamSkipUnsupportedTracks(t *testing.T)
|
|
|
|
func TestToStream(t *testing.T) {
|
|
track1 := &mpegts.Track{
|
|
Codec: &mpegts.CodecH264{},
|
|
}
|
|
|
|
s := &http.Server{
|
|
Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
switch {
|
|
case r.Method == http.MethodGet && r.URL.Path == "/stream.m3u8":
|
|
w.Header().Set("Content-Type", `application/vnd.apple.mpegurl`)
|
|
w.Write([]byte("#EXTM3U\n" +
|
|
"#EXT-X-VERSION:3\n" +
|
|
"#EXT-X-ALLOW-CACHE:NO\n" +
|
|
"#EXT-X-TARGETDURATION:2\n" +
|
|
"#EXT-X-MEDIA-SEQUENCE:0\n" +
|
|
"#EXT-X-PROGRAM-DATE-TIME:2018-05-20T08:17:15Z\n" +
|
|
"#EXTINF:2,\n" +
|
|
"segment1.ts\n" +
|
|
"#EXTINF:2,\n" +
|
|
"segment2.ts\n" +
|
|
"#EXTINF:2,\n" +
|
|
"segment2.ts\n" +
|
|
"#EXT-X-ENDLIST\n"))
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/segment1.ts":
|
|
w.Header().Set("Content-Type", `video/MP2T`)
|
|
|
|
w := &mpegts.Writer{W: w, Tracks: []*mpegts.Track{track1}}
|
|
err := w.Initialize()
|
|
require.NoError(t, err)
|
|
|
|
err = w.WriteH264(track1, 2*90000, 2*90000, [][]byte{
|
|
{7, 1, 2, 3}, // SPS
|
|
{8}, // PPS
|
|
})
|
|
require.NoError(t, err)
|
|
|
|
case r.Method == http.MethodGet && r.URL.Path == "/segment2.ts":
|
|
w.Header().Set("Content-Type", `video/MP2T`)
|
|
|
|
w := &mpegts.Writer{W: w, Tracks: []*mpegts.Track{track1}}
|
|
err := w.Initialize()
|
|
require.NoError(t, err)
|
|
|
|
err = w.WriteH264(track1, 2*90000, 2*90000, [][]byte{
|
|
{5, 1},
|
|
})
|
|
require.NoError(t, err)
|
|
}
|
|
}),
|
|
}
|
|
|
|
ln, err := net.Listen("tcp", "localhost:5781")
|
|
require.NoError(t, err)
|
|
|
|
go s.Serve(ln)
|
|
defer s.Shutdown(context.Background())
|
|
|
|
var strm *stream.Stream
|
|
done := make(chan struct{})
|
|
|
|
reader := test.NilLogger
|
|
|
|
var c *gohlslib.Client
|
|
c = &gohlslib.Client{
|
|
URI: "http://localhost:5781/stream.m3u8",
|
|
OnTracks: func(tracks []*gohlslib.Track) error {
|
|
medias, err2 := ToStream(c, tracks, &strm)
|
|
require.NoError(t, err2)
|
|
require.Equal(t, []*description.Media{{
|
|
Type: description.MediaTypeVideo,
|
|
Formats: []format.Format{&format.H264{
|
|
PayloadTyp: 96,
|
|
PacketizationMode: 1,
|
|
}},
|
|
}}, medias)
|
|
|
|
strm = &stream.Stream{
|
|
WriteQueueSize: 512,
|
|
RTPMaxPayloadSize: 1450,
|
|
Desc: &description.Session{Medias: medias},
|
|
GenerateRTPPackets: true,
|
|
Parent: test.NilLogger,
|
|
}
|
|
err2 = strm.Initialize()
|
|
require.NoError(t, err2)
|
|
|
|
strm.AddReader(
|
|
reader,
|
|
medias[0],
|
|
medias[0].Formats[0],
|
|
func(u unit.Unit) error {
|
|
require.Equal(t, time.Date(2018, 0o5, 20, 8, 17, 15, 0, time.UTC), u.GetNTP())
|
|
close(done)
|
|
return nil
|
|
})
|
|
|
|
strm.StartReader(reader)
|
|
|
|
return nil
|
|
},
|
|
}
|
|
err = c.Start()
|
|
require.NoError(t, err)
|
|
defer c.Close()
|
|
|
|
<-done
|
|
|
|
strm.RemoveReader(reader)
|
|
strm.Close()
|
|
}
|