reduce usage of rtsp-simple-server in client tests

This commit is contained in:
aler9
2021-03-13 13:49:21 +01:00
parent a9a93f4fac
commit 792d74e6ef
3 changed files with 384 additions and 172 deletions

View File

@@ -2,6 +2,7 @@ package gortsplib
import ( import (
"bufio" "bufio"
"crypto/tls"
"net" "net"
"os" "os"
"os/exec" "os/exec"
@@ -63,7 +64,7 @@ func (c *container) wait() int {
return int(code) return int(code)
} }
func TestClientDialRead(t *testing.T) { func TestClientRead(t *testing.T) {
for _, ca := range []struct { for _, ca := range []struct {
encrypted bool encrypted bool
proto string proto string
@@ -81,39 +82,142 @@ func TestClientDialRead(t *testing.T) {
t.Run(encryptedStr+"_"+ca.proto, func(t *testing.T) { t.Run(encryptedStr+"_"+ca.proto, func(t *testing.T) {
var scheme string var scheme string
var port string var l net.Listener
var serverConf string if ca.encrypted {
if !ca.encrypted {
scheme = "rtsp"
port = "8554"
serverConf = "{}"
} else {
scheme = "rtsps" scheme = "rtsps"
port = "8555"
serverConf = "readTimeout: 20s\n" + li, err := net.Listen("tcp", "localhost:8554")
"protocols: [tcp]\n" + require.NoError(t, err)
"encryption: yes\n" defer li.Close()
cert, err := tls.X509KeyPair(serverCert, serverKey)
require.NoError(t, err)
l = tls.NewListener(li, &tls.Config{Certificates: []tls.Certificate{cert}})
} else {
scheme = "rtsp"
var err error
l, err = net.Listen("tcp", "localhost:8554")
require.NoError(t, err)
defer l.Close()
} }
cnt1, err := newContainer("rtsp-simple-server", "server", []string{serverConf}) serverDone := make(chan struct{})
require.NoError(t, err) defer func() { <-serverDone }()
defer cnt1.close() go func() {
defer close(serverDone)
time.Sleep(1 * time.Second) conn, err := l.Accept()
require.NoError(t, err)
defer conn.Close()
bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
cnt2, err := newContainer("ffmpeg", "publish", []string{ var req base.Request
"-re", err = req.Read(bconn.Reader)
"-stream_loop", "-1", require.NoError(t, err)
"-i", "emptyvideo.ts", require.Equal(t, base.Options, req.Method)
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
scheme + "://localhost:" + port + "/teststream",
})
require.NoError(t, err)
defer cnt2.close()
time.Sleep(1 * time.Second) err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
string(base.Setup),
string(base.Play),
}, ", ")},
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
track, err := NewTrackH264(96, []byte("123456"), []byte("123456"))
require.NoError(t, err)
sdp := Tracks{track}.Write()
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: sdp,
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
th, err := headers.ReadTransport(req.Header["Transport"])
require.NoError(t, err)
if ca.proto == "udp" {
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Transport": headers.Transport{
Protocol: StreamProtocolUDP,
Delivery: func() *base.StreamDelivery {
v := base.StreamDeliveryUnicast
return &v
}(),
ClientPorts: th.ClientPorts,
ServerPorts: &[2]int{34556, 34557},
}.Write(),
},
}.Write(bconn.Writer)
require.NoError(t, err)
} else {
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Transport": headers.Transport{
Protocol: StreamProtocolTCP,
Delivery: func() *base.StreamDelivery {
v := base.StreamDeliveryUnicast
return &v
}(),
ClientPorts: th.ClientPorts,
InterleavedIds: &[2]int{0, 1},
}.Write(),
},
}.Write(bconn.Writer)
require.NoError(t, err)
}
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Play, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
}.Write(bconn.Writer)
require.NoError(t, err)
if ca.proto == "udp" {
l1, err := net.ListenPacket("udp", "localhost:34556")
require.NoError(t, err)
defer l1.Close()
l1.WriteTo([]byte("\x00\x00\x00\x00"), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[0],
})
} else {
err = base.InterleavedFrame{
TrackID: 0,
StreamType: StreamTypeRTP,
Payload: []byte("\x00\x00\x00\x00"),
}.Write(bconn.Writer)
require.NoError(t, err)
}
}()
conf := ClientConf{ conf := ClientConf{
StreamProtocol: func() *StreamProtocol { StreamProtocol: func() *StreamProtocol {
@@ -126,15 +230,12 @@ func TestClientDialRead(t *testing.T) {
}(), }(),
} }
conn, err := conf.DialRead(scheme + "://localhost:" + port + "/teststream") conn, err := conf.DialRead(scheme + "://localhost:8554/teststream")
require.NoError(t, err) require.NoError(t, err)
var firstFrame int32
frameRecv := make(chan struct{}) frameRecv := make(chan struct{})
done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) { done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) {
if atomic.SwapInt32(&firstFrame, 1) == 0 { close(frameRecv)
close(frameRecv)
}
}) })
<-frameRecv <-frameRecv
@@ -149,7 +250,7 @@ func TestClientDialRead(t *testing.T) {
} }
} }
func TestClientDialReadNoServerPorts(t *testing.T) { func TestClientReadNoServerPorts(t *testing.T) {
for _, ca := range []string{ for _, ca := range []string{
"zero", "zero",
"no", "no",
@@ -240,8 +341,6 @@ func TestClientDialReadNoServerPorts(t *testing.T) {
}.Write(bconn.Writer) }.Write(bconn.Writer)
require.NoError(t, err) require.NoError(t, err)
time.Sleep(1 * time.Second)
l1, err := net.ListenPacket("udp", "localhost:0") l1, err := net.ListenPacket("udp", "localhost:0")
require.NoError(t, err) require.NoError(t, err)
defer l1.Close() defer l1.Close()
@@ -271,40 +370,108 @@ func TestClientDialReadNoServerPorts(t *testing.T) {
} }
} }
func TestClientDialReadAutomaticProtocol(t *testing.T) { func TestClientReadAutomaticProtocol(t *testing.T) {
cnt1, err := newContainer("rtsp-simple-server", "server", []string{ l, err := net.Listen("tcp", "localhost:8554")
"protocols: [tcp]\n",
})
require.NoError(t, err) require.NoError(t, err)
defer cnt1.close() defer l.Close()
time.Sleep(1 * time.Second) serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
cnt2, err := newContainer("ffmpeg", "publish", []string{ conn, err := l.Accept()
"-re", require.NoError(t, err)
"-stream_loop", "-1", defer conn.Close()
"-i", "emptyvideo.ts", bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "tcp",
"rtsp://localhost:8554/teststream",
})
require.NoError(t, err)
defer cnt2.close()
time.Sleep(1 * time.Second) var req base.Request
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
string(base.Setup),
string(base.Play),
}, ", ")},
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
track, err := NewTrackH264(96, []byte("123456"), []byte("123456"))
require.NoError(t, err)
sdp := Tracks{track}.Write()
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: sdp,
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
err = base.Response{
StatusCode: base.StatusUnsupportedTransport,
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Transport": headers.Transport{
Protocol: StreamProtocolTCP,
Delivery: func() *base.StreamDelivery {
v := base.StreamDeliveryUnicast
return &v
}(),
InterleavedIds: &[2]int{0, 1},
}.Write(),
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Play, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
}.Write(bconn.Writer)
require.NoError(t, err)
err = base.InterleavedFrame{
TrackID: 0,
StreamType: StreamTypeRTP,
Payload: []byte("\x00\x00\x00\x00"),
}.Write(bconn.Writer)
require.NoError(t, err)
}()
conf := ClientConf{StreamProtocol: nil} conf := ClientConf{StreamProtocol: nil}
conn, err := conf.DialRead("rtsp://localhost:8554/teststream") conn, err := conf.DialRead("rtsp://localhost:8554/teststream")
require.NoError(t, err) require.NoError(t, err)
var firstFrame int32
frameRecv := make(chan struct{}) frameRecv := make(chan struct{})
done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) { done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) {
if atomic.SwapInt32(&firstFrame, 1) == 0 { close(frameRecv)
close(frameRecv)
}
}) })
<-frameRecv <-frameRecv
@@ -312,42 +479,137 @@ func TestClientDialReadAutomaticProtocol(t *testing.T) {
<-done <-done
} }
func TestClientDialReadRedirect(t *testing.T) { func TestClientReadRedirect(t *testing.T) {
cnt1, err := newContainer("rtsp-simple-server", "server", []string{ l, err := net.Listen("tcp", "localhost:8554")
"paths:\n" +
" path1:\n" +
" source: redirect\n" +
" sourceRedirect: rtsp://localhost:8554/path2\n" +
" path2:\n",
})
require.NoError(t, err) require.NoError(t, err)
defer cnt1.close() defer l.Close()
time.Sleep(1 * time.Second) serverDone := make(chan struct{})
defer func() { <-serverDone }()
go func() {
defer close(serverDone)
cnt2, err := newContainer("ffmpeg", "publish", []string{ conn, err := l.Accept()
"-re", require.NoError(t, err)
"-stream_loop", "-1", bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
"-i", "emptyvideo.ts",
"-c", "copy",
"-f", "rtsp",
"-rtsp_transport", "udp",
"rtsp://localhost:8554/path2",
})
require.NoError(t, err)
defer cnt2.close()
time.Sleep(1 * time.Second) var req base.Request
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
string(base.Setup),
string(base.Play),
}, ", ")},
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
err = base.Response{
StatusCode: base.StatusMovedPermanently,
Header: base.Header{
"Location": base.HeaderValue{"rtsp://localhost:8554/test"},
},
}.Write(bconn.Writer)
require.NoError(t, err)
conn.Close()
conn, err = l.Accept()
require.NoError(t, err)
defer conn.Close()
bconn = bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Options, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Public": base.HeaderValue{strings.Join([]string{
string(base.Describe),
string(base.Setup),
string(base.Play),
}, ", ")},
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Describe, req.Method)
track, err := NewTrackH264(96, []byte("123456"), []byte("123456"))
require.NoError(t, err)
sdp := Tracks{track}.Write()
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Content-Type": base.HeaderValue{"application/sdp"},
},
Body: sdp,
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Setup, req.Method)
th, err := headers.ReadTransport(req.Header["Transport"])
require.NoError(t, err)
err = base.Response{
StatusCode: base.StatusOK,
Header: base.Header{
"Transport": headers.Transport{
Protocol: StreamProtocolUDP,
Delivery: func() *base.StreamDelivery {
v := base.StreamDeliveryUnicast
return &v
}(),
ClientPorts: th.ClientPorts,
ServerPorts: &[2]int{34556, 34557},
}.Write(),
},
}.Write(bconn.Writer)
require.NoError(t, err)
err = req.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.Play, req.Method)
err = base.Response{
StatusCode: base.StatusOK,
}.Write(bconn.Writer)
require.NoError(t, err)
l1, err := net.ListenPacket("udp", "localhost:34556")
require.NoError(t, err)
defer l1.Close()
l1.WriteTo([]byte("\x00\x00\x00\x00"), &net.UDPAddr{
IP: net.ParseIP("127.0.0.1"),
Port: th.ClientPorts[0],
})
}()
conn, err := DialRead("rtsp://localhost:8554/path1") conn, err := DialRead("rtsp://localhost:8554/path1")
require.NoError(t, err) require.NoError(t, err)
var firstFrame int32
frameRecv := make(chan struct{}) frameRecv := make(chan struct{})
done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) { done := conn.ReadFrames(func(id int, typ StreamType, payload []byte) {
if atomic.SwapInt32(&firstFrame, 1) == 0 { close(frameRecv)
close(frameRecv)
}
}) })
<-frameRecv <-frameRecv
@@ -355,7 +617,7 @@ func TestClientDialReadRedirect(t *testing.T) {
<-done <-done
} }
func TestClientDialReadPause(t *testing.T) { func TestClientReadPause(t *testing.T) {
for _, proto := range []string{ for _, proto := range []string{
"udp", "udp",
"tcp", "tcp",
@@ -426,7 +688,7 @@ func TestClientDialReadPause(t *testing.T) {
} }
} }
func TestClientDialPublishSerial(t *testing.T) { func TestClientPublishSerial(t *testing.T) {
for _, proto := range []string{ for _, proto := range []string{
"udp", "udp",
"tcp", "tcp",
@@ -487,7 +749,7 @@ func TestClientDialPublishSerial(t *testing.T) {
} }
} }
func TestClientDialPublishParallel(t *testing.T) { func TestClientPublishParallel(t *testing.T) {
for _, ca := range []struct { for _, ca := range []struct {
proto string proto string
server string server string
@@ -600,7 +862,7 @@ func TestClientDialPublishParallel(t *testing.T) {
} }
} }
func TestClientDialPublishPauseSerial(t *testing.T) { func TestClientPublishPauseSerial(t *testing.T) {
for _, proto := range []string{ for _, proto := range []string{
"udp", "udp",
"tcp", "tcp",
@@ -672,7 +934,7 @@ func TestClientDialPublishPauseSerial(t *testing.T) {
} }
} }
func TestClientDialPublishPauseParallel(t *testing.T) { func TestClientPublishPauseParallel(t *testing.T) {
for _, proto := range []string{ for _, proto := range []string{
"udp", "udp",
"tcp", "tcp",

View File

@@ -342,6 +342,35 @@ y++U32uuSFiXDcSLarfIsE992MEJLSAynbF1Rsgsr3gXbGiuToJRyxbIeVy7gwzD
-----END RSA PRIVATE KEY----- -----END RSA PRIVATE KEY-----
`) `)
func TestServerTeardownResponse(t *testing.T) {
ts, err := newTestServ(nil)
require.NoError(t, err)
defer ts.close()
conn, err := net.Dial("tcp", "localhost:8554")
require.NoError(t, err)
defer conn.Close()
bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
err = base.Request{
Method: base.Teardown,
URL: base.MustParseURL("rtsp://localhost:8554/"),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
},
}.Write(bconn.Writer)
require.NoError(t, err)
var res base.Response
err = res.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
buf := make([]byte, 2048)
_, err = bconn.Read(buf)
require.Equal(t, io.EOF, err)
}
func TestServerPublishRead(t *testing.T) { func TestServerPublishRead(t *testing.T) {
for _, ca := range []struct { for _, ca := range []struct {
encrypted bool encrypted bool
@@ -447,36 +476,7 @@ func TestServerPublishRead(t *testing.T) {
} }
} }
func TestServerTeardownResponse(t *testing.T) { func TestServerReadWithoutSetupTrackID(t *testing.T) {
ts, err := newTestServ(nil)
require.NoError(t, err)
defer ts.close()
conn, err := net.Dial("tcp", "localhost:8554")
require.NoError(t, err)
defer conn.Close()
bconn := bufio.NewReadWriter(bufio.NewReader(conn), bufio.NewWriter(conn))
err = base.Request{
Method: base.Teardown,
URL: base.MustParseURL("rtsp://localhost:8554/"),
Header: base.Header{
"CSeq": base.HeaderValue{"1"},
},
}.Write(bconn.Writer)
require.NoError(t, err)
var res base.Response
err = res.Read(bconn.Reader)
require.NoError(t, err)
require.Equal(t, base.StatusOK, res.StatusCode)
buf := make([]byte, 2048)
_, err = bconn.Read(buf)
require.Equal(t, io.EOF, err)
}
func TestServerSetupWithoutTrackID(t *testing.T) {
ts, err := newTestServ(nil) ts, err := newTestServ(nil)
require.NoError(t, err) require.NoError(t, err)
defer ts.close() defer ts.close()
@@ -545,7 +545,7 @@ func TestServerSetupWithoutTrackID(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
} }
func TestServerResponseBeforeFrames(t *testing.T) { func TestServerReadResponseBeforeFrames(t *testing.T) {
ts, err := newTestServ(nil) ts, err := newTestServ(nil)
require.NoError(t, err) require.NoError(t, err)
defer ts.close() defer ts.close()
@@ -614,7 +614,7 @@ func TestServerResponseBeforeFrames(t *testing.T) {
require.NoError(t, err) require.NoError(t, err)
} }
func TestServerPlayMultiple(t *testing.T) { func TestServerReadPlayMultiple(t *testing.T) {
ts, err := newTestServ(nil) ts, err := newTestServ(nil)
require.NoError(t, err) require.NoError(t, err)
defer ts.close() defer ts.close()
@@ -692,7 +692,7 @@ func TestServerPlayMultiple(t *testing.T) {
require.Equal(t, base.StatusOK, res.StatusCode) require.Equal(t, base.StatusOK, res.StatusCode)
} }
func TestServerPauseMultiple(t *testing.T) { func TestServerReadPauseMultiple(t *testing.T) {
ts, err := newTestServ(nil) ts, err := newTestServ(nil)
require.NoError(t, err) require.NoError(t, err)
defer ts.close() defer ts.close()

View File

@@ -2,54 +2,4 @@
echo "$@" > /rtsp-simple-server.yml echo "$@" > /rtsp-simple-server.yml
echo "-----BEGIN CERTIFICATE-----
MIIDazCCAlOgAwIBAgIUXw1hEC3LFpTsllv7D3ARJyEq7sIwDQYJKoZIhvcNAQEL
BQAwRTELMAkGA1UEBhMCQVUxEzARBgNVBAgMClNvbWUtU3RhdGUxITAfBgNVBAoM
GEludGVybmV0IFdpZGdpdHMgUHR5IEx0ZDAeFw0yMDEyMTMxNzQ0NThaFw0zMDEy
MTExNzQ0NThaMEUxCzAJBgNVBAYTAkFVMRMwEQYDVQQIDApTb21lLVN0YXRlMSEw
HwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEB
AQUAA4IBDwAwggEKAoIBAQDG8DyyS51810GsGwgWr5rjJK7OE1kTTLSNEEKax8Bj
zOyiaz8rA2JGl2VUEpi2UjDr9Cm7nd+YIEVs91IIBOb7LGqObBh1kGF3u5aZxLkv
NJE+HrLVvUhaDobK2NU+Wibqc/EI3DfUkt1rSINvv9flwTFu1qHeuLWhoySzDKEp
OzYxpFhwjVSokZIjT4Red3OtFz7gl2E6OAWe2qoh5CwLYVdMWtKR0Xuw3BkDPk9I
qkQKx3fqv97LPEzhyZYjDT5WvGrgZ1WDAN3booxXF3oA1H3GHQc4m/vcLatOtb8e
nI59gMQLEbnp08cl873bAuNuM95EZieXTHNbwUnq5iybAgMBAAGjUzBRMB0GA1Ud
DgQWBBQBKhJh8eWu0a4au9X/2fKhkFX2vjAfBgNVHSMEGDAWgBQBKhJh8eWu0a4a
u9X/2fKhkFX2vjAPBgNVHRMBAf8EBTADAQH/MA0GCSqGSIb3DQEBCwUAA4IBAQBj
3aCW0YPKukYgVK9cwN0IbVy/D0C1UPT4nupJcy/E0iC7MXPZ9D/SZxYQoAkdptdO
xfI+RXkpQZLdODNx9uvV+cHyZHZyjtE5ENu/i5Rer2cWI/mSLZm5lUQyx+0KZ2Yu
tEI1bsebDK30msa8QSTn0WidW9XhFnl3gRi4wRdimcQapOWYVs7ih+nAlSvng7NI
XpAyRs8PIEbpDDBMWnldrX4TP6EWYUi49gCp8OUDRREKX3l6Ls1vZ02F34yHIt/7
7IV/XSKG096bhW+icKBWV0IpcEsgTzPK1J1hMxgjhzIMxGboAeUU+kidthOob6Sd
XQxaORfgM//NzX9LhUPk
-----END CERTIFICATE-----" > /server.crt
echo "-----BEGIN RSA PRIVATE KEY-----
MIIEogIBAAKCAQEAxvA8skudfNdBrBsIFq+a4ySuzhNZE0y0jRBCmsfAY8zsoms/
KwNiRpdlVBKYtlIw6/Qpu53fmCBFbPdSCATm+yxqjmwYdZBhd7uWmcS5LzSRPh6y
1b1IWg6GytjVPlom6nPxCNw31JLda0iDb7/X5cExbtah3ri1oaMkswyhKTs2MaRY
cI1UqJGSI0+EXndzrRc+4JdhOjgFntqqIeQsC2FXTFrSkdF7sNwZAz5PSKpECsd3
6r/eyzxM4cmWIw0+Vrxq4GdVgwDd26KMVxd6ANR9xh0HOJv73C2rTrW/HpyOfYDE
CxG56dPHJfO92wLjbjPeRGYnl0xzW8FJ6uYsmwIDAQABAoIBACi0BKcyQ3HElSJC
kaAao+Uvnzh4yvPg8Nwf5JDIp/uDdTMyIEWLtrLczRWrjGVZYbsVROinP5VfnPTT
kYwkfKINj2u+gC6lsNuPnRuvHXikF8eO/mYvCTur1zZvsQnF5kp4GGwIqr+qoPUP
bB0UMndG1PdpoMryHe+JcrvTrLHDmCeH10TqOwMsQMLHYLkowvxwJWsmTY7/Qr5S
Wm3PPpOcW2i0uyPVuyuv4yD1368fqnqJ8QFsQp1K6QtYsNnJ71Hut1/IoxK/e6hj
5Z+byKtHVtmcLnABuoOT7BhleJNFBksX9sh83jid4tMBgci+zXNeGmgqo2EmaWAb
agQslkECgYEA8B1rzjOHVQx/vwSzDa4XOrpoHQRfyElrGNz9JVBvnoC7AorezBXQ
M9WTHQIFTGMjzD8pb+YJGi3gj93VN51r0SmJRxBaBRh1ZZI9kFiFzngYev8POgD3
ygmlS3kTHCNxCK/CJkB+/jMBgtPj5ygDpCWVcTSuWlQFphePkW7jaaECgYEA1Blz
ulqgAyJHZaqgcbcCsI2q6m527hVr9pjzNjIVmkwu38yS9RTCgdlbEVVDnS0hoifl
+jVMEGXjF3xjyMvL50BKbQUH+KAa+V4n1WGlnZOxX9TMny8MBjEuSX2+362vQ3BX
4vOlX00gvoc+sY+lrzvfx/OdPCHQGVYzoKCxhLsCgYA07HcviuIAV/HsO2/vyvhp
xF5gTu+BqNUHNOZDDDid+ge+Jre2yfQLCL8VPLXIQW3Jff53IH/PGl+NtjphuLvj
7UDJvgvpZZuymIojP6+2c3gJ3CASC9aR3JBnUzdoE1O9s2eaoMqc4scpe+SWtZYf
3vzSZ+cqF6zrD/Rf/M35IQKBgHTU4E6ShPm09CcoaeC5sp2WK8OevZw/6IyZi78a
r5Oiy18zzO97U/k6xVMy6F+38ILl/2Rn31JZDVJujniY6eSkIVsUHmPxrWoXV1HO
y++U32uuSFiXDcSLarfIsE992MEJLSAynbF1Rsgsr3gXbGiuToJRyxbIeVy7gwzD
94TpAoGAY4/PejWQj9psZfAhyk5dRGra++gYRQ/gK1IIc1g+Dd2/BxbT/RHr05GK
6vwrfjsoRyMWteC1SsNs/CurjfQ/jqCfHNP5XPvxgd5Ec8sRJIiV7V5RTuWJsPu1
+3K6cnKEyg+0ekYmLertRFIY6SwWmY1fyKgTvxudMcsBY7dC4xs=
-----END RSA PRIVATE KEY-----" > /server.key
exec /rtsp-simple-server exec /rtsp-simple-server