雷霄骅,是音视频领域的大牛,向他致敬!
他博客中一篇文章:《最简单的基于FFmpeg的推流器(以推送RTMP为例)》,还有他写的代码,作为FFMPEG的RTMP推流学习教程,非常经典。
1.Windows平台调试
下面是调试的流程:
(1)从ffmpeg官网下载ffmpeg,配置环境变量(备注:配置lib和bin路径)。如果不配置环境变量,编译时会报错。
(2)配置nginx,运行nginx,启动RTMP流媒体服务。
(3)下载实例代码,用VS打开工程(备注:我们在windows平台下调试)。
(4)编译代码前,建议修改推流服务器地址:
out_filename = "rtmp://localhost/publishlive/livestream";//输出 URL(Output URL)[RTMP]
例如:
out_filename = "rtmp://192.168.1.100/live/1";
(5)编译,运行。如果看到运行窗口输出如下字符串:
Send 60 video frames to output URL
Send 61 video frames to output URL
Send 62 video frames to output URL
表示推流成功。
(6)运行vlc播放器,输入网络URL:
rtmp://192.168.1.100/live/1
播放流媒体,能顺利看到视频。
2.Linux平台调试
操作系统:Ubuntu 16.04.5 LTS
(1)准备工作:我们需要先安装FFMPEG,网上有很多方法。可以通过命令安装。由于命令安装时一直报错,一时半会解决不了,所以我们直接下载FFMPEG源代码(ffmpeg-4.1.3.tar.bz2),编译后安装。
(2)把压缩包(simplest_ffmpeg_streamer-master.zip)拷贝到Ubuntu的某个目录下,解压;
(3)编译代码前,建议修改推流服务器地址:
out_filename = "rtmp://localhost/publishlive/livestream";//输出 URL(Output URL)[RTMP]
例如:
out_filename = "rtmp://192.168.1.100/live/1";
(4)切换到“simplest_ffmpeg_streamer-master/simplest_ffmpeg_streamer”目录,如果直接执行编译命令:
sh compile_gcc.sh
会遇到编译错误:
simplest_ffmpeg_streamer.cpp:117:32: error: ‘CODEC_FLAG_GLOBAL_HEADER’ was not declared in this scope
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
^
解决方法:修改代码为:
if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; //CODEC_FLAG_GLOBAL_HEADER;
(5)再次执行命令“sh compile_gcc.sh”,会报更多错误:
/usr/local/lib/libavformat.a(allformats.o): In function `av_iformat_next':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/allformats.c:579: undefined reference to `pthread_once'
/usr/local/lib/libavformat.a(allformats.o): In function `av_oformat_next':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/allformats.c:591: undefined reference to `pthread_once'
/usr/local/lib/libavformat.a(allformats.o): In function `av_register_all':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/allformats.c:603: undefined reference to `pthread_once'
/usr/local/lib/libavformat.a(allformats.o): In function `av_register_input_format':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/allformats.c:603: undefined reference to `pthread_once'
/usr/local/lib/libavformat.a(allformats.o): In function `av_register_output_format':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/allformats.c:613: undefined reference to `pthread_once'
/usr/local/lib/libavformat.a(avienc.o): In function `avi_write_header':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/avienc.c:317: undefined reference to `ceil'
/usr/local/lib/libavformat.a(fifo.o): In function `fifo_write_trailer':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/fifo.c:592: undefined reference to `pthread_join'
/usr/local/lib/libavformat.a(fifo.o): In function `fifo_write_header':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/fifo.c:533: undefined reference to `pthread_create'
/usr/local/lib/libavformat.a(hlsenc.o): In function `sls_flags_filename_process':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/hlsenc.c:822: undefined reference to `lround'
/usr/local/lib/libavformat.a(http.o): In function `http_close':
/home2/build_server2/lzb/ffmpeg_test/ffmpeg-4.1.3/libavformat/http.c:1649: undefined reference to `inflateEnd'
解决方法:修改编译脚本“compile_gcc.sh”为:
#! /bin/sh
gcc simplest_ffmpeg_streamer.cpp -g -o simplest_ffmpeg_streamer.out \
-I /usr/local/include -L /usr/local/lib -lavformat -lavcodec -lavutil \
-pthread -ldl -lswresample -lm -lz
最后一行“-pthread -ldl -lswresample -lm -lz”是新添加的。
(6)再次执行命令“sh compile_gcc.sh”,这次编译顺利!
(7)运行编译生成的可执行程序:
./simplest_ffmpeg_streamer.out
可以看到终端打印如下信息:
Input #0, flv, from 'cuc_ieschool.flv':
Metadata:
metadatacreator : iku
hasKeyframes : true
hasVideo : true
hasAudio : true
hasMetadata : true
canSeekToEnd : false
datasize : 932906
videosize : 787866
audiosize : 140052
lasttimestamp : 34
lastkeyframetimestamp: 30
lastkeyframelocation: 886498
encoder : Lavf55.19.104
Duration: 00:00:34.20, start: 0.042000, bitrate: 394 kb/s
Stream #0:0: Video: h264 (High), yuv420p(progressive), 512x288 [SAR 1:1 DAR 16:9], 15 fps, 15 tbr, 1k tbn, 30 tbc
Stream #0:1: Audio: mp3, 44100 Hz, stereo, fltp, 128 kb/s
Output #0, flv, to 'rtmp://192.168.1.100/live/1':
Stream #0:0: Unknown: none
Stream #0:1: Unknown: none
[flv @ 0x2250000] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
[flv @ 0x2250000] Using AVStream.codec to pass codec parameters to muxers is deprecated, use AVStream.codecpar instead.
Send 0 video frames to output URL
Send 1 video frames to output URL
Send 2 video frames to output URL
Send 3 video frames to output URL
Send 4 video frames to output URL
Send 5 video frames to output URL
(9)运行vlc播放器,输入网络URL:
rtmp://192.168.1.100/live/1
播放流媒体,能顺利看到视频。