# `RTMP.Frame`
[🔗](https://github.com/Adeyeye93/rtmp/blob/v0.1.0/lib/rtmp/frame.ex#L1)

One audio or video frame, as delivered to `c:RTMP.Handler.handle_frame/2`.

## Fields

  * `:type` — `:audio` or `:video`.
  * `:codec` — `:aac` or `:h264` (parsed), or the FLV codec of a frame
    passed through unparsed (`:mp3`, `:speex`, `:vp6`, ...), or
    `{:unknown, id}`.
  * `:dts` — decode timestamp in milliseconds: the RTMP message timestamp.
    32-bit, wraps after about 49.7 days.
  * `:cts` — composition time offset in milliseconds (video only; `0` for
    audio). The presentation timestamp is `dts + cts` — see `pts/1`.
  * `:keyframe?` — video keyframe. Always `false` for audio.
  * `:sequence_header?` — this frame is decoder configuration, not media:
    an AAC AudioSpecificConfig or an H.264 AVCDecoderConfigurationRecord.
    Encoders send one before the first media frame and again if the
    configuration changes.
  * `:parsed?` — whether the codec payload was parsed. `false` for codecs
    that are passed through as-is.
  * `:data` — the codec payload with the FLV tag header stripped:
    * AAC sequence header: the AudioSpecificConfig bytes.
    * AAC frame: one raw AAC frame (no ADTS header).
    * H.264 sequence header: the AVCDecoderConfigurationRecord bytes.
    * H.264 frame: length-prefixed (AVCC) NAL units.
    * Unparsed codecs: everything after the first FLV tag byte.
  * `:config` — for sequence headers, the parsed configuration
    (see `RTMP.FLV.AudioTag` and `RTMP.FLV.VideoTag`). For unparsed audio,
    the FLV header's rate/size/channel fields. Otherwise `nil`.
  * `:nalus` — H.264 frames only: the NAL units split out of `:data`,
    without their length prefixes. `nil` otherwise.
  * `:stream_id` — the RTMP message stream id the frame arrived on.
  * `:payload` — the complete RTMP message payload, which is exactly an
    FLV tag body. Write this verbatim when remuxing to FLV.

Binary fields are sub-binaries of the received message, so carrying both
`:payload` and `:data` (and `:nalus`) costs no extra copies.

# `codec`

```elixir
@type codec() ::
  :aac
  | :h264
  | :pcm
  | :pcm_le
  | :adpcm
  | :mp3
  | :mp3_8khz
  | :nellymoser
  | :nellymoser_8khz
  | :nellymoser_16khz
  | :g711_alaw
  | :g711_mulaw
  | :speex
  | :device_specific
  | :jpeg
  | :sorenson_h263
  | :screen_video
  | :screen_video_v2
  | :vp6
  | :vp6_alpha
  | {:unknown, non_neg_integer()}
```

# `t`

```elixir
@type t() :: %RTMP.Frame{
  codec: codec(),
  config: map() | nil,
  cts: integer(),
  data: binary(),
  dts: non_neg_integer(),
  keyframe?: boolean(),
  nalus: [binary()] | nil,
  parsed?: boolean(),
  payload: binary(),
  sequence_header?: boolean(),
  stream_id: non_neg_integer(),
  type: :audio | :video
}
```

# `pts`

```elixir
@spec pts(t()) :: integer()
```

Presentation timestamp in milliseconds: `dts + cts`.

---

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