ngx_rtmp_mp4_module 实现了 Nginx RTMP 模块中的 MP4 相关功能,主要用于处理 RTMP 流的 MP4 视频文件格式。这包括了从 MP4 文件中解析音视频数据,并将其转换为 RTMP 协议流的过程。
1. 模块的主要目标
该模块的目标是支持 RTMP 流媒体协议与 MP4 文件格式之间的转换。它的功能包括:
-
解析 MP4 文件头部信息。
-
从 MP4 文件中提取视频和音频轨道。
-
处理 RTMP 流中的 MP4 媒体数据,支持视频和音频的推流。
2. 数据结构和类型定义
2.1 MP4 文件的内部结构
-
ngx_rtmp_mp4_chunk_entry_t
:-
用于描述 MP4 文件中的一个数据块,包含
first_chunk
(第一个块的编号)、samples_per_chunk
(每个块中的样本数量)和sample_descrption_index
(样本描述符的索引)。
-
-
ngx_rtmp_mp4_chunks_t
:-
描述 MP4 文件中的所有数据块信息,包含多个
ngx_rtmp_mp4_chunk_entry_t
类型的条目。
-
-
ngx_rtmp_mp4_time_entry_t
和ngx_rtmp_mp4_times_t
:-
用于描述时间戳相关的条目,其中
ngx_rtmp_mp4_time_entry_t
记录每个样本的时间戳和时间增量。
-
-
ngx_rtmp_mp4_delay_entry_t
和ngx_rtmp_mp4_delays_t
:-
描述延迟信息的条目,每个条目包含样本的延迟时间和延迟的数量。
-
-
ngx_rtmp_mp4_cursor_t
:-
用于描述当前 MP4 播放的位置,包括当前的时间戳、延迟、数据块位置等信息。它帮助跟踪和控制当前数据的位置。
-
-
ngx_rtmp_mp4_track_t
:-
表示 MP4 文件中的一个音视频轨道,包含轨道的各种信息,如类型(视频或音频)、编码格式、时间戳、样本大小、偏移量等。
-
-
ngx_rtmp_mp4_ctx_t
:-
存储关于当前 MP4 文件和轨道的上下文信息,包括轨道数量、音视频信息、解析状态等。
-
3. MP4 文件解析
模块中有多个函数负责解析 MP4 文件的不同部分。每个解析函数根据 MP4 文件的结构,处理不同类型的 Box(数据块)。常见的 MP4 Box 类型有:
-
trak
(轨道信息) -
mdhd
(媒体头信息) -
hdlr
(媒体类型) -
stsd
(样本描述符) -
stsc
(样本间隔) -
stts
(时间戳信息) -
avc1
、mp4v
(视频编码类型)
3.1 解析函数
-
ngx_rtmp_mp4_parse_trak
:-
解析
trak
Box,表示一个音视频轨道。如果轨道是有效的,函数会将其信息存储在ngx_rtmp_mp4_track_t
中。
-
-
ngx_rtmp_mp4_parse_mdhd
:-
解析
mdhd
Box,主要用来获取媒体的时间尺度和持续时间。
-
-
ngx_rtmp_mp4_parse_hdlr
:-
解析
hdlr
Box,确定当前轨道是音频还是视频,并设置相关的轨道类型。
-
-
ngx_rtmp_mp4_parse_avc1
、ngx_rtmp_mp4_parse_mp4v
:-
解析视频轨道的编码信息,这里是 H.264 和 MP4 视频格式。
-
-
ngx_rtmp_mp4_parse_mp4a
:-
解析音频轨道的编码信息,如 MP3 音频格式。
-
4. 音视频数据处理
该模块会根据 MP4 文件的结构,解析音视频数据并通过 RTMP 推送。具体处理过程包括:
-
解析视频和音频的帧信息(如大小、编码格式、时间戳等)。
-
时间戳转换:由于 MP4 文件中的时间戳和 RTMP 中使用的时间戳格式不同,模块需要进行转换。
-
ngx_rtmp_mp4_to_rtmp_timestamp
用于将 MP4 的时间戳转换为 RTMP 的时间戳。 -
ngx_rtmp_mp4_from_rtmp_timestamp
用于将 RTMP 的时间戳转换为 MP4 的时间戳。
-
5. MP4 数据的发送
-
ngx_rtmp_mp4_send_meta
:-
该函数用于向 RTMP 客户端发送 MP4 文件的元数据(如视频宽高、编码类型、音频采样率等)。这些元数据以 AMF 格式封装,并通过 RTMP 协议发送给客户端。
-
-
ngx_rtmp_mp4_send
:-
负责将 MP4 数据发送到 RTMP 客户端,处理音视频数据的发送,并根据解析结果进行相关的处理(如调整时间戳、计算数据偏移量等)。
-
6. 内存映射和文件处理
为了处理较大的 MP4 文件,模块使用了内存映射技术,通过 ngx_rtmp_mp4_mmap
和 ngx_rtmp_mp4_munmap
来映射文件内容到内存中,从而提高文件读取的效率。
-
在 Windows 系统中,使用
CreateFileMapping
和MapViewOfFile
来实现内存映射。 -
在其他操作系统(如 Linux)中,使用
mmap
来进行内存映射。
7. 视频和音频的播放控制
-
ngx_rtmp_mp4_next
:-
该函数负责控制视频和音频数据的播放进度,通过
ngx_rtmp_mp4_next_time
、ngx_rtmp_mp4_next_key
、ngx_rtmp_mp4_next_chunk
等函数来控制帧的播放、时间戳的更新、数据块的读取等操作。
-
-
ngx_rtmp_mp4_seek_time
:-
实现了 MP4 文件的时间跳转功能,允许 RTMP 客户端请求从指定时间戳开始播放视频。
-
8. 总结
Nginx RTMP MP4 模块主要用于支持 RTMP 流媒体服务器与 MP4 文件的转换。它解析 MP4 文件中的音视频数据,并通过 RTMP 协议发送到客户端。模块通过复杂的解析和播放控制流程,支持音视频轨道的提取、时间戳的转换、音视频帧的推送等功能。