> ## Documentation Index
> Fetch the complete documentation index at: https://mintlify.com/bluenviron/gortsplib/llms.txt
> Use this file to discover all available pages before exploring further.

# Audio formats

> Opus, MPEG-4 Audio (AAC), G711, G722, LPCM, AC-3, Speex, and more.

## Supported audio formats

| Struct | Codec | Payload type | RFC / spec | Encoder | Decoder |
| - | - | - | - | - | - |
| `format.Opus` | Opus / MultiOpus | dynamic (96–127) | RFC 7587 | Yes | Yes |
| `format.MPEG4Audio` | MPEG-4 Audio (AAC-HBR) | dynamic (96–127) | RFC 3640 | Yes | Yes |
| `format.MPEG4AudioLATM` | MPEG-4 Audio LATM | dynamic (96–127) | RFC 3016 | Yes | Yes |
| `format.G711` | G.711 PCMU / PCMA | 0 (PCMU), 8 (PCMA), or dynamic | RFC 3551 | Yes | Yes |
| `format.G722` | G.722 | 9 (static) | RFC 3551 | Yes | Yes |
| `format.LPCM` | Linear PCM (L8/L16/L24) | 10, 11 (static) or dynamic | RFC 3190, RFC 3551 | Yes | Yes |
| `format.AC3` | AC-3 (Dolby Digital) | dynamic (96–127) | RFC 4184 | Yes | Yes |
| `format.MPEG1Audio` | MPEG-1/2 Audio | 14 (static) | RFC 2250 | Yes | Yes |
| `format.Speex` | Speex | dynamic (96–127) | RFC 5574 | No | No |
| `format.Vorbis` | Vorbis | dynamic (96–127) | RFC 5215 | No | No |
| `format.G726` | G.726 | dynamic (96–127) | RFC 3551 | No | No |

***

<AccordionGroup>
  <Accordion title="Opus">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 7587

    ### Struct fields

    ```go theme={null}
    type Opus struct {
        // RTP payload type (96–127).
        PayloadTyp uint8

        // Number of audio channels (1 = mono, 2 = stereo).
        // Determined from the sprop-stereo fmtp parameter.
        ChannelCount int
    }
    ```

    ### Playback example

    ```go theme={null}
    // find the Opus media and format
    var forma *format.Opus
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    // create decoder
    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    // called when a RTP packet arrives
    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            log.Printf("waiting for timestamp")
            return
        }

        // extract Opus packets from RTP packets
        op, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        log.Printf("received Opus packet with PTS %v size %d", pts, len(op))
    })
    ```
  </Accordion>

  <Accordion title="MPEG-4 Audio (AAC)">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 3640

    ### Struct fields

    ```go theme={null}
    type MPEG4Audio struct {
        // RTP payload type (96–127).
        PayloadTyp uint8

        ProfileLevelID   int

        // Parsed AudioSpecificConfig from the config fmtp parameter.
        // Contains sample rate, channel count, and codec profile.
        Config           *mpeg4audio.AudioSpecificConfig

        SizeLength       int
        IndexLength      int
        IndexDeltaLength int
    }
    ```

    ### Playback example

    ```go theme={null}
    // find the MPEG-4 audio media and format
    var forma *format.MPEG4Audio
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    // create decoder
    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    // called when a RTP packet arrives
    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            log.Printf("waiting for timestamp")
            return
        }

        // extract access units from RTP packets
        aus, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        // one RTP packet may contain multiple access units
        for _, au := range aus {
            log.Printf("received access unit with PTS %v size %d", pts, len(au))
        }
    })
    ```

    <Tip>
      The `forma.Config` field contains the parsed `AudioSpecificConfig`, including `SampleRate` and `ChannelCount`. Check this before configuring any downstream AAC decoder.
    </Tip>
  </Accordion>

  <Accordion title="G711 (PCMU / PCMA)">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 3551

    ### Struct fields

    ```go theme={null}
    type G711 struct {
        // RTP payload type.
        // Static: 0 (PCMU) or 8 (PCMA). Dynamic: 96–127.
        PayloadTyp uint8

        // MULaw selects mu-law encoding (PCMU). False selects A-law (PCMA).
        MULaw bool

        // Sample rate in Hz. Typically 8000.
        SampleRate int

        // Number of audio channels.
        ChannelCount int
    }
    ```

    ### Usage

    The standard static payload types (0 = PCMU, 8 = PCMA) are detected automatically from the SDP. Dynamic payload types support non-standard sample rates.

    ```go theme={null}
    // declare a PCMU stream for recording
    forma := &format.G711{
        MULaw:        true, // PCMU
        SampleRate:   8000,
        ChannelCount: 1,
    }

    // — or detect while playing back —

    var forma *format.G711
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            return
        }

        samples, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        log.Printf("received G711 samples with PTS %v, size %d", pts, len(samples))
    })
    ```
  </Accordion>

  <Accordion title="LPCM">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 3190, RFC 3551

    ### Struct fields

    ```go theme={null}
    type LPCM struct {
        // RTP payload type.
        // Static: 10 (L16 stereo 44100 Hz) or 11 (L16 mono 44100 Hz).
        // Dynamic: 96–127 for L8, L16, or L24 at other rates.
        PayloadTyp uint8

        // Bit depth: 8, 16, or 24.
        BitDepth int

        // Sample rate in Hz.
        SampleRate int

        // Number of audio channels.
        ChannelCount int
    }
    ```

    ### Usage

    ```go theme={null}
    // declare a 16-bit stereo 44100 Hz LPCM stream
    forma := &format.LPCM{
        PayloadTyp:   96,
        BitDepth:     16,
        SampleRate:   44100,
        ChannelCount: 2,
    }

    // — or detect while playing back —

    var forma *format.LPCM
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            return
        }

        samples, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        log.Printf("received LPCM samples with PTS %v, size %d", pts, len(samples))
    })
    ```
  </Accordion>

  <Accordion title="AC-3">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 4184

    ### Struct fields

    ```go theme={null}
    type AC3 struct {
        // RTP payload type (96–127).
        PayloadTyp uint8

        // Sample rate in Hz.
        SampleRate int

        // Number of audio channels. Defaults to 6 if omitted in SDP.
        ChannelCount int
    }
    ```

    ### Usage

    ```go theme={null}
    var forma *format.AC3
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            return
        }

        frame, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        log.Printf("received AC-3 frame with PTS %v, size %d", pts, len(frame))
    })
    ```
  </Accordion>

  <Accordion title="G722">
    **Package path:** `github.com/bluenviron/gortsplib/v5/pkg/format`

    **Specification:** RFC 3551

    **Static payload type:** 9

    ### Struct fields

    ```go theme={null}
    // G722 has no configurable fields — payload type 9 is fixed by RFC 3551.
    type G722 struct{}
    ```

    ### Usage

    ```go theme={null}
    var forma *format.G722
    medi := desc.FindFormat(&forma)
    if medi == nil {
        panic("media not found")
    }

    rtpDec, err := forma.CreateDecoder()
    if err != nil {
        panic(err)
    }

    _, err = c.Setup(desc.BaseURL, medi, 0, 0)
    if err != nil {
        panic(err)
    }

    c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
        pts, ok := c.PacketPTS(medi, pkt)
        if !ok {
            return
        }

        samples, err := rtpDec.Decode(pkt)
        if err != nil {
            log.Printf("ERR: %v", err)
            return
        }

        log.Printf("received G722 samples with PTS %v, size %d", pts, len(samples))
    })
    ```
  </Accordion>
</AccordionGroup>

## Formats without built-in encoder/decoder

<Note>
  The following formats are recognized and parsed from SDP, but do not provide `CreateEncoder()` or `CreateDecoder()` methods. You must supply your own RTP packetizer and depacketizer.
</Note>

| Struct | Codec | Payload type | RFC |
| - | - | - | - |
| `format.Speex` | Speex | dynamic (96–127) | RFC 5574 |
| `format.Vorbis` | Vorbis | dynamic (96–127) | RFC 5215 |
| `format.G726` | G.726 | dynamic (96–127) | RFC 3551 |

For these formats you can still receive raw RTP packets via `OnPacketRTP` and implement your own framing logic:

```go theme={null}
var forma *format.Speex
medi := desc.FindFormat(&forma)
if medi == nil {
    panic("media not found")
}

_, err = c.Setup(desc.BaseURL, medi, 0, 0)
if err != nil {
    panic(err)
}

c.OnPacketRTP(medi, forma, func(pkt *rtp.Packet) {
    // pkt.Payload contains the raw Speex payload — apply your own depacketizer
    log.Printf("received raw Speex packet, payload size %d", len(pkt.Payload))
})
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.