go – Golang PION/WebRTC: Issues with Audio Transmission via PortAudio and OPUS Encoding
I am encountering issues with a Go script for a WebRTC-based application using the GO/PION library. The application captures a video stream and makes it available over a WebRTC connection, while also receiving audio via WebRTC and playing it through the system speakers. As a final module, I am implementing a system to send audio to the WebRTC connection. This system is supposed to capture the microphone stream using github.com/gordonklaus/portaudio, encode it in OPUS using gopkg.in/hraban/opus.v2, and write it to the output track added to the WebRTC connection.
Here is an excerpt of the non-functional code
import (
"github.com/gordonklaus/portaudio"
"github.com/hajimehoshi/oto"
"github.com/pion/webrtc/v4"
"github.com/pion/webrtc/v4/pkg/media"
"gopkg.in/hraban/opus.v2"
"github.com/pion/rtp"
"log"
"runtime"
"time"
)
func main() {
runtime.GOMAXPROCS(runtime.NumCPU()) // Utilize all available CPU cores
outboundAudioTrack, err := webrtc.NewTrackLocalStaticRTP(webrtc.RTPCodecCapability{
MimeType: webrtc.MimeTypeOpus,
}, "audio", "pion")
if err != nil {
log.Fatalf("Failed to create audio track: %s", err)
}
// Initialize PortAudio
if err := portaudio.Initialize(); err != nil {
log.Fatalf("Failed to initialize PortAudio: %s", err)
}
defer portaudio.Terminate()
go StartMicrophoneStream(outboundAudioTrack)
}
func StartMicrophoneStream(outboundAudioTrack *webrtc.TrackLocalStaticRTP) {
// Open default microphone device
stream, err := portaudio.OpenDefaultStream(1, 0, sampleRate, frameSize, readAudio)
if err != nil {
log.Fatalf("Failed to open default stream: %s", err)
}
defer stream.Close()
// Start the audio stream
if err := stream.Start(); err != nil {
log.Fatalf("Failed to start stream: %s", err)
}
defer stream.Stop()
log.Println("Microphone streaming started")
// Keep the stream open
select {}
}
func readAudio(in []int16) {
// Log input buffer
// log.Printf("Captured audio data: %v", inputBuffer)
// Create Opus encoder
encoder, err := opus.NewEncoder(sampleRate, channels, opus.AppVoIP)
if err != nil {
log.Fatalf("Failed to create Opus encoder: %s", err)
}
// Encode PCM to Opus
packet := make([]byte, 4000) // Adjust size as needed
n, err := encoder.Encode(in, packet)
if err != nil {
log.Printf("Error encoding PCM to Opus: %s", err)
return
}
// Log encoded packet size
// log.Printf("Encoded audio packet size: %d", n)
// Create RTP packet
rtpPacket := &rtp.Packet{
Header: rtp.Header{
Version: 2,
PayloadType: 111, // Dynamic payload type for Opus
SequenceNumber: uint16(time.Now().UnixNano()), // Use a more appropriate sequence number generator
Timestamp: uint32(time.Now().UnixNano() / int64(time.Millisecond)),
SSRC: 12345,
},
Payload: packet[:n],
}
// Marshal RTP packet to bytes
rawPacket, err := rtpPacket.Marshal()
if err != nil {
log.Printf("Error marshaling RTP packet: %s", err)
return
}
// Log RTP packet details
// log.Printf("RTP packet details: %v", rtpPacket.Header)
// Send RTP packet over WebRTC track
if err := outboundAudioTrack.WriteRTP(rtpPacket); err != nil {
log.Printf("Error writing RTP packet to track: %s", err)
} else {
log.Printf("RTP packet sent: %d bytes", len(rawPacket))
}
}
The issue is that the audio is not being heard on the other end of the WebRTC connection, even though the audio track is being received correctly. On the receiving end (using JavaScript and HTML), I mostly hear silence with occasional brief noises that occur at regular intervals. These noises do not appear when the connection is not established. This suggests that data is being sent but may be improperly encoded or not following an appropriate bitrate.
Does anyone have any ideas on how to resolve this issue?
Thank you!
Read more here: Source link