pion / webrtc

Pure Go implementation of the WebRTC API
https://pion.ly
MIT License
13.75k stars 1.66k forks source link

Decoding Audio Track #1996

Open edwardsPaul421 opened 3 years ago

edwardsPaul421 commented 3 years ago

Summary

Hello, I'm trying to write the audio I receive to PulseAudio Source-Output using Pulseaudio Simple API . Therefore, I need to decode my track from OPUS to PCM format. I'm using hraban opus lib to decode the Payload of the track. I get the decoded payload in PCM format in a int16[]. But, in order to write it to my pa source I need to write []byte. I'm doing the conversion like that : binary.Write(stream, binary.LittleEndian, pcm). However, when I play the audio I have a bit of "metalic voice" and cuts. The problem is when writing the track using oggwriter, It works fine.

ashellunts commented 3 years ago

Hi @edwardsPaul421 , if you can provide minimal reproducer, I can try to help you.

Sean-Der commented 2 years ago

Hey @edwardsPaul421

Anything me or @ashellunts can do? Happy to leave this open for a couple more days :)

This could be a great repo for you to share in https://github.com/pion/awesome-pion could help out others.

thanks

edwardsPaul421 commented 2 years ago

Hey @edwardsPaul421

Anything me or @ashellunts can do? Happy to leave this open for a couple more days :)

This could be a great repo for you to share in https://github.com/pion/awesome-pion could help out others.

thanks

Hi @Sean-Der @ashellunts sorry for the late reply. I'm trying to decode RTP Packet's Payload (Which in format of OPUS) to PCM (Raw). I'm using hraban opus lib to decode the Payload of the track, as mentioned above. I'm also using mediadevices/opus lib to create codec like this:

    opusParams, err := opus.NewParams()
    if err != nil {
        panic(err)
    }
    codecSelector := mediadevices.NewCodecSelector(
        mediadevices.WithAudioEncoders(&opusParams),
    )

    mediaEngine := webrtc.MediaEngine{}
    codecSelector.Populate(&mediaEngine)
    api := webrtc.NewAPI(webrtc.WithMediaEngine(&mediaEngine))
    peerConnection, err := api.NewPeerConnection(config)
    if err != nil {
        panic(err)
    }

The problem is that both libs are defining the following C function:

int bridge_encoder_set_bitrate(OpusEncoder *e, opus_int32 bitrate)
{
    return opus_encoder_ctl(e, OPUS_SET_BITRATE(bitrate));
}

Therefore, I get a double definition error.

I've tried to avoid using mediadevices to create the Opus decode and to use the following code I saw here in one of the examples:

        m := &webrtc.MediaEngine{}
    if err := m.RegisterCodec(webrtc.RTPCodecParameters{
        RTPCodecCapability: webrtc.RTPCodecCapability{MimeType: webrtc.MimeTypeOpus, ClockRate: 48000, Channels: 0, SDPFmtpLine: "", RTCPFeedback: nil},
        PayloadType:        111,
    }, webrtc.RTPCodecTypeAudio); err != nil {
        panic(err)
    }

But the program just dont work after I send the sdp.

brotherdang commented 2 years ago

@edwardsPaul421 Have you solve the problem ?? I have the same problem.