diff --git a/libipcamera/RTPRelay.go b/libipcamera/RTPRelay.go index 6018a4d..0be228c 100644 --- a/libipcamera/RTPRelay.go +++ b/libipcamera/RTPRelay.go @@ -11,9 +11,9 @@ import ( ) type Frame struct { - Data []byte + Data []byte + Elapsed uint32 } - type RTPRelay struct { close bool listener net.PacketConn @@ -50,6 +50,8 @@ func (r *RTPRelay) readLoop() { frameBuffer := bytes.Buffer{} + var elapsed uint32 // <-- store last timestamp + for { r.listener.SetReadDeadline(time.Now().Add(10 * time.Second)) @@ -86,12 +88,15 @@ func (r *RTPRelay) readLoop() { case 0x0001: frameBuffer.Write(payload) case 0x0002: + if len(payload) >= 16 { + elapsed = binary.LittleEndian.Uint32(payload[12:]) + } // Emit a full H264 frame if frameBuffer.Len() > 0 { - cp := append([]byte{}, frameBuffer.Bytes()...) - r.Frames <- Frame{Data: cp} - frameBuffer.Reset() - } + cp := append([]byte{}, frameBuffer.Bytes()...) + r.Frames <- Frame{Data: cp, Elapsed: elapsed} + frameBuffer.Reset() + } } } } diff --git a/rtsp/RTSPServer.go b/rtsp/RTSPServer.go index 41f7909..eb2fcb5 100644 --- a/rtsp/RTSPServer.go +++ b/rtsp/RTSPServer.go @@ -6,6 +6,7 @@ import ( "log" "strconv" "sync" + "time" "github.com/bluenviron/gortsplib/v5" "github.com/bluenviron/gortsplib/v5/pkg/base" @@ -97,7 +98,7 @@ func (s *Server) startPump(cctx context.Context, relay *libipcamera.RTPRelay, h defer s.wg.Done() var seq uint16 - var ts uint32 + var lastTS uint32 var sps, pps []byte @@ -110,6 +111,14 @@ func (s *Server) startPump(cctx context.Context, relay *libipcamera.RTPRelay, h if !ok { return } + var ts = frame.Elapsed * 90 + + if lastTS != 0 && frame.Elapsed > lastTS { + delta := frame.Elapsed - lastTS + time.Sleep(time.Duration(delta) * time.Millisecond) + } + + lastTS = frame.Elapsed nalus := splitNALUnits(frame.Data) for _, nalu := range nalus { @@ -208,7 +217,6 @@ func writeRTP(h *Handler, stream *gortsplib.ServerStream, payload []byte, marker stream.WritePacketRTP(stream.Desc.Medias[0], pkt) *seq++ - *ts += 3600 } // ---- SHUTDOWN ----