mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 23:26:54 +08:00
344 lines
8.2 KiB
Go
344 lines
8.2 KiB
Go
//go:build enable_e2e_tests
|
|
|
|
package teste2e
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"strconv"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
type container struct {
|
|
name string
|
|
}
|
|
|
|
func newContainer(image string, name string, args []string) (*container, error) {
|
|
c := &container{
|
|
name: name,
|
|
}
|
|
|
|
exec.Command("docker", "kill", "gortsplib-test-"+name).Run()
|
|
exec.Command("docker", "wait", "gortsplib-test-"+name).Run()
|
|
|
|
cmd := []string{
|
|
"docker", "run",
|
|
"--network=host",
|
|
"--name=gortsplib-test-" + name,
|
|
"gortsplib-test-" + image,
|
|
}
|
|
cmd = append(cmd, args...)
|
|
ecmd := exec.Command(cmd[0], cmd[1:]...)
|
|
ecmd.Stdout = nil
|
|
ecmd.Stderr = os.Stderr
|
|
|
|
err := ecmd.Start()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
return c, nil
|
|
}
|
|
|
|
func (c *container) close() {
|
|
exec.Command("docker", "kill", "gortsplib-test-"+c.name).Run()
|
|
exec.Command("docker", "wait", "gortsplib-test-"+c.name).Run()
|
|
exec.Command("docker", "rm", "gortsplib-test-"+c.name).Run()
|
|
}
|
|
|
|
func (c *container) wait() int {
|
|
exec.Command("docker", "wait", "gortsplib-test-"+c.name).Run()
|
|
out, _ := exec.Command("docker", "inspect", "gortsplib-test-"+c.name,
|
|
"--format={{.State.ExitCode}}").Output()
|
|
code, _ := strconv.ParseInt(string(out[:len(out)-1]), 10, 32)
|
|
return int(code)
|
|
}
|
|
|
|
func buildImage(image string) error {
|
|
ecmd := exec.Command("docker", "build", filepath.Join("images", image),
|
|
"-t", "gortsplib-test-"+image)
|
|
ecmd.Stdout = nil
|
|
ecmd.Stderr = os.Stderr
|
|
return ecmd.Run()
|
|
}
|
|
|
|
func TestServerVsExternal(t *testing.T) {
|
|
files, err := os.ReadDir("images")
|
|
require.NoError(t, err)
|
|
|
|
var wg sync.WaitGroup
|
|
|
|
for _, file := range files {
|
|
cfile := file
|
|
wg.Add(1)
|
|
go func() {
|
|
err := buildImage(cfile.Name())
|
|
require.NoError(t, err)
|
|
wg.Done()
|
|
}()
|
|
}
|
|
|
|
wg.Wait()
|
|
|
|
for _, ca := range []struct {
|
|
publisherSoft string
|
|
publisherScheme string
|
|
publisherProto string
|
|
publisherSecure string
|
|
readerSoft string
|
|
readerScheme string
|
|
readerProto string
|
|
readerSecure string
|
|
}{
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "udp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsp",
|
|
readerProto: "udp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "gstreamer",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "udp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "gstreamer",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsp",
|
|
readerProto: "udp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "multicast",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsp",
|
|
readerProto: "multicast",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsp",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "gstreamer",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "gstreamer",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsp",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "udp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsp",
|
|
publisherProto: "udp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsp",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsps",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsps",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "ffmpeg",
|
|
publisherScheme: "rtsps",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "gstreamer",
|
|
readerScheme: "rtsps",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
{
|
|
publisherSoft: "gstreamer",
|
|
publisherScheme: "rtsps",
|
|
publisherProto: "tcp",
|
|
publisherSecure: "unsecure",
|
|
readerSoft: "ffmpeg",
|
|
readerScheme: "rtsps",
|
|
readerProto: "tcp",
|
|
readerSecure: "unsecure",
|
|
},
|
|
} {
|
|
t.Run(ca.publisherSoft+"_"+ca.publisherScheme+"_"+ca.publisherProto+"_"+ca.publisherSecure+"_"+
|
|
ca.readerSoft+"_"+ca.readerScheme+"_"+ca.readerProto+"_"+ca.readerSecure, func(t *testing.T) {
|
|
ss := &sampleServer{}
|
|
|
|
if ca.publisherScheme == "rtsps" {
|
|
cert, err := tls.X509KeyPair(serverCert, serverKey)
|
|
require.NoError(t, err)
|
|
ss.tlsConfig = &tls.Config{Certificates: []tls.Certificate{cert}}
|
|
}
|
|
|
|
err := ss.initialize()
|
|
require.NoError(t, err)
|
|
defer ss.close()
|
|
|
|
switch ca.publisherSoft {
|
|
case "ffmpeg":
|
|
cnt1, err := newContainer("ffmpeg", "publish", []string{
|
|
"-re",
|
|
"-stream_loop", "-1",
|
|
"-i", "emptyvideo.mkv",
|
|
"-c", "copy",
|
|
"-f", "rtsp",
|
|
"-rtsp_transport", ca.publisherProto,
|
|
ca.publisherScheme + "://localhost:8554/test/stream?key=val",
|
|
})
|
|
require.NoError(t, err)
|
|
defer cnt1.close()
|
|
|
|
case "gstreamer":
|
|
var profile string
|
|
if ca.publisherSecure == "secure" {
|
|
profile = "GST_RTSP_PROFILE_SAVP"
|
|
} else {
|
|
profile = "GST_RTSP_PROFILE_AVP"
|
|
}
|
|
|
|
cnt1, err := newContainer("gstreamer", "publish", []string{
|
|
"filesrc location=emptyvideo.mkv ! matroskademux ! video/x-h264 ! rtspclientsink " +
|
|
"location=" + ca.publisherScheme + "://127.0.0.1:8554/test/stream?key=val" +
|
|
" protocols=" + ca.publisherProto +
|
|
" profiles=" + profile +
|
|
" tls-validation-flags=0 latency=0 timeout=0 rtx-time=0",
|
|
})
|
|
require.NoError(t, err)
|
|
defer cnt1.close()
|
|
|
|
time.Sleep(1 * time.Second)
|
|
}
|
|
|
|
time.Sleep(1 * time.Second)
|
|
|
|
switch ca.readerSoft {
|
|
case "ffmpeg":
|
|
var proto string
|
|
if ca.readerProto == "multicast" {
|
|
proto = "udp_multicast"
|
|
} else {
|
|
proto = ca.readerProto
|
|
}
|
|
|
|
cnt2, err := newContainer("ffmpeg", "read", []string{
|
|
"-rtsp_transport", proto,
|
|
"-i", ca.readerScheme + "://localhost:8554/test/stream?key=val",
|
|
"-vframes", "1",
|
|
"-f", "image2",
|
|
"-y", "/dev/null",
|
|
})
|
|
require.NoError(t, err)
|
|
defer cnt2.close()
|
|
require.Equal(t, 0, cnt2.wait())
|
|
|
|
case "gstreamer":
|
|
var proto string
|
|
if ca.readerProto == "multicast" {
|
|
proto = "udp-mcast"
|
|
} else {
|
|
proto = ca.readerProto
|
|
}
|
|
|
|
cnt2, err := newContainer("gstreamer", "read", []string{
|
|
"rtspsrc location=" + ca.readerScheme + "://127.0.0.1:8554/test/stream?key=val" +
|
|
" protocols=" + proto +
|
|
" tls-validation-flags=0 latency=0 " +
|
|
"! application/x-rtp,media=video ! decodebin ! video/x-raw ! fakesink num-buffers=1",
|
|
})
|
|
require.NoError(t, err)
|
|
defer cnt2.close()
|
|
require.Equal(t, 0, cnt2.wait())
|
|
}
|
|
})
|
|
}
|
|
}
|