# `Membrane.MP4.Demuxer.ISOM`
[🔗](https://github.com/membraneframework/membrane_mp4_plugin/blob/v0.36.11/lib/membrane_mp4/demuxer/isom.ex#L1)

A Membrane Element for demuxing an MP4.

The MP4 must have `fast start` enabled, i.e. the `moov` box must precede the `mdat` box.
Once the Demuxer identifies the tracks in the MP4, `t:new_tracks_t/0` notification is sent for each of the tracks.

All pads has to be linked either before `handle_playing/2` callback or after the Element sends `{:new_tracks, ...}`
notification.

Number of pads has to be equal to the number of demuxed tracks.

If the demuxed data contains only one track, linked pad doesn't have to specify `:kind` option.

If there are more than one track and pads are linked before `handle_playing/2`, every pad has to specify `:kind`
option.

If any of pads isn't linked before `handle_playing/2`, Membrane.MP4.Demuxer.ISOM will send `{:new_tracks, ...}`
notification to the parent. Otherwise, if any of them is linked before `handle_playing/3`, this notification won't
be sent.

If pads are linked after the `{:new_tracks, ...}` notfitaction, their references must match MP4 tracks ids
(`Pad.ref(:output, track_id)`).

## Element options

Passed via struct `t:Membrane.MP4.Demuxer.ISOM.t/0`

- `optimize_for_non_fast_start?`  

  ```
  boolean()
  ```
  
  Default value: `false`  
  When set to `true`, the demuxer is optimized for working with non-fast_start MP4
  stream (that means - with a stream, in which the :moov box is put after the :mdat box)
  You might consider setting that option to `true` if the following two conditions are met:
  - you are processing large non-fast_start MP4 files
  - the source of the stream is a "seekable source" - currently the only possible
  option is to use a `Membrane.File.Source` with `seekable?: true` option.
  
  When set to `false`, no optimization will be performed, so in case of processing the
  non-fast_start MP4 stream, the whole content of the :mdat box will be stored in
  memory.
  
  Defaults to `false`.

## Pads

### `:input`

Accepted formats:
```
%RemoteStream{type: :bytestream, content_format: content_format} when content_format in [nil, MP4]
```

Direction: | `:input`
Availability: | `:always`
Flow control: | `:auto`

### `:output`

Accepted formats:
```
%Membrane.AAC{config: {:esds, _esds}}
```
```
%Membrane.H264{stream_structure: {_avc, _dcr}, alignment: :au}
```
```
%Membrane.H265{stream_structure: {_hevc, _dcr}, alignment: :au}
```
```
%Membrane.Opus{self_delimiting?: false}
```
```
%Membrane.AV1{alignment: :tu}
```

Direction: | `:output`
Availability: | `:on_request`
Flow control: | `:auto`
Pad options:

- `kind`  

  ```
  :video | :audio | nil
  ```
  
  Default value: `nil`  
  Specifies, what kind of data can be handled by a pad.

# `new_tracks_t`

```elixir
@type new_tracks_t() :: {:new_tracks, [{track_id :: integer(), content :: struct()}]}
```

Notification sent when the tracks are identified in the MP4.

Upon receiving the notification, `Pad.ref(:output, track_id)` pads should be linked
for all the `track_id` in the list.
The `content` field contains the stream format which is contained in the track.

# `output_pad_opts`

```elixir
@type output_pad_opts() :: [{:kind, :video | :audio | nil}]
```

Options for pad `:output`

# `t`

```elixir
@type t() :: %Membrane.MP4.Demuxer.ISOM{optimize_for_non_fast_start?: boolean()}
```

Struct containing options for `Membrane.MP4.Demuxer.ISOM`

# `options`

```elixir
@spec options() :: keyword()
```

Returns description of options available for this module

---

*Consult [api-reference.md](api-reference.md) for complete listing*
