Ngnix服務(wù)器搭建痛阻,RTMP菌瘪、X264與交叉編譯

1.流媒體服務(wù)器推流的流程

流程.png

2.NGINX流服務(wù)器搭建

Nginx (engine x) 是一個高性能的HTTP和反向代理服務(wù),也是一個IMAP/POP3/SMTP服務(wù)

Linux操作:

1.下載nginx

wget http://nginx.org/download/nginx-1.15.3.tar.gz

2.解壓

tar xvf nginx-1.15.3.tar.gz

3.下載nginx rtmp模塊

wget https://codeload.github.com/arut/nginx-rtmp-module/tar.gz/v1.2.1

4.解壓

tar xvf v1.2.1  

5.進入nginx目錄

cd nginx-1.15.3

6.執(zhí)行:

#--add-module 指向rtmp模塊目錄
./configure --prefix=./bin --add-module=../nginx-rtmp-module-1.2.1

在這個過程中可能因為環(huán)境不同而出現(xiàn)不同錯誤阱当,比如缺少pcre俏扩、openssl等,這時候就需要安裝這些庫弊添。

https://blog.csdn.net/z920954494/article/details/52132125

7.執(zhí)行 Makefile

make install Makefile

8.編譯安裝完成后,當(dāng)前目錄的會有個bin目錄嫉戚。

cd bin/conf

vim nginx.conf 修改為:

user root;
worker_processes  1;

error_log  /root/nginx-1.15.3/bin/logs/error.log debug;

events {
    worker_connections  1024;
}

rtmp {
    server {
         #注意端口占用
        listen 1935;
        #myapp 可以修改  rtmp://IP:端口:myapp
        application myapp {
            live on;
            #丟棄閑置5s的連接
            drop_idle_publisher 5s;
        }
    }
}
http {
    server {
        #注意端口占用
        listen      8081;
        location /stat {
            rtmp_stat all;
            rtmp_stat_stylesheet stat.xsl;
        }
        location /stat.xsl {
            #注意目錄 修改成自己的nginx-rtmp-module目錄
            root /root/nginx-rtmp-module-1.2.1/;
        }
        location /control {
            rtmp_control all;
        }
        location /rtmp-publisher {
            #注意目錄 修改成自己的nginx-rtmp-module/test目錄
            root /root/nginx-rtmp-module-1.2.1/test;
        }
        
        location / {
            #注意目錄 修改成自己的nginx-rtmp-module/test/www目錄
            root /root/nginx-rtmp-module-1.2.1/test/www;
        }
    }
}

其實就是從 nginx-rtmp-module-1.2.1/test/nginx.conf中拷貝溯泣。

端口占用檢查: lsof -i:8080

需要注意的是目錄與端口是否被占用努潘,比如我的8080端口被占用慈俯,我改為了8081,然后需要開放端口略号。

配置了iptables防火墻的翻下前面的資料玄柠,如果沒安裝的阿里云服務(wù)器可以進入阿里云控制臺


阿里云控制臺.png

然后點擊配置規(guī)則,在新頁面點擊添加安全組規(guī)則,開放8081端口宫患,然后確定娃闲,就可以了匾浪。

開放端口.png

9.配置完成后蛋辈,就可以啟動nginx了

在nginx-1.15.3 目錄下 執(zhí)行 bin/sbin/nginx 即可啟動

bin/sbin/nginx -s stop 停止

一定要在當(dāng)前目錄啟動,因為上面的配置 error_log logs/error.log debug; 會去執(zhí)行命令的目錄下查找 logs渐白。

如果error_log 改成一個絕對路徑 那就沒關(guān)系了礼预。

在瀏覽器輸入

【IP】:端口

能訪問就表示配置完成了托酸。

3.RTMP励堡、X264與交叉編譯

1.RTMP

與HTTP(超文本傳輸協(xié)議)同樣是一個基于TCP的Real Time Messaging Protocol(實時消息傳輸協(xié)議)刨疼。由Adobe Systems公司為Flash播放器和服務(wù)器之間音頻鹅龄、視頻和數(shù)據(jù)傳輸開發(fā)的一種開放協(xié)議 迎卤。在國內(nèi)被廣泛的應(yīng)用于直播領(lǐng)域蜗搔。HTTP默認端口為80八堡,RTMP則為1935缝龄。

本質(zhì)上我們通過閱讀Adobe的協(xié)議規(guī)范挂谍,通過與服務(wù)器建立TCP通信,根據(jù)協(xié)議格式生成與解析數(shù)據(jù)即可使用RTMP進行直播庐扫。當(dāng)然我們也可以借助一些實現(xiàn)了RTMP協(xié)議的開源庫來完成這一過程形庭。

2.RTMPDump

RTMPDump 是一個用來處理RTMP流媒體的開源工具包萨醒。它能夠單獨使用進行RTMP的通信富纸,也可以集成到FFmpeg中通過FFmpeg接口來使用RTMPDump。

  1. RTMPDump源碼下載:http://rtmpdump.mplayerhq.hu/download/rtmpdump-2.3.tgz
rtmp源碼.png
  1. 解壓并把源碼導(dǎo)入到AS項目中。
    (根目錄下提供了一個Makefile與一些.c源文件勤庐。這里的源文件將會編譯出一系列的可執(zhí)行文件愉镰。然后我們需要的并不是可執(zhí)行文件钧汹,真正的對RTMP的實現(xiàn)都在librtmp子目錄中崭孤。在這個子目錄中同樣包含了一個Makefile文件遗锣。通過閱讀Makefile發(fā)現(xiàn)精偿,它的源碼并不多:OBJS=rtmp.o log.o amf.o hashswf.o parseurl.o笔咽。因此我們不進行預(yù)編譯叶组,即直接放入AS中借助CMakeLists.txt來進行編譯甩十。這么做可以讓我們方便的對庫本身進行調(diào)試或修改(實際上我們確實會稍微修改這個庫的源碼)

在AS中復(fù)制librtmp置于:src/main/cpp/librtmp,并為其編寫CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

#預(yù)編譯宏
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DNO_CRYPTO")


#所有源文件放入 rtmp_source 變量
file(GLOB rtmp_source *.c)

#編譯靜態(tài)庫
add_library(rtmp STATIC ${rtmp_source} )
3.x264

x264是一個C語言編寫的目前對H.264標準支持最完善的編解碼庫橄霉。與RTMPDump一樣同樣直接在Android中使用姓蜂,也可以集成進入FFMpeg覆糟。

https://www.videolan.org/developers/x264.html

在linux下載編譯:
1.下載 解壓

wget ftp://ftp.videolan.org/pub/x264/snapshots/last_x264.tar.bz2
tar xvf last_x264.tar.bz2

2.進入x265目錄造虏,創(chuàng)建 build.sh編譯腳本

vim build.sh
#!/bin/bash

PREFIX=./android/armeabi-v7a

TOOLCHAIN=$NDK_ROOT/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64

FLAGS="-isysroot $NDK_ROOT/sysroot -isystem $NDK_ROOT/sysroot/usr/include/arm-linux-androideabi -D__ANDROID_API__=17 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -march=armv7-a -mfloat-abi=softfp -mfpu=vfpv3-d16 -mthumb -Wa,--noexecstack -Wformat -Werror=format-security  -O0 -fPIC"
#--disable-cli 不需要命令行工具
#--enable-static 靜態(tài)庫
#和ffmpeg差不多
./configure \
--prefix=$PREFIX \
--disable-cli \
--enable-static \
--enable-pic \
--host=arm-linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--sysroot=$NDK_ROOT/platforms/android-17/arch-arm \
--extra-cflags="$FLAGS"

make clean
make install

3.修改 configure

編譯x264我們需要注意一點,x264在進行環(huán)境檢測的時候挟裂,使用的是比較寬松的方式栗竖,對于我們目前需要編譯的android-17為目標來說渠啤,編譯出的庫在使用上會出現(xiàn)問題(對于18以上不會)。(為什么有問題份名,錄了小視頻)

我們需要修改configure腳本,在腳本中搜索cc_check

vim如何搜索:在vim里底線命令模式辰如,輸入 /cc_check

cc_check() {
    ......
    if [ $compiler_style = MS ]; then
        cc_cmd="$CC conftest.c -Werror=implicit-function-declaration  $(cc_cflags $CFLAGS $CHECK_CFLAGS $2) -link $(cl_ldflags $2 $LDFLAGSCLI $LDFLAGS)"
    else
        cc_cmd="$CC conftest.c -Werror=implicit-function-declaration  $CFLAGS $CHECK_CFLAGS $2 $LDFLAGSCLI $LDFLAGS -o conftest"
    fi
    ......
}  

cc_cmd內(nèi)添加 -Werror=implicit-function-declaration 琉兜。

  1. 執(zhí)行 ./build.sh (第一次編譯需要添加權(quán)限 chmod +x build.sh)

生成好的包會在 android目錄下漆际。

將這個目錄下的 include 和lib目錄copy到項目的 app/src/main/cpp/下

5.配置app中的CmakeLists.txt

app/CMakeLists.txt中導(dǎo)入這個CMakeLists.txt

cmake_minimum_required(VERSION 3.4.1)

# 引入指定目錄下的CMakeLists.txt
add_subdirectory(src/main/cpp/librtmp)

add_library(
             native-lib

             SHARED

             src/main/cpp/native-lib.cpp )

include_directories(src/main/cpp/include)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -L${CMAKE_SOURCE_DIR}/src/main/cpp/libs/${ANDROID_ABI}")

target_link_libraries( native-lib
                       rtmp
                       x264
            log)

4.RTMP視頻數(shù)據(jù)

RTMP視頻流格式與FLV很相似,通過查看FLV的格式文檔奸汇,就能夠知道RTMP視頻數(shù)據(jù)應(yīng)該怎么拼接施符。

RTMP中的數(shù)據(jù)就是由FLV的TAG中的數(shù)據(jù)區(qū)構(gòu)成往声。

flv整體格式.jpg

FLV tags 結(jié)構(gòu)


字段 字節(jié) 描述
類型 1 0x08: 音頻
0x09: 視頻
0x12: 腳本(描述信息)
數(shù)據(jù)大小 3 數(shù)據(jù)區(qū)的大小,不包括包頭戳吝。
時間戳 3 當(dāng)前幀相對時間戳浩销,單位是毫秒。相對于第一個TAG時戳听哭。
時戳擴展 1 如果時戳大于0xFFFFFF慢洋,將會存在字節(jié)。
流ID 3 總是0
數(shù)據(jù)區(qū) n 音、視頻包
flv解碼配置信息.png

視頻數(shù)據(jù)

字段 占位 描述
幀類型 4 1: 關(guān)鍵幀
2: 普通幀
......
編碼ID 4 7: 高級視頻編碼 AVC
......
視頻數(shù)據(jù) n AVC則需要下面的AVCVIDEOPACKET

AVCVIDEOPACKET

字段 字節(jié) 描述
類型 1 0:AVC 序列頭(指導(dǎo)播放器如何解碼)
1:其他單元(其他NALU)
合成時間 3 對于AVC,全為0
數(shù)據(jù) n 類型不同蜒车,數(shù)據(jù)不同
flv解碼序列包.png
AVC 序列頭

在AVCVIDEOPACKET 中如果類型為0,則后續(xù)數(shù)據(jù)為:

類型 字節(jié) 說明
版本 1 0x01
編碼規(guī)格 3 sps[1]+sps[2]+sps[3] (后面說明)
幾個字節(jié)表示 NALU 的長度 1 0xFF屁置,包長為 (0xFF& 3) + 1使鹅,也就是4字節(jié)表示
SPS個數(shù) 1 0xE1冰沙,個數(shù)為0xE1 & 0x1F 也就是1
SPS長度 2 整個sps的長度
sps的內(nèi)容 n 整個sps
pps個數(shù) 1 0x01侥啤,不用計算就是1
pps長度 2 整個pps長度
pps內(nèi)容 n 整個pps內(nèi)容
flv解碼序列包sps與pps.png
其他

在AVCVIDEOPACKET 中如果類型為1,則后續(xù)數(shù)據(jù)為:

類型 字節(jié) 說明
包長 由AVC 序列頭中定義 后續(xù)長度
數(shù)據(jù) n H.264數(shù)據(jù)

一般情況下,組裝的RTMPPacket(RTMPDump中的結(jié)構(gòu)體)為:


[圖片上傳中...(視頻解碼序列包.png-84b251-1537358987761-0)]
視頻解碼序列包.png

NALU

NALU就是NAL UNIT邮府,nal單元。NAL全稱Network Abstract Layer, 即網(wǎng)絡(luò)抽象層,H.264在網(wǎng)絡(luò)上傳輸?shù)慕Y(jié)構(gòu)粟焊。一幀圖片經(jīng)過 H.264 編碼器之后沾乘,就被編碼為一個或多個片(slice)滥崩,而裝載著這些片(slice)的載體短条,就是 NALU 了 。

我們通過x264編碼獲得一組或者多組 `x264_nal_t`渠牲。結(jié)合RTMP芹壕,我們需要區(qū)分的是SPS序宦、PPS厚宰、關(guān)鍵幀與普通幀:
enum nal_unit_type_e
{
    NAL_UNKNOWN     = 0,
    NAL_SLICE       = 1,
    NAL_SLICE_DPA   = 2,
    NAL_SLICE_DPB   = 3,
    NAL_SLICE_DPC   = 4,
    NAL_SLICE_IDR   = 5,    /* ref_idc != 0 */      //關(guān)鍵幀片
    NAL_SEI         = 6,    /* ref_idc == 0 */
    NAL_SPS         = 7,                          //sps片
    NAL_PPS         = 8,                          //pps片
    NAL_AUD         = 9,
    NAL_FILLER      = 12,
    /* ref_idc == 0 for 6,9,10,11,12 */
};

IDR

一段h264視頻由N組GOP(group of picture)組成礁击,GOP指的就是畫面組测垛,一個GOP是一組連續(xù)的畫面 食侮。之前的學(xué)習(xí)中我們知道I幀能夠獨立解碼眉尸,而P慢宗、B需要參考其他幀筹我。

屬于I幀的子集岸夯,有一種特殊的I幀麻献,被稱之為IDR幀,IDR幀的作用為即時刷新猜扮。
GOP.png

上面的這張圖片描述的是2組GOP勉吻。其他I幀與IDR幀的區(qū)別就在于:刷新。當(dāng)解碼器解碼幀5的時候旅赢,可以跨過幀4參考到幀3齿桃,普通I幀不會導(dǎo)致解碼器的解碼信息數(shù)據(jù)刷新。而IDR幀則會刷新解碼需要的SPS煮盼、PPS數(shù)據(jù)短纵,所以幀8不可能跨幀7參考解碼。

H.264數(shù)據(jù)

往RTMP包中填充的是H.264數(shù)據(jù)僵控,但不是直接將x264編碼出來的數(shù)據(jù)填充進去香到。

一段包含了N個圖像的H.264裸數(shù)據(jù),每個NAL之間由:

00 00 00 01 或者 00 00 01

進行分割报破。在分割符之后的第一個字節(jié)悠就,就是表示這個nal的類型。

0x67:sps 0x68:pps 0x65:IDR

即為上面的

NAL_SLICE_IDR 0x65& 0x1f = 5

NAL_SPS 0x67 & 0x1f = 7,
NAL_PPS 0x68 & 0x1f= 8,

在將數(shù)據(jù)加入RTMPPacket的時候是需要去除分割符的充易。


h264.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末理卑,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蔽氨,更是在濱河造成了極大的恐慌帆疟,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,265評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件宇立,死亡現(xiàn)場離奇詭異踪宠,居然都是意外死亡,警方通過查閱死者的電腦和手機妈嘹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,078評論 2 385
  • 文/潘曉璐 我一進店門柳琢,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人润脸,你說我怎么就攤上這事柬脸。” “怎么了毙驯?”我有些...
    開封第一講書人閱讀 156,852評論 0 347
  • 文/不壞的土叔 我叫張陵倒堕,是天一觀的道長。 經(jīng)常有香客問我爆价,道長垦巴,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,408評論 1 283
  • 正文 為了忘掉前任铭段,我火速辦了婚禮骤宣,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘序愚。我一直安慰自己憔披,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 65,445評論 5 384
  • 文/花漫 我一把揭開白布爸吮。 她就那樣靜靜地躺著活逆,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拗胜。 梳的紋絲不亂的頭發(fā)上蔗候,一...
    開封第一講書人閱讀 49,772評論 1 290
  • 那天,我揣著相機與錄音埂软,去河邊找鬼锈遥。 笑死,一個胖子當(dāng)著我的面吹牛勘畔,可吹牛的內(nèi)容都是我干的所灸。 我是一名探鬼主播,決...
    沈念sama閱讀 38,921評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼炫七,長吁一口氣:“原來是場噩夢啊……” “哼爬立!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起万哪,我...
    開封第一講書人閱讀 37,688評論 0 266
  • 序言:老撾萬榮一對情侶失蹤侠驯,失蹤者是張志新(化名)和其女友劉穎抡秆,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吟策,經(jīng)...
    沈念sama閱讀 44,130評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡儒士,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,467評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了檩坚。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片着撩。...
    茶點故事閱讀 38,617評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖匾委,靈堂內(nèi)的尸體忽然破棺而出拖叙,到底是詐尸還是另有隱情,我是刑警寧澤赂乐,帶...
    沈念sama閱讀 34,276評論 4 329
  • 正文 年R本政府宣布薯鳍,位于F島的核電站,受9級特大地震影響沪猴,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜采章,卻給世界環(huán)境...
    茶點故事閱讀 39,882評論 3 312
  • 文/蒙蒙 一运嗜、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧悯舟,春花似錦担租、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,740評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至反惕,卻和暖如春尝艘,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背姿染。 一陣腳步聲響...
    開封第一講書人閱讀 31,967評論 1 265
  • 我被黑心中介騙來泰國打工背亥, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人悬赏。 一個月前我還...
    沈念sama閱讀 46,315評論 2 360
  • 正文 我出身青樓狡汉,卻偏偏與公主長得像,于是被迫代替她去往敵國和親闽颇。 傳聞我的和親對象是個殘疾皇子盾戴,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,486評論 2 348

推薦閱讀更多精彩內(nèi)容