mirror of
https://github.com/aler9/gortsplib
synced 2025-10-05 07:06:58 +08:00
165 lines
3.6 KiB
Go
165 lines
3.6 KiB
Go
package gortsplib
|
|
|
|
import (
|
|
"crypto/tls"
|
|
"fmt"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func extractPort(address string) (int, error) {
|
|
_, tmp, err := net.SplitHostPort(address)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
tmp2, err := strconv.ParseInt(tmp, 10, 64)
|
|
if err != nil {
|
|
return 0, err
|
|
}
|
|
|
|
return int(tmp2), nil
|
|
}
|
|
|
|
// Server is a RTSP server.
|
|
type Server struct {
|
|
// a TLS configuration to accept TLS (RTSPS) connections.
|
|
TLSConfig *tls.Config
|
|
|
|
// a port to send and receive UDP/RTP packets.
|
|
// If UDPRTPAddress and UDPRTCPAddress are != "", the server can accept and send UDP streams.
|
|
UDPRTPAddress string
|
|
|
|
// a port to send and receive UDP/RTCP packets.
|
|
// If UDPRTPAddress and UDPRTCPAddress are != "", the server can accept and send UDP streams.
|
|
UDPRTCPAddress string
|
|
|
|
// timeout of read operations.
|
|
// It defaults to 10 seconds
|
|
ReadTimeout time.Duration
|
|
|
|
// timeout of write operations.
|
|
// It defaults to 10 seconds
|
|
WriteTimeout time.Duration
|
|
|
|
// read buffer count.
|
|
// If greater than 1, allows to pass buffers to routines different than the one
|
|
// that is reading frames.
|
|
// It also allows to buffer routed frames and mitigate network fluctuations
|
|
// that are particularly high when using UDP.
|
|
// It defaults to 512
|
|
ReadBufferCount int
|
|
|
|
// read buffer size.
|
|
// This must be touched only when the server reports problems about buffer sizes.
|
|
// It defaults to 2048.
|
|
ReadBufferSize int
|
|
|
|
// function used to initialize the TCP listener.
|
|
// It defaults to net.Listen
|
|
Listen func(network string, address string) (net.Listener, error)
|
|
|
|
receiverReportPeriod time.Duration
|
|
|
|
tcpListener net.Listener
|
|
udpRTPListener *serverUDPListener
|
|
udpRTCPListener *serverUDPListener
|
|
}
|
|
|
|
// Serve starts listening on the given address.
|
|
func (s *Server) Serve(address string) error {
|
|
if s.ReadTimeout == 0 {
|
|
s.ReadTimeout = 10 * time.Second
|
|
}
|
|
if s.WriteTimeout == 0 {
|
|
s.WriteTimeout = 10 * time.Second
|
|
}
|
|
if s.ReadBufferCount == 0 {
|
|
s.ReadBufferCount = 512
|
|
}
|
|
if s.ReadBufferSize == 0 {
|
|
s.ReadBufferSize = 2048
|
|
}
|
|
|
|
if s.Listen == nil {
|
|
s.Listen = net.Listen
|
|
}
|
|
|
|
if s.receiverReportPeriod == 0 {
|
|
s.receiverReportPeriod = 10 * time.Second
|
|
}
|
|
|
|
if s.TLSConfig != nil && s.UDPRTPAddress != "" {
|
|
return fmt.Errorf("TLS can't be used together with UDP")
|
|
}
|
|
|
|
if (s.UDPRTPAddress != "" && s.UDPRTCPAddress == "") ||
|
|
(s.UDPRTPAddress == "" && s.UDPRTCPAddress != "") {
|
|
return fmt.Errorf("UDPRTPAddress and UDPRTCPAddress must be used together")
|
|
}
|
|
|
|
if s.UDPRTPAddress != "" {
|
|
rtpPort, err := extractPort(s.UDPRTPAddress)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
rtcpPort, err := extractPort(s.UDPRTCPAddress)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if (rtpPort % 2) != 0 {
|
|
return fmt.Errorf("RTP port must be even")
|
|
}
|
|
|
|
if rtcpPort != (rtpPort + 1) {
|
|
return fmt.Errorf("RTCP and RTP ports must be consecutive")
|
|
}
|
|
|
|
s.udpRTPListener, err = newServerUDPListener(s, s.UDPRTPAddress, StreamTypeRTP)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
s.udpRTCPListener, err = newServerUDPListener(s, s.UDPRTCPAddress, StreamTypeRTCP)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
var err error
|
|
s.tcpListener, err = s.Listen("tcp", address)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// Accept accepts a connection.
|
|
func (s *Server) Accept() (*ServerConn, error) {
|
|
nconn, err := s.tcpListener.Accept()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return newServerConn(s, nconn), nil
|
|
}
|
|
|
|
// Close closes all the server resources.
|
|
func (s *Server) Close() error {
|
|
s.tcpListener.Close()
|
|
|
|
if s.udpRTPListener != nil {
|
|
s.udpRTPListener.close()
|
|
}
|
|
|
|
if s.udpRTCPListener != nil {
|
|
s.udpRTCPListener.close()
|
|
}
|
|
|
|
return nil
|
|
}
|