FFmpeg开发笔记(八十一)FFmpeg代码对RTSP和RTMP的推流区别

《FFmpeg开发实战:从零基础到短视频上线》一书的"10.2.2 FFmpeg向网络推流"介绍了如何使用FFmpeg代码向网络推送视频流,当时的例程采用了RTSP方式推流,在向RTSP地址时推流是正常的,但向RTMP地址推流时出现了问题,下面就介绍了如何使用FFmpeg代码向RTMP地址推送视频流。

一、FFmpeg推流环境的区别

首先注意RTSP推流地址以"rtsp://"开头,且RTSP地址的默认端口号为8554。而RTMP推流地址以"rtmp://"开头,且RTMP地址的默认端口号为1935。

其次注意FFmpeg从6.1开始对RTMP协议做了增强支持,主要是支持HEVC、VP9和AV1等编码格式通过RTMP协议进行推流,所以建议将编译环境的FFmpeg版本升级到6.1或者更高版本。

二、FFmpeg推流代码的适配

FFmpeg推流代码对于RTSP地址和RTMP地址主要有下列两点适配区别:

1、调用avformat_alloc_output_context2函数分配音视频文件封装实例的时候,第三个输入参数对于RTSP地址而言要填rtsp,对于RTMP地址而言要填flv。比如以下代码通过判断推流地址的协议类型来决定avformat_alloc_output_context2的第三个参数要填何值。

复制代码
int ret = 0;
// 分配音视频文件的封装实例(注意rtmp协议的第三个参数填flv,rtsp协议的第三个参数填rtsp)
if (strstr(dest_name, "rtmp") != NULL) {
    ret = avformat_alloc_output_context2(&out_fmt_ctx, NULL, "flv", dest_name);
} else {
    ret = avformat_alloc_output_context2(&out_fmt_ctx, NULL, "rtsp", dest_name);
}
if (ret < 0) {
    av_log(NULL, AV_LOG_ERROR, "Can't alloc output_file %s.\n", dest_name);
    return -1;
}
av_log(NULL, AV_LOG_INFO, "Success open push url %s.\n", dest_name);

2、调用avformat_alloc_output_context2函数之后,还要依据推流地址的协议类型来决定是否接着调用avio_open函数打开输出流,对于RTSP地址而言不必调用avio_open,对于RTMP地址而言必须调用avio_open。具体的判断与调用代码如下所示:

复制代码
// 打开输出流(注意rtsp推流不要调用avio_open,但rtmp推流要调用avio_open)
if (strstr(dest_name, "rtmp") != NULL) {
    ret = avio_open(&out_fmt_ctx->pb, dest_name, AVIO_FLAG_READ_WRITE);
    if (ret < 0) {
        av_log(NULL, AV_LOG_ERROR, "Can't open output_file %s.\n", dest_name);
        return -1;
    }
}

按照以上两点代码修改了《FFmpeg开发实战:从零基础到短视频上线》随书源码第十章的推流程序代码chapter10/pushvideo.c后,先按照之前的文章《详解MediaMTX的推拉流》启动电脑本地的流媒体服务器MediaMTX,再执行下面的编译命令。

复制代码
gcc pushvideo.c -o pushvideo -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm

编译完成后执行以下命令启动测试程序,期望把2018.mp4推给RTMP协议的推流地址rtmp://127.0.0.1:1935/stream。

复制代码
./pushvideo ../file/2018.mp4 rtmp://127.0.0.1:1935/stream

接着打开另一个MSYS窗口,同样进入该书第十章的源码目录chapter10,执行下面的编译命令。

复制代码
gcc pullvideo.c -o pullvideo -I/usr/local/ffmpeg/include -L/usr/local/ffmpeg/lib -I/usr/local/sdl2/include -L/usr/local/sdl2/lib -lsdl2 -lavformat -lavdevice -lavfilter -lavcodec -lavutil -lswscale -lswresample -lpostproc -lm

编译完成后执行以下命令启动测试程序,期望从http://127.0.0.1:8888/stream/index.m3u8拉取视频流并弹窗播放。

复制代码
./pullvideo http://127.0.0.1:8888/stream/index.m3u8

然后果真弹出一个SDL窗口,正在播放从HLS服务拉取的视频画面,说明修改后的推流代码成功支持了RTMP协议。

更多详细的FFmpeg开发知识参见《FFmpeg开发实战:从零基础到短视频上线》一书。

相关推荐
Pocker_Spades_A3 小时前
视频不用再一张张截图:ClipSketch AI 把关键画面转成漫画,还能顺手生成文案
人工智能·音视频
星辰徐哥3 小时前
本地视频预览别只自己看:把Remotion动效项目发给客户远程验收
docker·ai·node.js·html·音视频·react·remotion
镜像视界(浙江)科技有限公司3 小时前
《视频孪生之上:二维展示终结,三维空间计算重构城市逻辑》——跨摄像连续表达 × 三角测量厘米级定位 × 动态轨迹建模,构建新一代城市空间
大数据·人工智能·算法·矩阵·音视频·空间计算
你不是我我4 小时前
【AI 测评】想用自己的声音给视频配音?Index-TTS本地部署这样做
人工智能·音视频
Ulyanov7 小时前
AudioVision Pro:基于 PySide6 + sounddevice 的实时音频可视化播放器设计
python·算法·音视频
福大大架构师每日一题7 小时前
ComfyUI v0.34.0发布:视频、音频、三维、显存与合作节点全面更新
音视频
敲代码的嘎仔10 小时前
用 Redis 合并写 + DelayQueue 延迟检测,把视频播放进度写库频率降到 1/60
java·开发语言·数据库·redis·缓存·音视频·高并发
Xxtaoaooo11 小时前
AI 视频生成能不能真正跑通?MoneyPrinterTurbo 本地制作、远程访问与授权验证
人工智能·音视频·cpolar·ai视频·自动化短视频
Bruce_Liuxiaowei11 小时前
录屏片段无损合并:从 ffmpeg concat 原理到 Python 自动化脚本
python·ffmpeg·自动化
bloxed12 小时前
“视频上看得见的洪水淹没预演”:视频数字孪生完整实践
音视频