<!-- review: finished -->

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

# MP4

该模块为 MP4 文件提供伪流媒体的服务器端支持。这类文件通常具有 .mp4、.m4v 或 .m4a 文件扩展名。

伪流媒体与兼容的媒体播放器协同工作。播放器向服务器发送一个 HTTP 请求，请求中指定查询字符串参数的开始时间（简单命名为 start，单位为秒），服务器则回应以使其起始位置对应于请求的时间，例如：

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

这允许在任意时间进行随机寻址，或从时间轴中间开始播放。

为了支持寻址，基于 H.264 的格式在所谓的 "moov atom" 中存储元数据。它是文件的一部分，包含整个文件的索引信息。

为了开始播放，播放器首先需要读取元数据。这是通过发送一个带有 `start=0` 参数的特殊请求来完成的。许多编码软件将元数据插入到文件的末尾。这对于伪流媒体来说是不理想的，因为播放器必须在开始播放之前下载整个文件。如果元数据位于文件的开头，对于 Angie 来说，只需开始发送文件内容即可。如果元数据位于文件的末尾，Angie 必须读取整个文件并准备一个新的流，以便元数据在媒体数据之前。这涉及一些 CPU、内存和磁盘 I/O 的开销，因此最好提前 [准备](https://github.com/flowplayer/flowplayer/wiki/7.1.1-video-file-correction) 原始文件以进行伪流媒体，而不是让 Angie 在每个这样的请求上都执行此操作。

该模块还支持 HTTP 请求的 `end` 参数，该参数设置播放的结束点。`end` 参数可以与 start 参数一起指定，也可以单独指定：

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

对于包含非零 `start` 或 `end` 参数的匹配请求，Angie 将从文件中读取元数据，准备请求时间范围的流，并将其发送给客户端。这与上述描述的开销相同。

如果 `start` 参数指向非关键视频帧，则视频的开头将会损坏。为了解决此问题，视频 [可以](#mp4-start-key-frame) 在 `start` 点之前添加关键帧以及它们之间的所有中间帧。这些帧将通过编辑列表从播放中隐藏。

如果匹配请求不包含 `start` 和 `end` 参数，则没有开销，文件将简单地作为静态资源发送。一些播放器也支持字节范围请求，因此不需要此模块。

当 [从源代码构建](https://cn.angie.software//angie/docs/installation/sourcebuild.md#sourcebuild) 时，该模块默认并不构建；应通过 `‑‑with‑http_mp4_module` [构建选项](https://cn.angie.software//angie/docs/installation/sourcebuild.md#configure) 启用它。在来自 [我们的仓库](https://cn.angie.software//angie/docs/installation/index.md#install-packages) 的软件包和镜像中，该模块已包含在构建中。

#### WARNING
如果之前使用了第三方的 `mp4` 模块，则应将其禁用。

对于 FLV 文件，提供了类似的伪流媒体支持：[FLV](https://cn.angie.software//angie/docs/configuration/modules/http/http_flv.md#http-flv) 模块。

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

## 配置示例

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

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

## 指令

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

<a id="id4"></a>

### mp4

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4`;   |
|--------------------------------------------------------------------------------------|----------|
| 默认                                                                                   | —        |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | location |

在周围位置启用模块处理。

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

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

### mp4_buffer_size

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_buffer_size` size;   |
|--------------------------------------------------------------------------------------|---------------------------|
| 默认                                                                                   | `mp4_buffer_size 512K;`   |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location    |

设置用于处理 MP4 文件的缓冲区的初始大小。

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

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

### mp4_max_buffer_size

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_max_buffer_size` size;   |
|--------------------------------------------------------------------------------------|-------------------------------|
| 默认                                                                                   | `mp4_max_buffer_size 10M;`    |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location        |

在元数据处理期间，可能需要更大的缓冲区。其大小不得超过指定大小，否则 Angie 将返回 500（内部服务器错误）服务器错误，并记录以下消息：

> "/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

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_limit_rate` `on` | `off` | factor;   |
|--------------------------------------------------------------------------------------|-------------------------------------------|
| 默认                                                                                   | `mp4_limit_rate off;`                     |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location                    |

对请求的 MP4 文件向客户端的传输进行速率限制。要计算限制，将 factor 乘以文件的平均比特率。

- `off` 值禁用速率限制。
- `on` 值设置 factor 为 `1.1`。
- 限制在达到由 [mp4_limit_rate_after](#mp4-limit-rate-after) 设置的值后应用。

请求是单独进行速率限制的：如果客户端打开两个连接，结果速率翻倍。因此，考虑使用 [limit_conn](https://cn.angie.software//angie/docs/configuration/modules/http/http_api.md#limit-conn) 和相关指令。

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

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

### mp4_limit_rate_after

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_limit_rate_after` time;   |
|--------------------------------------------------------------------------------------|--------------------------------|
| 默认                                                                                   | `mp4_limit_rate_after 60s;`    |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location         |

设置（以 [播放时间](https://cn.angie.software//angie/docs/configuration/configfile.md#syntax) 为单位）传输的媒体数据量，达到该数据量后触发由 [mp4_limit_rate](#mp4-limit-rate) 设置的速率限制。

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

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

### mp4_start_key_frame

| [语法](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)   | `mp4_start_key_frame` `on` | `off`;   |
|--------------------------------------------------------------------------------------|---------------------------------------|
| 默认                                                                                   | `mp4_start_key_frame off;`            |
| [上下文](https://cn.angie.software//angie/docs/configuration/configfile.md#configfile)  | http, server, location                |

强制输出视频始终以关键视频帧开始。如果 start 参数不指向关键帧，则初始帧将通过 mp4 编辑列表隐藏。编辑列表受到主要播放器和浏览器的支持，如 Chrome、Safari、QuickTime 和 ffmpeg，Firefox 部分支持。
