@@ -27,13 +27,24 @@ func (c *Client) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiver
2727
2828 if c .sender == nil {
2929 c .sender = core .NewSender (media , track .Codec )
30+
31+ // Set up the audio handler
3032 c .sender .Handler = func (packet * rtp.Packet ) {
3133 // Get connection in a thread-safe way
3234 conn := c .getConnection ()
3335 if conn == nil {
3436 return
3537 }
3638
39+ // For G.711, we should send raw audio data without RTP headers
40+ // The Dahua camera expects pure G.711 audio samples
41+ audioData := packet .Payload
42+
43+ // Skip empty packets
44+ if len (audioData ) == 0 {
45+ return
46+ }
47+
3748 // Send multipart boundary with payload
3849 boundary := "\r \n --go2rtc-audio-boundary\r \n "
3950
@@ -49,18 +60,18 @@ func (c *Client) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiver
4960 }
5061
5162 boundary += "Content-Type: " + contentType + "\r \n "
52- boundary += "Content-Length: " + fmt . Sprintf ( "%d" , len ( packet . Payload )) + " \r \n \r \n "
63+ boundary += fmt . Sprintf ( "Content-Length: %d \r \n \r \n " , len ( audioData ))
5364
54- // Write boundary first
55- if _ , err := conn .Write ([]byte (boundary )); err != nil {
56- log .Error ().Err (err ).Msg ("[dahua] failed to write boundary" )
57- return
58- }
65+ // Write boundary and audio data in one operation to reduce fragmentation
66+ fullData := append ([]byte (boundary ), audioData ... )
67+
68+ // Use thread-safe connection writing
69+ c .connMu .Lock ()
70+ n , err := conn .Write (fullData )
71+ c .connMu .Unlock ()
5972
60- // Write payload
61- n , err := conn .Write (packet .Payload )
6273 if err != nil {
63- log .Error ().Err (err ).Msg ("[dahua] failed to write audio payload " )
74+ log .Debug ().Err (err ).Msg ("[dahua] failed to write audio data " )
6475 return
6576 }
6677
@@ -73,14 +84,14 @@ func (c *Client) AddTrack(media *core.Media, _ *core.Codec, track *core.Receiver
7384 Msg ("[dahua] audio sender created" )
7485 }
7586
76- c .sender .HandleRTP (track )
87+ c .sender .WithParent (track ). Start ( )
7788 return nil
7889}
7990
8091// getConnection returns the current connection in a thread-safe way
8192func (c * Client ) getConnection () io.WriteCloser {
82- // For now, just return the connection directly
83- // TODO: Add proper synchronization if needed
93+ c . connMu . RLock ()
94+ defer c . connMu . RUnlock ()
8495 return c .conn
8596}
8697
@@ -111,7 +122,6 @@ func (c *Client) Stop() (err error) {
111122 if err != nil {
112123 log .Error ().Err (err ).Msg ("[dahua] error during close" )
113124 }
114- // Don't call c.conn.Close() again since c.close() already handles it
115125 log .Debug ().Msg ("[dahua] connection closed" )
116126 }
117127
0 commit comments