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协议的第三个参数填flvrtsp协议的第三个参数填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, Cant 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, Cant 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协议。