The following program is designed to receive audio tracks from a client. Each time the client connects or reconnects, the latest audio track is passed into this program. However, there is a very strange issue: the first connection works perfectly fine, and when the first connection is lost, the for
loop correctly triggers a break
. However, for all subsequent connections, there is no real-time feedback at all. I have to restart the entire program to make it work again.
func (c *Channel) HandleAudio(track *webrtc.TrackRemote) {
if track.Kind() != webrtc.RTPCodecTypeAudio {
log.Println(color.Yellow.Sprintf("[channel:HandleAudio] Received non-audio track"))
return
}
codec := track.Codec()
log.Println(color.Gray.Sprintf("[channel:HandleAudio] Audio MIME: %s\n", codec.MimeType))
if c.Assistant.Channel.LocalAudio != nil && c.Assistant.Status {
log.Println(color.Gray.Sprintf("[channel:HandleAudio] Started audio"))
pcm := make([]int16, 960)
decoder, err := opus.NewDecoder(48000, 1)
if err != nil {
log.Println(color.Red.Sprintf("[channel:HandleAudio] Failed to create decoder: %v", err))
return
}
for {
rtp, _, err := track.ReadRTP()
if err != nil {
log.Println(color.Red.Sprintf("[channel:HandleAudio] Failed to read RTP: %v", err))
break
}
_, err = decoder.Decode(rtp.Payload, pcm)
if err != nil {
log.Println(color.Gray.Sprintf("[channel:HandleAudio] Failed to decode sample: %v", err))
continue
}
err = c.Assistant.Channel.LocalAudio.WriteRTP(rtp)
if err != nil {
log.Println(color.Red.Sprintf("[channel:HandleAudio] Failed to write sample: %v", err))
}
}
}
}
Below is the relevant handling for each client connection or disconnection, which can be used as a reference.
peer.RTC.OnTrack(func(track *webrtc.TrackRemote, receiver *webrtc.RTPReceiver) {
if track.Kind() == webrtc.RTPCodecTypeAudio {
log.Println(color.Gray.Sprintf("[router:handler:realtime:human] OnTrack"))
realtime.Get.Channel.HandleAudio(track)
}
})