×

Nginx 中实现 MP4 视频的边下边播

Falcon 2024-12-03 views:
自动摘要

正在生成中……

要在 Nginx 中实现 MP4 视频的边下边播(即支持 HTTP 伪流媒体),可以通过配置 ngx_http_mp4_module 模块实现。


Nginx配置

1. 确认 Nginx 已启用 ngx_http_mp4_module

ngx_http_mp4_module 是 Nginx 自带的模块,但需要在编译时启用。如果 Nginx 已安装,可以运行以下命令检查模块是否启用:

nginx -V 2>&1 | grep -- '--with-http_mp4_module'

如果输出包含 --with-http_mp4_module,说明已启用。如果没有,需要重新编译或安装支持该模块的版本。


2. 配置 Nginx

编辑 Nginx 配置文件(通常位于 /etc/nginx/nginx.conf/etc/nginx/sites-available/default):

server {
    listen 80;
    server_name example.com;

    location /videos/ {
        root /path/to/your/video/files;
        mp4;
        mp4_buffer_size 1m;    # 设置缓冲区大小
        mp4_max_buffer_size 5m; # 设置最大缓冲区大小
    }
}

在此配置中:

  • root /path/to/your/video/files; 是存放视频文件的目录。

    注意: 准确来说,在这个location配置场景,应该是videos文件目录的父目录,比如你的视频地址为 /www/my-website/videos/example.mp4,则应该填写/www/my-website,不需要填写videos部分!否则会报404错误。

  • mp4; 启用了 MP4 流式播放功能。

  • mp4_buffer_sizemp4_max_buffer_size 可以根据需求调整缓冲区的大小,默认值是 512KB。


3. 重载 Nginx 配置

编辑完成后,检查配置语法并重启 Nginx:

nginx -t  # 检查配置语法
nginx -s reload  # 重载配置

4. 测试视频播放

将一个 MP4 文件放入 /path/to/your/video/files 目录下,然后通过浏览器或视频播放器(支持 HTTP 流媒体,如 VLC)访问:

http://example.com/videos/your-video.mp4

播放器应该能在不完整下载整个文件的情况下边下载边播放。


注意事项

  1. 文件格式:确保 MP4 文件是“快速启动”(Fast Start)的。也就是说,MP4 的元数据需要在文件开头。如果视频在下载完成前无法播放,可能需要用工具(如 ffmpeg)调整:

    ffmpeg -i input.mp4 -movflags faststart output.mp4
    
  2. 带宽需求:边下边播对带宽要求较高,确保服务器网络环境支持用户的需求。

  3. 缓存优化:对于高流量视频站点,建议结合 Nginx 的缓存机制或使用 CDN 提供更好的性能。

  4. 防盗链:如果需要保护资源,可以配置防盗链功能,以限制未经授权的访问。

在 Nginx 中,如果视频服务器和引用网站位于不同域名下,你需要配置 CORS(跨域资源共享),以便客户端浏览器允许视频跨域加载。

跨域配置

修改 Nginx 配置支持 CORS

  1. 编辑 Nginx 配置文件 打开托管视频文件的 Nginx 配置文件,找到对应的 location 块,并添加以下内容:

    server {
        listen 80;
        server_name videos.example.com;
    
        location /videos/ {
            root /path/to/your/video/files;
            mp4;
            mp4_buffer_size 1m;
            mp4_max_buffer_size 5m;
    
            # CORS 配置
            add_header Access-Control-Allow-Origin *; # 允许所有域访问,也可以限定特定域
            add_header Access-Control-Allow-Methods "GET, OPTIONS"; # 允许的方法
            add_header Access-Control-Allow-Headers "Range"; # 允许请求头,支持 Range 播放
            add_header Access-Control-Expose-Headers "Content-Length, Content-Range"; # 暴露的响应头,支持视频断点续传
    
            # OPTIONS 预检请求
            if ($request_method = 'OPTIONS') {
                add_header Access-Control-Allow-Origin *;
                add_header Access-Control-Allow-Methods "GET, OPTIONS";
                add_header Access-Control-Allow-Headers "Range";
                return 204; # 直接返回成功,无需内容
            }
        }
    }
    

    解释:

    • Access-Control-Allow-Origin:指定允许的跨域来源。可以设置为 * 表示允许所有域访问,也可以指定特定域,例如 https://www.example.com
    • Access-Control-Allow-Methods:定义允许的 HTTP 方法。对于视频播放,通常只需要 GETOPTIONS
    • Access-Control-Allow-Headers:定义允许的请求头,Range 是视频播放所需的请求头。
    • Access-Control-Expose-Headers:定义前端可以访问的响应头,Content-LengthContent-Range 是支持断点续传播放所需的头。
    • if ($request_method = 'OPTIONS'):处理浏览器发送的预检请求(OPTIONS 请求)。

  1. 检查配置语法并重启 Nginx 保存配置后,检查语法并重启 Nginx:

    nginx -t
    nginx -s reload
    

测试跨域访问

  1. 在视频引用的网站上,尝试嵌入视频:

    <video controls>
        <source src="http://videos.example.com/videos/sample.mp4" type="video/mp4">
        Your browser does not support the video tag.
    </video>
    
  2. 打开开发者工具(F12),在“网络”选项卡检查视频的网络请求。如果配置正确,你应该看到以下请求头和响应头:

    • 请求头
      Origin: https://www.example.com
      
    • 响应头
      Access-Control-Allow-Origin: *
      Access-Control-Allow-Methods: GET, OPTIONS
      Access-Control-Allow-Headers: Range
      Access-Control-Expose-Headers: Content-Length, Content-Range
      

限制跨域来源(可选)

如果希望只允许特定域访问,修改 Access-Control-Allow-Origin 的值,例如:

add_header Access-Control-Allow-Origin "https://www.example.com";

这样,只有 https://www.example.com 域名可以加载视频。


注意事项

  1. Range 支持:确保 Nginx 的 mp4 模块配置正确,因为 CORS 配置和断点续传密切相关。
  2. 安全性:尽量避免将 Access-Control-Allow-Origin 设置为 *,以减少资源被滥用的风险。
  3. HTTPS 支持:如果网站使用 HTTPS,确保视频服务器也使用 HTTPS,避免混合内容警告。

检查视频是否支持快速启动

要检查 MP4 文件是否已经支持“快速启动”(即元数据是否位于文件的开头),可以使用脚本比较,只要 moov 偏移量小于 mdat 的偏移量就支持。

cat check_faststart :

#!/bin/bash

# 检查输入参数
if [ "$#" -ne 1 ]; then
    echo "用法: $0 <视频文件路径>"
    exit 1
fi

FILE="$1"

# 检查文件是否存在
if [ ! -f "$FILE" ]; then
    echo "错误: 文件 $FILE 不存在!"
    exit 1
fi

# 提取 moov 和 mdat 的偏移量
MOOV_OFFSET=$(xxd "$FILE" | grep -m 1 -i "moov" | cut -d ' ' -f 1)
MDAT_OFFSET=$(xxd "$FILE" | grep -m 1 -i "mdat" | cut -d ' ' -f 1)

# 检查是否找到 moov 和 mdat
if [ -z "$MOOV_OFFSET" ]; then
    echo "错误: 未找到 moov 元数据!文件可能损坏或不支持 MP4 格式。"
    exit 1
fi

if [ -z "$MDAT_OFFSET" ]; then
    echo "错误: 未找到 mdat 数据块!文件可能损坏或不支持 MP4 格式。"
    exit 1
fi

# 输出偏移量
echo "moov 偏移量: $MOOV_OFFSET"
echo "mdat 偏移量: $MDAT_OFFSET"
echo "如果 moov 小于 mdat 的偏移量则表示已经支持快速启动"

用法:

check_faststart Downloads/test-video.mp4

输出:

moov 偏移量: 00000010:
mdat 偏移量: 000037a0:
如果 moov 小于 mdat 的偏移量则表示已经支持快速启动
本文收录于