<!-- review: finished -->

<a id="http-mp4"></a>

# MP4

The module provides pseudo-streaming server-side support for MP4 files. Such
files typically have the .mp4, .m4v, or .m4a filename extensions.

Pseudo-streaming works in alliance with a compatible media player. The player
sends an HTTP request to the server with the start time specified in the query
string argument (named simply start and specified in seconds), and the server
responds with the stream such that its start position corresponds to the
requested time, for example:

```none
http://example.com/elephants_dream.mp4?start=238.88
```

This allows performing a random seeking at any time, or starting playback in the
middle of the timeline.

To support seeking, H.264-based formats store metadata in a so-called "moov
atom". It is a part of the file that holds the index information for the whole
file.

To start playback, the player first needs to read metadata. This is done by
sending a special request with the `start=0` argument. A lot of encoding
software insert the metadata at the end of the file. This is suboptimal for
pseudo-streaming, because the player has to download the entire file before
starting playback. If the metadata are located at the beginning of the file, it
is enough for Angie to simply start sending back the file contents. If the
metadata are located at the end of the file, Angie must read the entire file and
prepare a new stream so that the metadata come before the media data. This
involves some CPU, memory, and disk I/O overhead, so it is a good idea to
[prepare](https://github.com/flowplayer/flowplayer/wiki/7.1.1-video-file-correction) an
original file for pseudo-streaming in advance, rather than having Angie do this
on every such request.

The module also supports the `end` argument of an HTTP request which sets
the end point of playback. The `end` argument can be specified with the
start argument or separately:

```none
http://example.com/elephants_dream.mp4?start=238.88&end=555.55
```

For a matching request with a non-zero `start` or `end` argument,
Angie will read the metadata from the file, prepare the stream with the
requested time range, and send it to the client. This has the same overhead as
described above.

If the `start` argument points to a non-key video frame, the beginning of
such video will be broken. To fix this issue, the video [can](#mp4-start-key-frame) be prepended with the key frame before `start`
point and with all intermediate frames between them. These frames will be hidden
from playback using an edit list.

If a matching request does not include the `start` and `end`
arguments, there is no overhead, and the file is sent simply as a static
resource. Some players also support byte-range requests, and thus do not require
this module.

When [building from the source code](https://en.angie.software//angie/docs/installation/sourcebuild.md#sourcebuild),
this module isn't built by default;
it should be enabled with the
`‑‑with‑http_mp4_module`
[build option](https://en.angie.software//angie/docs/installation/sourcebuild.md#configure).
In packages and images from [our repos](https://en.angie.software//angie/docs/installation/index.md#install-packages), the module is
included in the build.

#### WARNING
If a third-party `mp4` module was previously used, it should be disabled.

A similar pseudo-streaming support for FLV files is provided by the [FLV](https://en.angie.software//angie/docs/configuration/modules/http/http_flv.md#http-flv) module.

<a id="configuration-example-31"></a>

## Configuration Example

```nginx
location /video/ {
    mp4;
    mp4_buffer_size     1m;
    mp4_max_buffer_size 5m;
}
```

<a id="directives-32"></a>

## Directives

<a id="index-0"></a>

<a id="id1"></a>

### mp4

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4`;   |
|------------------------------------------------------------------------------------------|----------|
| Default                                                                                  | —        |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | location |

Turns on module processing in a surrounding location.

<a id="index-1"></a>

<a id="mp4-buffer-size"></a>

### mp4_buffer_size

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_buffer_size` size;   |
|------------------------------------------------------------------------------------------|---------------------------|
| Default                                                                                  | `mp4_buffer_size 512K;`   |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location    |

Sets the initial size of the buffer used for processing MP4 files.

<a id="index-2"></a>

<a id="mp4-max-buffer-size"></a>

### mp4_max_buffer_size

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_max_buffer_size` size;   |
|------------------------------------------------------------------------------------------|-------------------------------|
| Default                                                                                  | `mp4_max_buffer_size 10M;`    |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location        |

During metadata processing, a larger buffer may become necessary. Its size cannot exceed the specified size, or else Angie will return the 500 (Internal Server Error) server error, and log the following message:

> "/some/movie/file.mp4" mp4 moov atom is too large:
> 12583268, you may want to increase mp4_max_buffer_size

<a id="index-3"></a>

<a id="mp4-limit-rate"></a>

### mp4_limit_rate

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_limit_rate` `on` | `off` | factor;   |
|------------------------------------------------------------------------------------------|-------------------------------------------|
| Default                                                                                  | `mp4_limit_rate off;`                     |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location                    |

Rate-limits the transfer of the requested MP4 file to the client.
To calculate the limit, the factor is multiplied
by the average bitrate of the file.

- The `off` value disables rate limiting.
- The `on` value sets a factor of `1.1`.
- The limit is applied after reaching the value set by
  [mp4_limit_rate_after](#mp4-limit-rate-after).

The requests are rate limited individually:
if the client opens two connections,
the resulting rate doubles.
In this regard, consider using [limit_conn](https://en.angie.software//angie/docs/configuration/modules/http/http_api.md#limit-conn) and accompanying directives.

<a id="index-4"></a>

<a id="mp4-limit-rate-after"></a>

### mp4_limit_rate_after

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_limit_rate_after` time;   |
|------------------------------------------------------------------------------------------|--------------------------------|
| Default                                                                                  | `mp4_limit_rate_after 60s;`    |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location         |

Sets
(in terms of
[playback time](https://en.angie.software//angie/docs/configuration/configfile.md#syntax))
the amount of media data transferred
that triggers
the rate limit set by
[mp4_limit_rate](#mp4-limit-rate).

<a id="index-5"></a>

<a id="mp4-start-key-frame"></a>

### mp4_start_key_frame

| [Syntax](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_start_key_frame` `on` | `off`;   |
|------------------------------------------------------------------------------------------|---------------------------------------|
| Default                                                                                  | `mp4_start_key_frame off;`            |
| [Context](https://en.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location                |

Forces output video to always start with a key video frame. If the start argument does not point to a key frame, initial frames are hidden using an mp4 edit list. Edit lists are supported by major players and browsers such as Chrome, Safari, QuickTime and ffmpeg, partially supported by Firefox.
