雷霄驊,是音視頻領域的大牛,向他致敬!
他博客中一篇文章:《最簡單的基於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
播放流媒體,能順利看到視頻。