You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何配置Nginx RTMP模块将直播视频自动存储至S3存储桶

结论

这个需求完全可以实现,不需要魔改nginx-rtmp-module,靠模块原生能力配合简单系统脚本就能稳定跑通。你现在没法存S3的核心原因是配置里显式关了录制功能,且当前开启的HLS/DASH切片会按配置的playlist长度自动过期删除,本身就不是为持久化存储设计的。

具体实现步骤
  • 前置环境准备
    先在服务器上安装S3兼容的命令行工具,完成AK/SK、目标存储桶的权限配置,手动执行命令测试从服务器本地传文件到S3桶可正常成功,将工具执行权限赋给nginx的运行用户(通常为www-data或nginx)。单独创建录制文件存储目录,比如/var/www/html/stream/record,同样给nginx运行用户开放读写权限,不要把录制文件和HLS/DASH临时切片混放。
  • 调整RTMP服务配置
    原有RTMP配置只需要修改application live块内的录制相关参数,新增录制完成回调即可,调整后的配置参考如下:
    rtmp {
            server {
                    listen 1935;
                    chunk_size 4096;
                    allow publish 127.0.0.1;
                    deny publish all;
    
                    application live {
                            live on;
                            # 关闭录制的配置改为开启全量录制
                            record all;
                            # 录制文件本地存储路径
                            record_path /var/www/html/stream/record;
                            # 录制文件名后缀,拼接流名、时间戳避免重名覆盖
                            record_suffix _${name}_%Y%m%d_%H%M%S.flv;
                            # 开启文件名唯一校验,防止重名冲突
                            record_unique on;
                            # 录制完成(主播断流结束直播)时触发上传脚本,显式传参给脚本
                            on_record_done /usr/local/bin/rtmp_upload_s3.sh $record_path $name;
    
                            hls on;
                            hls_path /var/www/html/stream/hls;
                            hls_fragment 3;
                            hls_playlist_length 60;
    
                            dash on;
                            dash_path /var/www/html/stream/dash;
                    }
            }
    }
    
    改完配置执行nginx -s reload重载即可,不影响正在运行的直播流。
  • 编写S3上传回调脚本
    在上面配置指定的路径/usr/local/bin/rtmp_upload_s3.sh创建shell脚本,nginx触发回调时会自动把录制文件路径、流名参数传给脚本,核心逻辑是把录好的完整直播文件传到S3,传完删除本地文件节省空间,参考内容如下:
    #!/bin/bash
    # 第一个参数为本地录制文件完整路径
    RECORD_FILE=$1
    # 第二个参数为对应的流名称
    STREAM_NAME=$2
    # S3目标存储路径,按流名/日期分类存储方便后续检索
    S3_TARGET="s3://替换为你的存储桶名/record/${STREAM_NAME}/$(basename $RECORD_FILE)"
    
    # 执行上传,设置合理超时避免长时间阻塞
    s3 cp $RECORD_FILE $S3_TARGET --expected-size $(stat -c%s $RECORD_FILE)
    if [ $? -eq 0 ]; then
        # 上传成功删除本地文件
        rm -f $RECORD_FILE
    else
        # 上传失败打错误日志,后续配定时任务扫残留文件重试即可
        echo "upload $RECORD_FILE to s3 failed at $(date)" >> /var/log/rtmp_upload.log
    fi
    
    写完给脚本加可执行权限:chmod 755 /usr/local/bin/rtmp_upload_s3.sh,将脚本属主改成nginx运行用户。
可选优化方案
  • 如果需要近乎实时把直播内容同步到S3,不想等主播下播才传整文件,可以在服务器上装文件监控工具,监控HLS/DASH的切片目录,每生成一个新的切片文件就立刻上传到S3,同时同步更新m3u8/mpd索引文件。注意要加逻辑把过期的旧切片从S3上删掉,不然会堆大量无用文件产生额外存储成本。
  • 如果需要给用户提供mp4格式的回放,不用存储flv原文件,直接在上传脚本里加ffmpeg转码命令,把录制好的flv转成mp4后再上传,转码时记得加线程参数限制CPU占用,避免抢占直播服务的运行资源。
  • 可以新增开播回调on_publish,在主播开始推流的时候自动在S3对应目录写入开播时间标记、生成直播回放的占位信息,不用等录制完成才生成回放记录。
常见踩坑提醒
  • 不要用FUSE方式把S3存储桶直接挂载到本地当录制目录,大文件持续写入时非常容易出现IO错误,导致录制文件损坏、直播断流,本地磁盘写完再一次性上传的稳定性高很多。
  • 给录制目录加磁盘使用率监控,脚本上传成功后及时删除本地文件,避免磁盘写满导致整个直播服务崩溃。
  • 回调脚本不要写太重的逻辑,大文件上传建议丢后台异步执行,不要阻塞nginx的RTMP事件进程,避免影响正常推流。

内容的提问来源于stack exchange,提问作者user19409887

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 11:06:24