技术知识文章集合TECHNICAL ARCHIVE · 807 DOCUMENTS

显示模式

登录
ARCHIVE DOCUMENTBE

Nginx 伺服 mp4 视频流的配置参考

所属分类
Backend
文件格式
Markdown
原始路径
Backend/Nginx 伺服 mp4 视频流的配置参考
本文目录4 个章节
  1. 配置总览
  2. 关键配置解读
  3. 适用场景
  4. 参考

Nginx 伺服 mp4 视频流的配置参考

Category(分类): Backend Status: 已读

原文:Nginx configuration for serving mp4 videos(GitHub Gist,CSRaghunandan)。 本文为整理版本:Gist 原文只有一份完整的 nginx.conf,此处保留配置并补充逐段注释,便于理解每部分的作用。

配置总览

这是一份用于 WebRTC 直播 + mp4 点播的混合配置(janus 信令反代、flv 直播、mp4 点播缓存),其中与 mp4 视频伺服直接相关的是最后一个 location ~/.mp4 块。

#user  nobody;
worker_processes  4;

events {
    worker_connections  1024;
}

http {
    include       mime.types;
    default_type  application/octet-stream;

    access_log             off;
    sendfile_max_chunk     512k;
    sendfile               on;
    tcp_nopush             on;
    keepalive_timeout      65;
    gzip                   on;

    server {
        # 代理缓存路径:缓存 70MB,命名 mycache
        proxy_cache_path /tmp/mycache keys_zone=mycache:70m;

        listen      *:9000;
        root        /usr/local/nginx/html;
        index       index.html index.htm;
        server_name _;

        # —— WebRTC 信令(janus)反向代理 ——
        location /rtc {
            proxy_set_header Host      $host;
            proxy_set_header X-Real-IP $remote_addr;
            proxy_pass http://127.0.0.1:8088/janus;
        }

        # —— rtcapp WebSocket 升级代理 ——
        location /rtcapp {
            # 为直播启用线程池
            aio threads=default;
            proxy_pass http://localhost:8188;
            proxy_http_version 1.1;
            proxy_set_header Upgrade    $http_upgrade;
            proxy_set_header Connection "upgrade";
            proxy_set_header Host       $host;
        }

        # —— flv 直播流 ——
        location ~ \.flv$ {
            aio threads=default;
            flv;
        }

        # —— mp4 点播(核心部分)——
        location ~/.mp4 {
            root /media;
            mp4;
            mp4_buffer_size       1M;
            mp4_max_buffer_size   3M;

            # 启用线程池,避免阻塞 worker
            aio threads=default;

            # 为 mp4 启用代理缓存
            proxy_cache             mycache;
            proxy_cache_valid 200   300s;
            proxy_cache_lock        on;

            # 启用 nginx 分片缓存
            slice                   1m;
            proxy_cache_key         $host$uri$is_args$args$slice_range;
            proxy_set_header Range  $slice_range;
            proxy_http_version      1.1;

            # 回填缓存期间立即回源
            proxy_cache_lock_timeout 0s;
            # 将 age 设为大于预期回填时间的值
            proxy_cache_lock_age     200s;
            proxy_cache_use_stale    updating;
        }
    }
}

关键配置解读

mp4 模块

mp4;
mp4_buffer_size     1M;
mp4_max_buffer_size 3M;
  • mp4 指令启用 ngx_http_mp4_module,支持"伪流媒体"(pseudo-streaming):浏览器通过 ?start= 查询参数即可从任意位置开始播放,无需下载整个文件;
  • mp4_buffer_size 是处理 mp4 元数据(moov atom)的初始缓冲区,mp4_max_buffer_size 是上限。注意保持合理值,过大(例如有人设到 300M)会显著增加内存压力。

aio threads(线程池)

aio threads=default;

将阻塞的磁盘读取操作交给独立线程池处理,避免慢速 I/O 阻塞事件循环。官方博客的测试中,线程池可将大文件传输性能提升数倍(见下一篇《Nginx 伺服大体积 mp4 文件效率问题排查》)。

sendfile 与分片

sendfile           on;
sendfile_max_chunk 512k;
  • sendfile 让数据在内核态直接从文件描述符传输到 socket,避免用户态拷贝;
  • sendfile_max_chunk 限制单次 sendfile 传输量(512k),防止单个连接长时间独占 worker。

slice 分片缓存 + Range 请求

slice                   1m;
proxy_cache_key         $host$uri$is_args$args$slice_range;
proxy_set_header Range  $slice_range;
proxy_http_version      1.1;

slice 模块将大响应切成固定大小(1m)的子请求,每个分片独立缓存。配合 Range 请求头,同一个大 mp4 文件的不同分片可以被分别缓存和复用,非常适合按需拖动进度条的场景。

缓存行为控制

proxy_cache_lock         on;
proxy_cache_lock_timeout 0s;
proxy_cache_lock_age     200s;
proxy_cache_use_stale    updating;
  • proxy_cache_lock on:同一分片回填期间,后续请求等待而不是重复回源;
  • proxy_cache_lock_timeout 0s + proxy_cache_lock_age 200s:等待超时后直接回源;
  • proxy_cache_use_stale updating:缓存刷新期间可以返回旧缓存,避免用户请求被卡住。

适用场景

  • 视频文件较大、用户会频繁拖动进度条(Range 请求多);
  • 同一批视频会被反复观看(缓存命中收益高);
  • 服务器磁盘 I/O 较慢(线程池 + aio 避免阻塞)。

参考

807 DOCUMENTS · 12 COLLECTIONS
ARCHIVE SEARCH807 篇文章