second forcepush this away if i fail

This commit is contained in:
Soph :3 2025-11-24 20:41:43 +02:00
parent d1f1aae0d3
commit 9e5cd110e0
3 changed files with 201 additions and 316 deletions

View file

@ -11,36 +11,36 @@ import (
"time"
)
// RTPRelay holds information on the relaying stream listener
type RTPRelay struct {
close bool
targetIP net.IP
targetPort int
listener net.PacketConn
context context.Context
// Frame is a decoded RTP packet buffer forwarded to the RTSP server
type Frame struct {
Payload []byte
}
var close bool
// RTPRelay holds information on the relaying stream listener
type RTPRelay struct {
close bool
listener net.PacketConn
context context.Context
Output chan Frame // 🚨 NEW: channel to push decoded RTP frames
}
var closeFlag bool
// CreateRTPRelay creates a UDP listener that handles live data
// from the camera and forwards it as an RTP stream
func CreateRTPRelay(ctx context.Context, targetAddress net.IP, targetPort int) *RTPRelay {
// and pushes RTP-ready payloads into Output channel.
func CreateRTPRelay(ctx context.Context) *RTPRelay {
conn, err := net.ListenPacket("udp", ":6669")
if err != nil {
log.Printf("ERROR: %s\n", err)
}
close = false
closeFlag = false
relay := RTPRelay{
close: false,
targetIP: targetAddress,
targetPort: targetPort,
listener: conn,
context: ctx,
}
if err != nil {
log.Printf("ERROR: %s\n", err)
close: false,
listener: conn,
context: ctx,
Output: make(chan Frame, 100), // buffered for smoother streaming
}
go handleCameraStream(relay, conn)
@ -55,92 +55,85 @@ func handleCameraStream(relay RTPRelay, conn net.PacketConn) {
header := streamHeader{}
var payload []byte
rtpTarget := net.UDPAddr{
IP: relay.targetIP,
Port: relay.targetPort,
}
rtpSource, _ := net.ResolveUDPAddr("udp", "127.0.0.1")
rtpConn, err := net.DialUDP("udp", rtpSource, &rtpTarget)
if err != nil {
log.Printf("ERROR creating RTP sender: %s\n", err)
}
var sequenceNumber uint16
var elapsed uint32
frameBuffer := bytes.Buffer{}
packetBuffer := bytes.Buffer{}
T:
for {
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
select {
case <-relay.context.Done():
log.Println("Context Done")
rtpConn.Close()
T:
for {
conn.SetReadDeadline(time.Now().Add(10 * time.Second))
select {
case <-relay.context.Done():
log.Println("Context Done")
relay.listener.Close()
close(relay.Output)
break T
default:
if closeFlag {
relay.listener.Close()
close(relay.Output)
break T
default:
if close {
rtpConn.Close()
relay.listener.Close()
break T
}
conn.ReadFrom(buffer)
packetReader.Reset(buffer)
}
binary.Read(packetReader, binary.BigEndian, &header)
conn.ReadFrom(buffer)
packetReader.Reset(buffer)
if header.Magic != 0xBCDE {
log.Printf("Received message with invalid magic (%x).", header.Magic)
binary.Read(packetReader, binary.BigEndian, &header)
if header.Magic != 0xBCDE {
log.Printf("Received message with invalid magic (%x).", header.Magic)
break
}
if header.Length > 0 {
payload = make([]byte, header.Length)
_, err := io.ReadFull(packetReader, payload)
if err != nil {
log.Printf("Read Error: %s\n", err)
break
}
} else {
payload = []byte{}
}
if header.Length > 0 {
payload = make([]byte, header.Length)
_, err := io.ReadFull(packetReader, payload)
if err != nil {
log.Printf("Read Error: %s\n", err)
break
}
} else {
payload = []byte{}
}
switch header.MessageType {
case 0x0001: // H.264 Data
frameBuffer.Write(payload)
switch header.MessageType {
case 0x0001: // H.264 Data
frameBuffer.Write(payload)
case 0x0002: // Time
// Append the Framebuffer
packetBuffer.Write(frameBuffer.Bytes())
case 0x0002: // Time
// Append full frame
packetBuffer.Write(frameBuffer.Bytes())
// Send out the packet
rtpConn.Write(packetBuffer.Bytes())
// Push to RTSP server (in-memory)
relay.Output <- Frame{Payload: append([]byte{}, packetBuffer.Bytes()...)}
// Prepare the next packet
packetBuffer.Reset()
packetBuffer.Write([]byte{0x80, 0x63})
binary.Write(&packetBuffer, binary.BigEndian, sequenceNumber+1)
binary.Write(&packetBuffer, binary.BigEndian, (uint32)(elapsed)*90)
binary.Write(&packetBuffer, binary.BigEndian, (uint64(0)))
// Reset the next packet
packetBuffer.Reset()
packetBuffer.Write([]byte{0x80, 0x63})
binary.Write(&packetBuffer, binary.BigEndian, sequenceNumber+1)
binary.Write(&packetBuffer, binary.BigEndian, (uint32)(elapsed)*90)
binary.Write(&packetBuffer, binary.BigEndian, (uint64(0)))
// Reset the Framebuffer
frameBuffer.Reset()
sequenceNumber++
frameBuffer.Reset()
sequenceNumber++
elapsed = binary.LittleEndian.Uint32(payload[12:])
elapsed = binary.LittleEndian.Uint32(payload[12:])
default:
log.Printf("Received Unknown Message: %+v\n", header)
log.Printf("Payload:\n%s\n", hex.Dump(payload))
}
default:
log.Printf("Received Unknown Message: %+v\n", header)
log.Printf("Payload:\n%s\n", hex.Dump(payload))
}
}
}
close(relay.Output)
}
// Stop stops listening for packets
func (r *RTPRelay) Stop() {
close = true
closeFlag = true
r.close = true
r.listener.Close()
}