如何配置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 fichmod 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
相关产品推荐
相关产品推荐

