mirror of https://github.com/EasyDarwin/EasyDarwin
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
278 lines
6.9 KiB
278 lines
6.9 KiB
package rtsp |
|
|
|
import ( |
|
"bytes" |
|
"fmt" |
|
"log" |
|
"net" |
|
"strconv" |
|
"strings" |
|
"time" |
|
|
|
"github.com/penggy/EasyGoLib/utils" |
|
) |
|
|
|
type UDPServer struct { |
|
*Session |
|
*RTSPClient |
|
|
|
APort int |
|
AConn *net.UDPConn |
|
AControlPort int |
|
AControlConn *net.UDPConn |
|
VPort int |
|
VConn *net.UDPConn |
|
VControlPort int |
|
VControlConn *net.UDPConn |
|
|
|
Stoped bool |
|
} |
|
|
|
func (s *UDPServer) AddInputBytes(bytes int) { |
|
if s.Session != nil { |
|
s.Session.InBytes += bytes |
|
return |
|
} |
|
if s.RTSPClient != nil { |
|
s.RTSPClient.InBytes += bytes |
|
return |
|
} |
|
panic(fmt.Errorf("session and RTSPClient both nil")) |
|
} |
|
|
|
func (s *UDPServer) HandleRTP(pack *RTPPack) { |
|
if s.Session != nil { |
|
for _, v := range s.Session.RTPHandles { |
|
v(pack) |
|
} |
|
return |
|
} |
|
|
|
if s.RTSPClient != nil { |
|
for _, v := range s.RTSPClient.RTPHandles { |
|
v(pack) |
|
} |
|
return |
|
} |
|
panic(fmt.Errorf("session and RTSPClient both nil")) |
|
} |
|
|
|
func (s *UDPServer) Logger() *log.Logger { |
|
if s.Session != nil { |
|
return s.Session.logger |
|
} |
|
if s.RTSPClient != nil { |
|
return s.RTSPClient.logger |
|
} |
|
panic(fmt.Errorf("session and RTSPClient both nil")) |
|
} |
|
|
|
func (s *UDPServer) Stop() { |
|
if s.Stoped { |
|
return |
|
} |
|
s.Stoped = true |
|
if s.AConn != nil { |
|
s.AConn.Close() |
|
s.AConn = nil |
|
} |
|
if s.AControlConn != nil { |
|
s.AControlConn.Close() |
|
s.AControlConn = nil |
|
} |
|
if s.VConn != nil { |
|
s.VConn.Close() |
|
s.VConn = nil |
|
} |
|
if s.VControlConn != nil { |
|
s.VControlConn.Close() |
|
s.VControlConn = nil |
|
} |
|
} |
|
|
|
func (s *UDPServer) SetupAudio() (err error) { |
|
logger := s.Logger() |
|
addr, err := net.ResolveUDPAddr("udp", ":0") |
|
if err != nil { |
|
return |
|
} |
|
s.AConn, err = net.ListenUDP("udp", addr) |
|
if err != nil { |
|
return |
|
} |
|
networkBuffer := utils.Conf().Section("rtsp").Key("network_buffer").MustInt(1048576) |
|
if err := s.AConn.SetReadBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server audio conn set read buffer error, %v", err) |
|
} |
|
if err := s.AConn.SetWriteBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server audio conn set write buffer error, %v", err) |
|
} |
|
la := s.AConn.LocalAddr().String() |
|
strPort := la[strings.LastIndex(la, ":")+1:] |
|
s.APort, err = strconv.Atoi(strPort) |
|
if err != nil { |
|
return |
|
} |
|
go func() { |
|
bufUDP := make([]byte, UDP_BUF_SIZE) |
|
logger.Printf("udp server start listen audio port[%d]", s.APort) |
|
defer logger.Printf("udp server stop listen audio port[%d]", s.APort) |
|
timer := time.Unix(0, 0) |
|
for !s.Stoped { |
|
if n, _, err := s.AConn.ReadFromUDP(bufUDP); err == nil { |
|
elapsed := time.Now().Sub(timer) |
|
if elapsed >= 30*time.Second { |
|
logger.Printf("Package recv from AConn.len:%d\n", n) |
|
timer = time.Now() |
|
} |
|
rtpBytes := make([]byte, n) |
|
s.AddInputBytes(n) |
|
copy(rtpBytes, bufUDP) |
|
pack := &RTPPack{ |
|
Type: RTP_TYPE_AUDIO, |
|
Buffer: bytes.NewBuffer(rtpBytes), |
|
} |
|
s.HandleRTP(pack) |
|
} else { |
|
logger.Println("udp server read audio pack error", err) |
|
continue |
|
} |
|
} |
|
}() |
|
addr, err = net.ResolveUDPAddr("udp", ":0") |
|
if err != nil { |
|
return |
|
} |
|
s.AControlConn, err = net.ListenUDP("udp", addr) |
|
if err != nil { |
|
return |
|
} |
|
if err := s.AControlConn.SetReadBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server audio control conn set read buffer error, %v", err) |
|
} |
|
if err := s.AControlConn.SetWriteBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server audio control conn set write buffer error, %v", err) |
|
} |
|
la = s.AControlConn.LocalAddr().String() |
|
strPort = la[strings.LastIndex(la, ":")+1:] |
|
s.AControlPort, err = strconv.Atoi(strPort) |
|
if err != nil { |
|
return |
|
} |
|
go func() { |
|
bufUDP := make([]byte, UDP_BUF_SIZE) |
|
logger.Printf("udp server start listen audio control port[%d]", s.AControlPort) |
|
defer logger.Printf("udp server stop listen audio control port[%d]", s.AControlPort) |
|
for !s.Stoped { |
|
if n, _, err := s.AControlConn.ReadFromUDP(bufUDP); err == nil { |
|
//logger.Printf("Package recv from AControlConn.len:%d\n", n) |
|
rtpBytes := make([]byte, n) |
|
s.AddInputBytes(n) |
|
copy(rtpBytes, bufUDP) |
|
pack := &RTPPack{ |
|
Type: RTP_TYPE_AUDIOCONTROL, |
|
Buffer: bytes.NewBuffer(rtpBytes), |
|
} |
|
s.HandleRTP(pack) |
|
} else { |
|
logger.Println("udp server read audio control pack error", err) |
|
continue |
|
} |
|
} |
|
}() |
|
return |
|
} |
|
|
|
func (s *UDPServer) SetupVideo() (err error) { |
|
logger := s.Logger() |
|
addr, err := net.ResolveUDPAddr("udp", ":0") |
|
if err != nil { |
|
return |
|
} |
|
s.VConn, err = net.ListenUDP("udp", addr) |
|
if err != nil { |
|
return |
|
} |
|
networkBuffer := utils.Conf().Section("rtsp").Key("network_buffer").MustInt(1048576) |
|
if err := s.VConn.SetReadBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server video conn set read buffer error, %v", err) |
|
} |
|
if err := s.VConn.SetWriteBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server video conn set write buffer error, %v", err) |
|
} |
|
la := s.VConn.LocalAddr().String() |
|
strPort := la[strings.LastIndex(la, ":")+1:] |
|
s.VPort, err = strconv.Atoi(strPort) |
|
if err != nil { |
|
return |
|
} |
|
go func() { |
|
bufUDP := make([]byte, UDP_BUF_SIZE) |
|
logger.Printf("udp server start listen video port[%d]", s.VPort) |
|
defer logger.Printf("udp server stop listen video port[%d]", s.VPort) |
|
timer := time.Unix(0, 0) |
|
for !s.Stoped { |
|
if n, _, err := s.VConn.ReadFromUDP(bufUDP); err == nil { |
|
elapsed := time.Now().Sub(timer) |
|
if elapsed >= 30*time.Second { |
|
logger.Printf("Package recv from VConn.len:%d\n", n) |
|
timer = time.Now() |
|
} |
|
rtpBytes := make([]byte, n) |
|
s.AddInputBytes(n) |
|
copy(rtpBytes, bufUDP) |
|
pack := &RTPPack{ |
|
Type: RTP_TYPE_VIDEO, |
|
Buffer: bytes.NewBuffer(rtpBytes), |
|
} |
|
s.HandleRTP(pack) |
|
} else { |
|
logger.Println("udp server read video pack error", err) |
|
continue |
|
} |
|
} |
|
}() |
|
|
|
addr, err = net.ResolveUDPAddr("udp", ":0") |
|
if err != nil { |
|
return |
|
} |
|
s.VControlConn, err = net.ListenUDP("udp", addr) |
|
if err != nil { |
|
return |
|
} |
|
if err := s.VControlConn.SetReadBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server video control conn set read buffer error, %v", err) |
|
} |
|
if err := s.VControlConn.SetWriteBuffer(networkBuffer); err != nil { |
|
logger.Printf("udp server video control conn set write buffer error, %v", err) |
|
} |
|
la = s.VControlConn.LocalAddr().String() |
|
strPort = la[strings.LastIndex(la, ":")+1:] |
|
s.VControlPort, err = strconv.Atoi(strPort) |
|
if err != nil { |
|
return |
|
} |
|
go func() { |
|
bufUDP := make([]byte, UDP_BUF_SIZE) |
|
logger.Printf("udp server start listen video control port[%d]", s.VControlPort) |
|
defer logger.Printf("udp server stop listen video control port[%d]", s.VControlPort) |
|
for !s.Stoped { |
|
if n, _, err := s.VControlConn.ReadFromUDP(bufUDP); err == nil { |
|
//logger.Printf("Package recv from VControlConn.len:%d\n", n) |
|
rtpBytes := make([]byte, n) |
|
s.AddInputBytes(n) |
|
copy(rtpBytes, bufUDP) |
|
pack := &RTPPack{ |
|
Type: RTP_TYPE_VIDEOCONTROL, |
|
Buffer: bytes.NewBuffer(rtpBytes), |
|
} |
|
s.HandleRTP(pack) |
|
} else { |
|
logger.Println("udp server read video control pack error", err) |
|
continue |
|
} |
|
} |
|
}() |
|
return |
|
}
|
|
|