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

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
}