mediamtx/main_test.go

835 lines
20 KiB
Go
Raw Normal View History

2020-05-10 19:32:40 +00:00
package main
import (
"io/ioutil"
2020-06-08 19:36:42 +00:00
"net"
2020-05-10 19:32:40 +00:00
"os"
"os/exec"
"path/filepath"
2020-10-18 22:08:44 +00:00
"regexp"
2020-07-10 10:22:30 +00:00
"strconv"
2020-05-10 19:32:40 +00:00
"testing"
"time"
"github.com/aler9/gortsplib"
2020-05-10 19:32:40 +00:00
"github.com/stretchr/testify/require"
2020-10-13 22:50:08 +00:00
2020-11-01 21:56:56 +00:00
"github.com/aler9/rtsp-simple-server/internal/conf"
2020-05-10 19:32:40 +00:00
)
2020-12-05 19:42:59 +00:00
var ownDockerIP = func() string {
2020-06-08 19:36:42 +00:00
out, err := exec.Command("docker", "network", "inspect", "bridge",
"-f", "{{range .IPAM.Config}}{{.Subnet}}{{end}}").Output()
if err != nil {
panic(err)
}
_, ipnet, err := net.ParseCIDR(string(out[:len(out)-1]))
if err != nil {
panic(err)
}
ifaces, err := net.Interfaces()
if err != nil {
panic(err)
}
for _, i := range ifaces {
addrs, err := i.Addrs()
if err != nil {
continue
}
for _, addr := range addrs {
if v, ok := addr.(*net.IPNet); ok {
if ipnet.Contains(v.IP) {
return v.IP.String()
}
}
}
}
panic("IP not found")
}()
2020-05-10 19:32:40 +00:00
type container struct {
2020-07-10 10:22:30 +00:00
name string
2020-05-10 19:32:40 +00:00
}
func newContainer(image string, name string, args []string) (*container, error) {
c := &container{
2020-07-10 10:22:30 +00:00
name: name,
2020-05-10 19:32:40 +00:00
}
exec.Command("docker", "kill", "rtsp-simple-server-test-"+name).Run()
exec.Command("docker", "wait", "rtsp-simple-server-test-"+name).Run()
2020-06-08 19:36:42 +00:00
cmd := []string{"docker", "run",
2020-05-10 19:32:40 +00:00
"--name=rtsp-simple-server-test-" + name,
"rtsp-simple-server-test-" + image}
cmd = append(cmd, args...)
ecmd := exec.Command(cmd[0], cmd[1:]...)
2020-07-10 10:22:30 +00:00
ecmd.Stdout = nil
2020-05-10 19:32:40 +00:00
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", "rtsp-simple-server-test-"+c.name).Run()
exec.Command("docker", "wait", "rtsp-simple-server-test-"+c.name).Run()
exec.Command("docker", "rm", "rtsp-simple-server-test-"+c.name).Run()
}
2020-07-10 10:22:30 +00:00
func (c *container) wait() int {
2020-05-10 19:32:40 +00:00
exec.Command("docker", "wait", "rtsp-simple-server-test-"+c.name).Run()
2020-07-10 10:22:30 +00:00
out, _ := exec.Command("docker", "inspect", "rtsp-simple-server-test-"+c.name,
2020-10-03 19:10:41 +00:00
"-f", "{{.State.ExitCode}}").Output()
2020-07-10 10:22:30 +00:00
code, _ := strconv.ParseInt(string(out[:len(out)-1]), 10, 64)
return int(code)
2020-05-10 19:32:40 +00:00
}
2020-10-03 19:10:41 +00:00
func (c *container) ip() string {
out, _ := exec.Command("docker", "inspect", "rtsp-simple-server-test-"+c.name,
"-f", "{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}").Output()
return string(out[:len(out)-1])
}
func testProgram(conf string) (*program, error) {
if conf == "" {
2020-10-13 23:19:14 +00:00
return newProgram([]string{})
}
tmpf, err := ioutil.TempFile(os.TempDir(), "rtsp-")
if err != nil {
return nil, err
}
defer os.Remove(tmpf.Name())
tmpf.WriteString(conf)
tmpf.Close()
2020-10-13 23:19:14 +00:00
return newProgram([]string{tmpf.Name()})
}
func TestEnvironment(t *testing.T) {
// string
2020-10-30 23:11:51 +00:00
os.Setenv("RTSP_RUNONCONNECT", "test=cmd")
defer os.Unsetenv("RTSP_RUNONCONNECT")
// int
os.Setenv("RTSP_RTSPPORT", "8555")
defer os.Unsetenv("RTSP_RTSPPORT")
// bool
os.Setenv("RTSP_METRICS", "yes")
defer os.Unsetenv("RTSP_METRICS")
// duration
os.Setenv("RTSP_READTIMEOUT", "22s")
defer os.Unsetenv("RTSP_READTIMEOUT")
// slice
os.Setenv("RTSP_LOGDESTINATIONS", "stdout,file")
defer os.Unsetenv("RTSP_LOGDESTINATIONS")
// map key
os.Setenv("RTSP_PATHS_TEST2", "")
defer os.Unsetenv("RTSP_PATHS_TEST2")
2020-10-18 22:08:44 +00:00
// map values, "all" path
os.Setenv("RTSP_PATHS_ALL_READUSER", "testuser")
defer os.Unsetenv("RTSP_PATHS_ALL_READUSER")
os.Setenv("RTSP_PATHS_ALL_READPASS", "testpass")
defer os.Unsetenv("RTSP_PATHS_ALL_READPASS")
// map values, generic path
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
os.Setenv("RTSP_PATHS_CAM1_SOURCEPROTOCOL", "tcp")
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCEPROTOCOL")
os.Setenv("RTSP_PATHS_CAM1_SOURCEONDEMAND", "yes")
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCEONDEMAND")
p, err := testProgram("")
require.NoError(t, err)
defer p.close()
2020-10-30 23:11:51 +00:00
require.Equal(t, "test=cmd", p.conf.RunOnConnect)
require.Equal(t, 8555, p.conf.RtspPort)
require.Equal(t, true, p.conf.Metrics)
require.Equal(t, 22*time.Second, p.conf.ReadTimeout)
require.Equal(t, []string{"stdout", "file"}, p.conf.LogDestinations)
pa, ok := p.conf.Paths["test2"]
require.Equal(t, true, ok)
2020-10-13 22:50:08 +00:00
require.Equal(t, &conf.PathConf{
Source: "record",
SourceOnDemandStartTimeout: 10 * time.Second,
SourceOnDemandCloseAfter: 10 * time.Second,
RunOnDemandStartTimeout: 10 * time.Second,
RunOnDemandCloseAfter: 10 * time.Second,
}, pa)
2020-10-18 22:08:44 +00:00
pa, ok = p.conf.Paths["~^.*$"]
require.Equal(t, true, ok)
require.Equal(t, &conf.PathConf{
Regexp: regexp.MustCompile("^.*$"),
Source: "record",
SourceProtocol: "automatic",
SourceOnDemandStartTimeout: 10 * time.Second,
SourceOnDemandCloseAfter: 10 * time.Second,
ReadUser: "testuser",
ReadPass: "testpass",
RunOnDemandStartTimeout: 10 * time.Second,
RunOnDemandCloseAfter: 10 * time.Second,
2020-10-18 22:08:44 +00:00
}, pa)
pa, ok = p.conf.Paths["cam1"]
require.Equal(t, true, ok)
2020-10-13 22:50:08 +00:00
require.Equal(t, &conf.PathConf{
Source: "rtsp://testing",
SourceProtocol: "tcp",
SourceProtocolParsed: func() *gortsplib.StreamProtocol {
v := gortsplib.StreamProtocolTCP
return &v
}(),
SourceOnDemand: true,
SourceOnDemandStartTimeout: 10 * time.Second,
SourceOnDemandCloseAfter: 10 * time.Second,
RunOnDemandStartTimeout: 10 * time.Second,
RunOnDemandCloseAfter: 10 * time.Second,
}, pa)
}
func TestEnvironmentNoFile(t *testing.T) {
os.Setenv("RTSP_PATHS_CAM1_SOURCE", "rtsp://testing")
defer os.Unsetenv("RTSP_PATHS_CAM1_SOURCE")
p, err := testProgram("{}")
require.NoError(t, err)
defer p.close()
pa, ok := p.conf.Paths["cam1"]
require.Equal(t, true, ok)
require.Equal(t, &conf.PathConf{
Source: "rtsp://testing",
SourceProtocol: "automatic",
SourceOnDemandStartTimeout: 10 * time.Second,
SourceOnDemandCloseAfter: 10 * time.Second,
RunOnDemandStartTimeout: 10 * time.Second,
RunOnDemandCloseAfter: 10 * time.Second,
}, pa)
}
func TestPublish(t *testing.T) {
for _, conf := range []struct {
publishSoft string
publishProto string
}{
{"ffmpeg", "udp"},
{"ffmpeg", "tcp"},
{"gstreamer", "udp"},
{"gstreamer", "tcp"},
2020-05-10 19:32:40 +00:00
} {
t.Run(conf.publishSoft+"_"+conf.publishProto, func(t *testing.T) {
p, err := testProgram("")
2020-05-10 19:32:40 +00:00
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
switch conf.publishSoft {
case "ffmpeg":
2020-10-27 23:29:53 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", conf.publishProto,
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/teststream",
})
require.NoError(t, err)
defer cnt1.close()
default:
cnt1, err := newContainer("gstreamer", "source", []string{
2020-10-05 19:07:34 +00:00
"filesrc location=emptyvideo.ts ! tsdemux ! queue ! video/x-h264 ! h264parse config-interval=1 ! rtspclientsink " +
2020-12-05 19:42:59 +00:00
"location=rtsp://" + ownDockerIP + ":8554/teststream protocols=" + conf.publishProto + " latency=0",
})
require.NoError(t, err)
defer cnt1.close()
}
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/teststream",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
})
}
}
func TestRead(t *testing.T) {
for _, conf := range []struct {
readSoft string
readProto string
}{
{"ffmpeg", "udp"},
{"ffmpeg", "tcp"},
{"vlc", "udp"},
{"vlc", "tcp"},
} {
t.Run(conf.readSoft+"_"+conf.readProto, func(t *testing.T) {
p, err := testProgram("")
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
2020-05-10 19:32:40 +00:00
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/teststream",
2020-05-10 19:32:40 +00:00
})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
switch conf.readSoft {
case "ffmpeg":
2020-10-27 23:29:53 +00:00
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", conf.readProto,
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/teststream",
2020-07-10 10:22:30 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-07-10 10:22:30 +00:00
default:
2020-07-10 10:22:30 +00:00
args := []string{}
if conf.readProto == "tcp" {
2020-07-10 10:22:30 +00:00
args = append(args, "--rtsp-tcp")
}
2020-12-05 19:42:59 +00:00
args = append(args, "rtsp://"+ownDockerIP+":8554/teststream")
2020-05-10 19:32:40 +00:00
2020-07-10 10:22:30 +00:00
cnt2, err := newContainer("vlc", "dest", args)
require.NoError(t, err)
defer cnt2.close()
2020-05-10 19:32:40 +00:00
require.Equal(t, 0, cnt2.wait())
2020-07-10 10:22:30 +00:00
}
2020-05-10 19:32:40 +00:00
})
}
}
2020-09-05 11:19:55 +00:00
func TestTCPOnly(t *testing.T) {
2020-10-27 23:29:53 +00:00
p, err := testProgram("protocols: [tcp]\n")
2020-08-29 17:48:41 +00:00
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
2020-08-29 17:48:41 +00:00
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "tcp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/teststream",
2020-08-29 17:48:41 +00:00
})
require.NoError(t, err)
defer cnt1.close()
2020-10-27 23:29:53 +00:00
cnt2, err := newContainer("ffmpeg", "dest", []string{
2020-08-29 17:48:41 +00:00
"-rtsp_transport", "tcp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/teststream",
2020-08-29 17:48:41 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-08-29 17:48:41 +00:00
}
2020-08-29 18:49:26 +00:00
func TestPathWithSlash(t *testing.T) {
p, err := testProgram("")
2020-08-29 18:49:26 +00:00
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
2020-08-29 18:49:26 +00:00
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/test/stream",
2020-08-29 18:49:26 +00:00
})
require.NoError(t, err)
defer cnt1.close()
2020-10-27 23:29:53 +00:00
cnt2, err := newContainer("ffmpeg", "dest", []string{
2020-08-29 18:49:26 +00:00
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test/stream",
2020-08-29 18:49:26 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-08-29 18:49:26 +00:00
}
func TestPathWithQuery(t *testing.T) {
p, err := testProgram("")
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/test?param1=val&param2=val",
})
require.NoError(t, err)
defer cnt1.close()
2020-10-27 23:29:53 +00:00
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test?param3=otherval",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
}
2020-07-10 10:22:30 +00:00
func TestAuth(t *testing.T) {
t.Run("publish", func(t *testing.T) {
2020-10-27 23:29:53 +00:00
p, err := testProgram("paths:\n" +
2020-07-10 10:22:30 +00:00
" all:\n" +
" publishUser: testuser\n" +
" publishPass: test!$()*+.;<=>[]^_-{}\n" +
2020-10-27 23:29:53 +00:00
" publishIps: [172.17.0.0/16]\n")
2020-07-10 10:22:30 +00:00
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIP + ":8554/test/stream",
2020-07-10 10:22:30 +00:00
})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test/stream",
2020-07-10 10:22:30 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
2020-05-10 19:32:40 +00:00
require.Equal(t, 0, cnt2.wait())
2020-05-10 19:32:40 +00:00
})
2020-07-10 10:22:30 +00:00
for _, soft := range []string{
"ffmpeg",
"vlc",
} {
t.Run("read_"+soft, func(t *testing.T) {
2020-10-27 23:29:53 +00:00
p, err := testProgram("paths:\n" +
2020-07-10 10:22:30 +00:00
" all:\n" +
" readUser: testuser\n" +
" readPass: test!$()*+.;<=>[]^_-{}\n" +
2020-10-27 23:29:53 +00:00
" readIps: [172.17.0.0/16]\n")
2020-07-10 10:22:30 +00:00
require.NoError(t, err)
defer p.close()
2020-05-10 20:56:46 +00:00
2020-07-10 10:22:30 +00:00
time.Sleep(1 * time.Second)
2020-05-10 20:56:46 +00:00
2020-07-10 10:22:30 +00:00
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/test/stream",
2020-07-10 10:22:30 +00:00
})
require.NoError(t, err)
defer cnt1.close()
2020-05-10 20:56:46 +00:00
2020-07-10 10:22:30 +00:00
time.Sleep(1 * time.Second)
2020-05-10 20:56:46 +00:00
2020-07-10 10:22:30 +00:00
if soft == "ffmpeg" {
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIP + ":8554/test/stream",
2020-07-10 10:22:30 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-07-10 10:22:30 +00:00
} else {
cnt2, err := newContainer("vlc", "dest", []string{
2020-12-05 19:42:59 +00:00
"rtsp://testuser:test!$()*+.;<=>[]^_-{}@" + ownDockerIP + ":8554/test/stream",
})
2020-07-10 10:22:30 +00:00
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-07-10 10:22:30 +00:00
}
})
}
2020-05-10 20:56:46 +00:00
}
func TestAuthIpFail(t *testing.T) {
p, err := testProgram("paths:\n" +
" all:\n" +
" publishIps: [127.0.0.1/32]\n")
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
"rtsp://" + ownDockerIP + ":8554/test/stream",
})
require.NoError(t, err)
defer cnt1.close()
require.NotEqual(t, 0, cnt1.wait())
}
2020-10-03 19:10:41 +00:00
func TestSourceRtsp(t *testing.T) {
for _, proto := range []string{
"udp",
"tcp",
} {
t.Run(proto, func(t *testing.T) {
2020-10-27 23:29:53 +00:00
p1, err := testProgram("paths:\n" +
" all:\n" +
" readUser: testuser\n" +
2020-10-27 23:29:53 +00:00
" readPass: testpass\n")
require.NoError(t, err)
defer p1.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/teststream",
})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
p2, err := testProgram("rtspPort: 8555\n" +
"rtpPort: 8100\n" +
"rtcpPort: 8101\n" +
"\n" +
"paths:\n" +
" proxied:\n" +
" source: rtsp://testuser:testpass@localhost:8554/teststream\n" +
2020-07-30 11:41:56 +00:00
" sourceProtocol: " + proto + "\n" +
2020-10-27 23:29:53 +00:00
" sourceOnDemand: yes\n")
require.NoError(t, err)
defer p2.close()
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8555/proxied",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
})
}
}
2020-07-30 11:41:56 +00:00
2020-10-03 19:10:41 +00:00
func TestSourceRtmp(t *testing.T) {
cnt1, err := newContainer("nginx-rtmp", "rtmpserver", []string{})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "flv",
"rtmp://" + cnt1.ip() + "/stream/test",
})
require.NoError(t, err)
defer cnt2.close()
time.Sleep(1 * time.Second)
2020-10-27 23:29:53 +00:00
p, err := testProgram("paths:\n" +
2020-10-03 19:10:41 +00:00
" proxied:\n" +
" source: rtmp://" + cnt1.ip() + "/stream/test\n" +
2020-10-27 23:29:53 +00:00
" sourceOnDemand: yes\n")
2020-10-03 19:10:41 +00:00
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
cnt3, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/proxied",
2020-10-03 19:10:41 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt3.close()
require.Equal(t, 0, cnt3.wait())
2020-10-03 19:10:41 +00:00
}
2020-10-27 23:29:53 +00:00
func TestRedirect(t *testing.T) {
p1, err := testProgram("paths:\n" +
" path1:\n" +
" source: redirect\n" +
2020-12-05 19:42:59 +00:00
" sourceRedirect: rtsp://" + ownDockerIP + ":8554/path2\n" +
2020-10-27 23:29:53 +00:00
" path2:\n")
require.NoError(t, err)
defer p1.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/path2",
2020-10-27 23:29:53 +00:00
})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/path1",
2020-10-27 23:29:53 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-10-27 23:29:53 +00:00
}
2020-11-01 16:48:00 +00:00
func TestFallback(t *testing.T) {
p1, err := testProgram("paths:\n" +
" path1:\n" +
2020-12-05 19:42:59 +00:00
" fallback: rtsp://" + ownDockerIP + ":8554/path2\n" +
2020-11-01 16:48:00 +00:00
" path2:\n")
require.NoError(t, err)
defer p1.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "source", []string{
"-re",
"-stream_loop", "-1",
"-i", "/emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"rtsp://" + ownDockerIP + ":8554/path2",
2020-11-01 16:48:00 +00:00
})
require.NoError(t, err)
defer cnt1.close()
time.Sleep(1 * time.Second)
cnt2, err := newContainer("ffmpeg", "dest", []string{
"-rtsp_transport", "udp",
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/path1",
2020-11-01 16:48:00 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt2.close()
require.Equal(t, 0, cnt2.wait())
2020-11-01 16:48:00 +00:00
}
2020-07-30 11:41:56 +00:00
func TestRunOnDemand(t *testing.T) {
2020-10-27 23:29:53 +00:00
p1, err := testProgram("paths:\n" +
2020-09-19 15:13:45 +00:00
" all:\n" +
2020-11-01 16:33:06 +00:00
" runOnDemand: ffmpeg -hide_banner -loglevel error -re -i testimages/ffmpeg/emptyvideo.ts -c copy -f rtsp rtsp://localhost:$RTSP_PORT/$RTSP_PATH\n")
2020-07-30 11:41:56 +00:00
require.NoError(t, err)
defer p1.close()
time.Sleep(1 * time.Second)
cnt1, err := newContainer("ffmpeg", "dest", []string{
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/ondemand",
2020-07-30 11:41:56 +00:00
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt1.close()
require.Equal(t, 0, cnt1.wait())
2020-07-30 11:41:56 +00:00
}
func TestHotReloading(t *testing.T) {
confPath := filepath.Join(os.TempDir(), "rtsp-conf")
err := ioutil.WriteFile(confPath, []byte("paths:\n"+
" test1:\n"+
" runOnDemand: ffmpeg -hide_banner -loglevel error -re -i testimages/ffmpeg/emptyvideo.ts -c copy -f rtsp rtsp://localhost:$RTSP_PORT/$RTSP_PATH\n"+
" test3:\n"+
" runOnInit: echo aaa\n"+
" test4:\n"+
" runOnInit: echo bbb\n"),
0644)
require.NoError(t, err)
defer os.Remove(confPath)
p, err := newProgram([]string{confPath})
require.NoError(t, err)
defer p.close()
time.Sleep(1 * time.Second)
func() {
cnt1, err := newContainer("ffmpeg", "dest", []string{
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test1",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt1.close()
require.Equal(t, 0, cnt1.wait())
}()
err = ioutil.WriteFile(confPath, []byte("paths:\n"+
" test2:\n"+
" runOnDemand: ffmpeg -hide_banner -loglevel error -re -i testimages/ffmpeg/emptyvideo.ts -c copy -f rtsp rtsp://localhost:$RTSP_PORT/$RTSP_PATH\n"+
" test3:\n"+
" test4:\n"+
" runOnInit: echo bbb\n"),
0644)
require.NoError(t, err)
time.Sleep(1 * time.Second)
func() {
cnt1, err := newContainer("ffmpeg", "dest", []string{
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test1",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt1.close()
require.Equal(t, 1, cnt1.wait())
}()
func() {
cnt1, err := newContainer("ffmpeg", "dest", []string{
2020-12-05 19:42:59 +00:00
"-i", "rtsp://" + ownDockerIP + ":8554/test2",
"-vframes", "1",
"-f", "image2",
"-y", "/dev/null",
})
require.NoError(t, err)
defer cnt1.close()
require.Equal(t, 0, cnt1.wait())
}()
}