# eflvmux

`eflvmux` is an extension to the `flvmux`, capable of multiplexing multiple tracks and signalling advanced codecs in FOURCC format as per Enhanced RTMP (V2) specification.

Two types of sink pads can be requested from `eflvmux`

1. `audio`/`video` - for create a default track and can be used to stream in the legacy or extended FLV format. The format can be selected using the `flv-track-mode` pad property. See flv-track-mode

2. `audio_%u`/`video_%u` - for creating multiple tracks in extended FLV format of multitrack type, each with a unique non-zero track ID. The track ID will be same as the pad index.

It is important to specify the right pad template (preferably with specific pad index in case of `_%u` type pads) while linking pads using `gst_element_link_pads` or `_parse_launch`. Failing to specify the pad template can result streaming in the wrong FLV format.

Note: Since we use pad index as the track id and a track with id 0 can be created only through the `audio`/`video` pads, requesting a `audio_0` or `video_0` is not allowed.

## Example launch line saving 2 audio and 2 video tracks to a FLV file

    gst-launch-1.0 eflvmux name=mux audio::flv-track-mode=multitrack video::flv-track-mode=non-multitrack  ! filesink location=$HOME/Videos/test_eflv_non.flv \
       audiotestsrc  wave=ticks ! audio/x-raw,rate=44100,format=S16LE,channels=2 ! fdkaacenc ! mux.audio \
       audiotestsrc  wave=white-noise  ! audio/x-raw,rate=44100,format=S16LE,channels=2 !  fdkaacenc ! mux.audio_2  \
       videotestsrc ! videoconvert ! timeoverlay ! x264enc tune=zerolatency key-int-max=30 ! h264parse ! mux.video   \
       videotestsrc ! videoconvert ! timeoverlay ! x265enc ! h265parse ! mux.video_2

The pipeline creates - the default audio track from the `audio` pad in multitrack eFLV format with track id 0 - additional audio track from the `audio_1` pad in the multitrack eFLV format with track id 1 - the default video track from the `video` pad in non-mulitrack eFLV format so it won't have any track id - additional video track from the `video_1` pad in the multitrack eFLV format with track id 1

## To play the above file using `ffplay` (FFmpeg version 8 or greater)

`ffplay $HOME/Videos/test_eflv_non.flv`

(switch the video tracks using `v` and audio tracks with `a` keys)

## Example launch line for streaming 2 audio tracks to Twitch

    gst-launch-1.0 videotestsrc pattern=ball ! 'video/x-raw,format=I420,width=1280,height=720,framerate=30/1' ! \
       timeoverlay ! videoconvert ! x264enc tune=zerolatency key-int-max=30 ! h264parse ! eflvmux name=mux ! \
       rtmp2sink location="rtmp://ingest.global-contribute.live-video.net/app/$STREAM_KEY" \
       audiotestsrc wave=ticks ! fdkaacenc ! mux.audio \
       audiotestsrc !  fdkaacenc ! mux.audio_1

## Hierarchy

    GObject
        ╰──GInitiallyUnowned
            ╰──GstObject
                ╰──GstElement
                    ╰──GstAggregator
                        ╰──GstFlvMux
                            ╰──eflvmux

## Implemented interfaces

    GstChildProxy
    GstTagSetter

## Factory details

Authors: – Taruntej Kanakamalla

Classification: – `Codec/Muxer`

Rank – primary

Plugin – flv

Package – GStreamer Good Plug-ins

## Pad Templates

### `audio`

    audio/x-adpcm:
             layout: swf
           channels: { (int)1, (int)2 }
               rate: { (int)5512, (int)11025, (int)22050, (int)44100 }
    audio/mpeg:
        mpegversion: 1
              layer: 3
           channels: { (int)1, (int)2 }
               rate: { (int)5512, (int)8000, (int)11025, (int)22050, (int)44100 }
             parsed: true
    audio/mpeg:
        mpegversion: { (int)4, (int)2 }
      stream-format: raw
    audio/x-nellymoser:
           channels: { (int)1, (int)2 }
               rate: { (int)5512, (int)8000, (int)11025, (int)16000, (int)22050, (int)44100 }
    audio/x-raw:
             format: { U8, S16LE }
             layout: interleaved
           channels: { (int)1, (int)2 }
               rate: { (int)5512, (int)11025, (int)22050, (int)44100 }
    audio/x-alaw:
           channels: { (int)1, (int)2 }
               rate: 8000
    audio/x-mulaw:
           channels: { (int)1, (int)2 }
               rate: 8000
    audio/x-speex:
           channels: 1
               rate: 16000

Presence – request

Direction – sink

Object type – GstEFlvMuxPad

### `audio_%u`

    audio/mpeg:
        mpegversion: 1
              layer: 3
           channels: { (int)1, (int)2 }
               rate: { (int)5512, (int)8000, (int)11025, (int)22050, (int)44100 }
             parsed: true
    audio/mpeg:
        mpegversion: { (int)4, (int)2 }
      stream-format: raw

Presence – request

Direction – sink

Object type – GstFlvMuxPad

### `src`

    video/x-flv:

Presence – always

Direction – src

Object type – GstAggregatorPad

### `video`

    video/x-flash-video:
    video/x-flash-screen:
    video/x-vp6-flash:
    video/x-vp6-alpha:
    video/x-h264:
      stream-format: avc
    video/x-h265:
      stream-format: hvc1
          alignment: au
    video/x-av1:
      stream-format: obu-stream
          alignment: tu

Presence – request

Direction – sink

Object type – GstEFlvMuxPad

### `video_%u`

    video/x-h264:
      stream-format: avc
    video/x-h265:
      stream-format: hvc1
    video/x-av1:
      stream-format: obu-stream
          alignment: tu

Presence – request

Direction – sink

Object type – GstFlvMuxPad

The results of the search are