以下对ngx_http_mp4_file_t的结构定义进行说明:
typedef struct {
ngx\_file\_t file; # mp4文件对象
u_char \*buffer; # 用于mp4分析的缓冲区
u_char \*buffer_start; # buffer空闲的起始位置
u_char \*buffer_pos; # buffer中可用于分析的起始位置
u_char \*buffer_end; # buffer中可用于分析的结束位置
size\_t buffer_size; # mp4分析缓冲区buffer的大小
off\_t offset; # buffer_start对应的mp4文件读取的偏移量
off\_t end; # 当前mp4文件的文件大小
off\_t content_length; # 最终发送给客户端响应的内容长度
ngx\_uint\_t start; # 请求的起始偏移时间
ngx\_uint\_t length; # 请求的视频时长
uint32\_t timescale; # mp4文件中设置的时间scale值
ngx\_http\_request\_t \*request; # 对应当前的http request对象
ngx\_array\_t trak; # mp4包含的track列表,引用traks,最多2个
ngx\_http\_mp4\_trak\_t traks[2]; # mp4包含的track列表
size\_t ftyp_size; # ftyp atom的大小
size\_t moov_size; # moov atom的大小
ngx\_chain\_t \*out;
ngx\_chain\_t ftyp_atom; # 链接了ftyp_atom_buf的缓冲区链
ngx\_chain\_t moov_atom; # 链接了moov_atom_buf的缓冲区链
ngx\_chain\_t mvhd_atom; # 链接了mvhd_atom_buf的缓冲区链
ngx\_chain\_t mdat_atom; # 链接了mdat_atom_buf的缓冲区链
ngx\_chain\_t mdat_data; # 链接了mdat_data_buf的缓冲区链
ngx\_buf\_t ftyp_atom_buf; # ftyp atom的缓冲区
ngx\_buf\_t moov_atom_buf; # moov atom的缓冲区
ngx\_buf\_t mvhd_atom_buf; # mvhd atom的缓冲区
ngx\_buf\_t mdat_atom_buf; # mdat atom的缓冲区
ngx\_buf\_t mdat_data_buf; # mdat atom的缓冲区
u_char moov_atom_header[8];
u_char mdat_atom_header[16];
} ngx\_http\_mp4\_file\_t;
3.2.4 MP4文件的发送
其实现源码如下,源码里面进行了详细的备注说明:
log->action = "sending mp4 to client";
/\* 如果需要,开启directio \*/
if (clcf->directio <= of.size) {
/\*
\* DIRECTIO is set on transfer only
\* to allow kernel to cache "moov" atom
\*/
if (ngx\_directio\_on(of.fd) == NGX_FILE_ERROR) {
ngx\_log\_error(NGX_LOG_ALERT, log, ngx_errno,
ngx_directio_on_n " \"%s\" failed", path.data);
}
of.is_directio = 1;
if (mp4) {
mp4->file.directio = 1;
}
}
/\* 设置响应状态和相关响应头信息,然后将响应头发送给用户 \*/
r->headers_out.status = NGX_HTTP_OK;
r->headers_out.last_modified_time = of.mtime;
if (ngx\_http\_set\_etag(r) != NGX_OK) {
return NGX_HTTP_INTERNAL_SERVER_ERROR;
}