This commit is contained in:
Soph :3 2025-11-24 20:46:11 +02:00
parent 9e5cd110e0
commit ab8b9f5315
2 changed files with 55 additions and 52 deletions

View file

@ -273,7 +273,10 @@ func main() {
} }
relay := libipcamera.CreateRTPRelay(applicationContext) relay := libipcamera.CreateRTPRelay(applicationContext)
rtspServer, err := rtsp.CreateServer(applicationContext, host, port, relay) rtspServer, err := rtsp.CreateServer(applicationContext, host, port, relay)
defer rtspServer.Close() if rtspServer != nil {
defer rtspServer.Close()
}
if err := camera.StartPreviewStream(); err != nil { if err := camera.StartPreviewStream(); err != nil {

View file

@ -24,45 +24,47 @@ type Server struct {
wg sync.WaitGroup wg sync.WaitGroup
} }
// CreateServer now requires relay as input
func CreateServer(parentCtx context.Context, host string, port int, relay *libipcamera.RTPRelay) (*Server, error) { func CreateServer(parentCtx context.Context, host string, port int, relay *libipcamera.RTPRelay) (*Server, error) {
ctx, cancel := context.WithCancel(parentCtx) ctx, cancel := context.WithCancel(parentCtx)
stream, media, err := newH264Stream() // Create the RTSP server instance first
if err != nil { h := &handler{}
cancel() gs := &gortsplib.Server{
return nil, fmt.Errorf("create H264 stream: %w", err) Handler: h,
} RTSPAddress: fmt.Sprintf("%s:%d", host, port),
}
srv := &Server{ // Now create the H264 stream bound to this server
ctx: ctx, stream, media, err := newH264Stream(gs)
cancel: cancel, if err != nil {
stream: stream, cancel()
media: media, return nil, fmt.Errorf("create H264 stream: %w", err)
} }
h := &handler{srv: srv} // Final server struct assembly
srv := &Server{
ctx: ctx,
cancel: cancel,
gs: gs,
stream: stream,
media: media,
}
h.srv = srv // link handler to server instance
gs := &gortsplib.Server{ // Start pumping RTP frames from relay into RTSP
Handler: h, srv.wg.Add(1)
RTSPAddress: fmt.Sprintf("%s:%d", host, port), go srv.relayPump(relay)
}
srv.gs = gs
// 🧠 Pump from relay to RTSP // Start the RTSP server
srv.wg.Add(1) go func() {
go srv.relayPump(relay) log.Printf("RTSP server ready on rtsp://%s:%d/", host, port)
if err := gs.StartAndWait(); err != nil {
log.Printf("RTSP stopped: %v", err)
}
cancel()
}()
go func() { return srv, nil
log.Printf("RTSP server ready on rtsp://%s:%d/", host, port)
err := gs.StartAndWait()
if err != nil {
log.Printf("RTSP stopped: %v", err)
}
cancel()
}()
return srv, nil
} }
func (s *Server) Close() { func (s *Server) Close() {
@ -113,27 +115,25 @@ func (h *handler) OnPlay(ctx *gortsplib.ServerHandlerOnPlayCtx) (*base.Response,
} }
// Build simple baseline H264 SDP // Build simple baseline H264 SDP
func newH264Stream() (*gortsplib.ServerStream, *description.Media, error) { func newH264Stream(gs *gortsplib.Server) (*gortsplib.ServerStream, *description.Media, error) {
h264 := &format.H264{ h264 := &format.H264{
PayloadTyp: 96, PayloadTyp: 96,
PacketizationMode: 1, PacketizationMode: 1,
SPS: []byte{0x67, 0x42, 0xC0, 0x1F, 0x96, 0x54, 0x05, 0x01, 0xED, 0x00, 0xF0, 0x88, 0x45, 0x80}, SPS: []byte{0x67, 0x42, 0xC0, 0x1F, 0x96, 0x54, 0x05, 0x01, 0xED, 0x00, 0xF0, 0x88, 0x45, 0x80},
PPS: []byte{0x68, 0xCE, 0x38, 0x80}, PPS: []byte{0x68, 0xCE, 0x38, 0x80},
} }
media := &description.Media{ media := &description.Media{
Type: description.MediaTypeVideo, Type: description.MediaTypeVideo,
Formats: []format.Format{h264}, Formats: []format.Format{h264},
} }
desc := &description.Session{ desc := &description.Session{
Medias: []*description.Media{media}, Medias: []*description.Media{media},
} }
stream := &gortsplib.ServerStream{Desc: desc} // REQUIRED: link stream to the running server
if err := stream.Initialize(); err != nil { stream := gortsplib.NewServerStream(gs, desc)
return nil, nil, err
}
return stream, media, nil return stream, media, nil
} }