凌峰创科服务平台

nginx mp4 流媒体服务器

这个模块允许 Nginx 直接支持 FLV (Flash Video) 格式,并通过 HTTP-FLV 协议实现低延迟的直播和点播,它也极大地优化了 MP4 的点播体验,支持 伪流,即可以拖动进度条到任意位置开始播放,而无需等待整个文件下载。

nginx mp4 流媒体服务器-图1
(图片来源网络,侵删)

核心概念:伪流 vs. 真流

在开始之前,理解这两个概念非常重要:

  1. 伪流

    • 原理:MP4 文件是一个容器,里面包含了多个 moov (元数据) 和 mdat (媒体数据) 块,伪流技术通过在服务器端解析 MP4 文件,找到 moov 块并将其移动到文件的最前面,这样,播放器在请求时可以快速获取到视频的时长、分辨率等关键信息,并根据请求的时间点(如 start=30)计算出对应的字节偏移量,直接从 mdat 块中读取数据开始播放。
    • 优点
      • 实现简单,无需对现有 MP4 文件做特殊处理(只需一次预处理)。
      • 普通 HTTP 服务器即可支持。
      • 支持拖动进度条。
    • 缺点
      • 每次拖动都需要服务器重新计算和响应,对服务器有一定开销。
      • 对于非常大的文件,首次加载(获取 moov 元数据)可能会慢一些。
  2. 真流

    • 原理:视频文件被分割成一系列小的、连续的片段(如 .ts 文件),并生成一个索引文件(如 .m3u8 文件),播放器首先下载 .m3u8 文件,然后按顺序下载并播放各个 .ts 片段。
    • 优点
      • 首次加载极快,因为索引文件非常小。
      • 拖动非常高效,直接定位到对应的片段即可。
      • 适合网络传输,可以轻松实现不同码率的自适应码率流。
    • 缺点

      需要一个“转码”或“封装”的过程,将原始 MP4 文件转换成 HLS (m3u8) 或 DASH 格式,这需要额外的工具(如 FFmpeg)和存储空间。

      nginx mp4 流媒体服务器-图2
      (图片来源网络,侵删)

Nginx + nginx-http-flv-module 主要优化了伪流体验,并增加了对 HTTP-FLV 直播的支持。


MP4 伪流点播服务器(推荐)

这是最常见的需求,即让用户可以在网页上直接播放 MP4 文件,并能拖动进度条。

步骤 1:安装 Nginx (带 nginx-http-flv-module)

你不能直接用 aptyum 安装的 Nginx,因为它默认不包含这个模块,你需要自己从源码编译。

  1. 安装依赖

    nginx mp4 流媒体服务器-图3
    (图片来源网络,侵删)
    # CentOS / RHEL
    sudo yum groupinstall "Development Tools"
    sudo yum install pcre-devel zlib-devel openssl-devel git
    # Ubuntu / Debian
    sudo apt update
    sudo apt install build-essential libpcre3-dev zlib1g-dev libssl-dev git
  2. 下载 Nginx 源码和模块

    # 下载 Nginx (请替换为最新稳定版)
    wget http://nginx.org/download/nginx-1.24.0.tar.gz
    tar -xzvf nginx-1.24.0.tar.gz
    # 下载 nginx-http-flv-module
    git clone https://github.com/winshu/nginx-http-flv-module.git
  3. 编译和安装

    cd nginx-1.24.0
    # 配置编译参数
    # --add-module= 指向你下载的模块路径
    ./configure --prefix=/usr/local/nginx \
                --add-module=/path/to/nginx-http-flv-module \
                --with-http_ssl_module \
                --with-http_v2_module
    # 编译和安装
    make
    sudo make install

    安装完成后,Nginx 可执行文件通常在 /usr/local/nginx/sbin/nginx

步骤 2:配置 Nginx

编辑 Nginx 的配置文件,通常是 /usr/local/nginx/conf/nginx.conf

user  nobody;
worker_processes  1;
error_log  logs/error.log warn;
pid        logs/nginx.pid;
events {
    worker_connections  1024;
}
http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    #======== MP4 伪流配置 ========#
    server {
        listen       80;
        server_name  localhost;
        # 设置 MP4 文件根目录
        location ~ \.mp4$ {
            # 核心指令,启用 MP4 伪流
            mp4;
            # 可选:设置文件根目录
            root   html;
            # 可选:默认文件名
            index  index.html;
            # 可选:限制单个请求的速率,防止带宽被占满
            limit_rate_after 5m;
            limit_rate 512k;
        }
        # 可选:一个简单的测试页面
        location / {
            root   html;
            index  index.html index.htm;
        }
    }
}

配置详解:

  • location ~ \.mp4$:匹配所有以 .mp4 结尾的 URL 请求。
  • mp4;这是最关键的指令,它告诉 Nginx 对这个 location 启用 MP4 伪流功能,Nginx 会自动处理 moov 元数据,并解析 start 参数。

步骤 3:准备测试文件和启动 Nginx

  1. 将你的 MP4 文件放到 Nginx 的 html 目录下。/usr/local/nginx/html/my_video.mp4
  2. 启动 Nginx:
    /usr/local/nginx/sbin/nginx
  3. 访问 http://localhost/my_video.mp4,你可以在浏览器中直接打开,也可以在支持 HTML5 video 标签的网页中测试。

HTML5 测试代码示例 (index.html):

<!DOCTYPE html>
<html>
<head>MP4 Pseudo-Streaming Test</title>
</head>
<body>
    <h1>MP4 Pseudo-Streaming Test</h1>
    <video width="800" height="450" controls>
        <!-- 注意这里的 URL,可以添加 start 参数来测试拖动 -->
        <!-- http://localhost/my_video.mp4?start=30 -->
        <source src="/my_video.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
</body>
</html>

你可以在浏览器中打开这个页面,视频播放器会加载,并且你可以拖动进度条到任意位置,视频会从该点开始播放。


低延迟直播服务器(HTTP-FLV)

这个方案需要有一个推流端(如 OBS、FFmpeg)将视频流推送到 Nginx,然后用户通过 Nginx 拉流观看。

步骤 1:安装 Nginx

安装过程与方案一完全相同,必须包含 nginx-http-flv-module

步骤 2:配置 Nginx

nginx.conf 中添加直播相关的配置。

http {
    # ... 其他配置 ...
    #======== 直播流媒体配置 ========#
    server {
        listen       8080; # 直播服务监听端口
        server_name  localhost;
        # HTTP-FLV 直播配置
        location /live {
            # 核心指令,启用直播功能
            flv_live on;
            # 设置直播流的应用名
            chunked_transfer_encoding on; # 开启分块传输,对直播很重要
            # 可选:设置 HLS 录制
            hls on;
            hls_path /usr/local/nginx/hls; # 录制文件存放目录
            hls_fragment 3s; # 每个切片时长
            hls_cleanup on; # 自动清理旧的录制文件
        }
        # 可选:配置 HLS 点播(录制后的文件)
        location /hls {
            types {
                application/vnd.apple.mpegurl m3u8;
                video/mp2t ts;
            }
            root /usr/local/nginx;
            add_header Cache-Control no-cache; # HLS 需要不缓存
        }
    }
}

配置详解:

  • listen 8080;:直播服务使用不同的端口,避免与普通 Web 服务冲突。
  • location /live:所有推流和拉流的请求都以 /live 开头。
  • flv_live on;核心指令,启用 HTTP-FLV 直播模式。
  • chunked_transfer_encoding on;:对于直播这种持续长连接的场景,开启分块传输是标准做法。
  • hls on;:可选功能,开启 HLS 录制,这样直播流可以被录制下来,形成 .m3u8.ts 文件供后续点播。

步骤 3:启动 Nginx 和推流

  1. 启动 Nginx

    /usr/local/nginx/sbin/nginx
  2. 使用 FFmpeg 推流: 假设你有一个视频文件 input.mp4,想推送到 Nginx 的 my_live_stream 这个流名。

    ffmpeg -re -i input.mp4 -c copy -f flv "http://localhost:8080/live?app=my_live_stream&stream=my_live_stream"
    • -re:以文件本身的帧率读取,模拟实时流。
    • -i input.mp4:输入文件。
    • -c copy:直接复制流,不做转码,速度最快。
    • -f flv:指定输出格式为 FLV。
    • http://...:推流地址。appstream 是自定义的应用名和流名。
  3. 观看直播: 使用支持 FLV 的播放器(如 flv.js)或 VLC 播放器,拉取流地址: http://localhost:8080/live?app=my_live_stream&stream=my_live_stream

    HTML5 + flv.js 示例:

    <!DOCTYPE html>
    <html>
    <head>
        <title>Live Stream Test</title>
        <script src="https://cdn.jsdelivr.net/npm/flv.js@1.6.2/dist/flv.min.js"></script>
    </head>
    <body>
        <video id="videoElement" controls width="800" height="450"></video>
        <script>
            if (flvjs.isSupported()) {
                const videoElement = document.getElementById('videoElement');
                const flvPlayer = flvjs.createPlayer({
                    type: 'flv',
                    url: 'http://localhost:8080/live?app=my_live_stream&stream=my_live_stream'
                });
                flvPlayer.attachMediaElement(videoElement);
                flvPlayer.load();
                flvPlayer.play();
            }
        </script>
    </body>
    </html>

总结与建议

特性 MP4 伪流点播 HTTP-FLV 直播
适用场景 存在大量 MP4 文件,用户可在线观看和拖动。 实时视频直播,如会议、教学、游戏直播。
核心模块 nginx-http-flv-module (提供 mp4 指令) nginx-http-flv-module (提供 flv_live 指令)
配置关键 location ~ \.mp4$ { mp4; } location /live { flv_live on; }
优点 配置简单,利用现有文件,拖动体验好。 延迟低(通常在 1-3 秒),协议成熟。
缺点 不适合实时直播,大文件首次加载可能慢。 需要推流端,服务器需持续处理长连接。

最终建议:

  • 如果你只是想让网站上的 MP4 视频文件支持在线播放和拖动,方案一(MP4 伪流) 是最简单、最直接的选择。
  • 如果你需要搭建一个低延迟的直播平台,方案二(HTTP-FLV 直播) 是非常好的选择,它比传统的 RTMP 直播在穿透性上更有优势(基于 HTTP),延迟也足够低。
  • 对于更高要求的直播场景,可以结合 HLSDASH,虽然延迟稍高(10-20秒),但兼容性最好,特别是移动端,这通常需要 FFmpeg 在推流时进行转码封装。
分享:
扫描分享到社交APP
上一篇
下一篇