.環境準備
先看看一個流媒體服務器應用場景,如下是一個安防場景。
服務器:SRS(Simple RTMP Server,?持RTMP、HTTP-FLV,HLS)
推流端:ffmpeg 、 OBS
拉流端:ffplay 、VLC 、 srs播放器
srs在github上的官網:https://github.com/ossrs/srs
非常好用的流媒體集群,具有非常詳細的文檔。作者現在已經是阿里釘釘的后臺CTO。他也是因為這個這個寫出這個SRC框架被發現。
SRS在碼云的官網:https://gitee.com/winlinvip/srs.oschina
關于代碼提交,請參考這個鏈接地址:
https://github.com/ossrs/srs/wiki/v1_CN_Git
如圖所示:
選擇通過碼云下載,速度快。選擇當前比較新的release版本3.0
命令:git clone https://gitee.com/winlinvip/srs.oschina.git
下載完畢后,進入此目錄。
可以看出4.0都出來了,但是穩定可靠的還是3.0,所以這里就選擇3.0。
選擇3.0,切換到3.0release分支。關于git使用,后面再多寫幾篇文章。
git checkout -b 3.0 remotes/origin/3.0release
進入trunk目錄:
開始編譯srs。這個過程大概需要幾分鐘。
./configure && make
./configure編譯過程如下:
./configure結束如下:
然后make
make過程如下:
make結束如下,代表編譯完成:
目錄如下:
修改配置文件:vim conf/rtmp.conf,如下路徑:
修改前配置如下:
修改后配置如下:
使用#注釋,否則有可能出錯。
listen 1935表示rtmp協議默認端口號是1935。
max_connections 1000:表示默認支持1000連接。
經過上面步驟后,就啟動srs。-c表示讀取配置文件。
./objs/srs -c conf/rtmp.conf
這個時候,就表示啟動成功了。
查看日志:tail -f ./objs/srs.log,出現如下界面,表示啟動成功。
可以通過lsof -i:1935,查看是哪個進程占用了這個端口號。
使用?FFMPEG命令推流,需要提前搭建好ffmpeg環境:檢驗測試效果。
這里的live就表示是一個欄目,比如電影,這里的livestream表示具體的電影名字。
注意:需要使用自己的ip。rtmp.flv這個文件換成自己的文件。
需要先切換到rtmp.flv這個目錄。比如我這里是這個路徑。
ffmpeg -re -i rtmp.flv -vcodec copy -acodec copy -f flv -y rtmp://172.16.204.132/live/livestream
表示正在推流:
使用ffplay或VLC或其它拉流工具都是可以。表示正在拉流:
ffplay rtmp://172.16.204.132/live/livestream
出現如下拉流畫面,就說明跑通了。
服務器,這邊就收到很多消息。如下界面:
你也可以使?在線SRS播放器播放:
http://ossrs.net/srs.release/trunk/research/players/srs_player.html?vhost=__defaultVhost__&autostart=true&server=192.168.1.170&app=live&stream=livestream&port=1935
如下圖:
關于SRS的RTMP分發推流,可以參看官網這個鏈接地址:
https://github.com/ossrs/srs/wiki/v1_CN_DeliveryRTMP
2.使用OBS推流
如果你覺得ffmpeg的命令??式不太友好,推薦使?主流的OBS開源推流軟件,可從官?https://obsproject.com/下載最新版本,?前很多?絡主播都是?它做直播。該軟件?持本地視頻?件以及攝像頭推流?;蚴?:https://pc.qq.com/detail/4/detail_23604.html 去普通下載。
官網:
這里演示下文件推流:
選擇本地視頻文件。填入本地文件的地址。
接下來是關鍵的部分,進?設置:
在串流->服務器這?,輸?srs的地址:rtmp://192.168.1.11:1935/live (注意這?不要帶livestream), 然后在串流密鑰這?,才是輸?livestream
設置好以后,就可以點擊“開始推流”了。如果順利,下?的狀態欄,會顯示?些實時數據:
注意:OBS進?推流占?率?較?(實際CPU占有率 還好,內有那么高),原因在于osb在推流時對源?件進?了解碼再編碼的操作。obs也能捕獲聲音,是一款非常好用的工具,還包括了錄制等功能,所以這個也是非常值得學習和使用。
點擊開始推流,服務器這里會收到消息:如下
同樣使用ffplay拉流即可。ffplay rtmp://172.16.204.132/live/livestream
拉流畫面如下:
同時服務器會收到,有客戶端連接消息。
使用攝像頭推流
這里與推文件流,實際差不多,區別只是添加“視頻捕捉設備”。
采集畫面,默認配置如下:
接下來的操作就與推文件流?樣了(但是CPU占有率上來了),如下:
更多關于obs設置,可以參考如下鏈接:
https://cloud.tencent.com/document/product/267/32726
界面如下:
這里有非常多的設置地址,如下:
通過github下載速度慢。
命令:https://github.com/ossrs/srs.git
本篇文章,非常詳細的講解了,如何去搭建Rtmp流媒體服務器,是學習流媒體開發必須學會的技術,希望對你有幫助。
創作不易,歡迎關注,點贊,轉發,分享。
后面關于項目知識,后期會更新。歡迎關注微信公眾號"記錄世界 from antonio"。
、ffmpeg介紹
文章最后有福利
FFmpeg是一套可以用來記錄、轉換數字音頻、視頻,并能將其轉化為流的開源計算機程序。采用LGPL或GPL許可證。它提供了錄制、轉換以及流化音視頻的完整解決方案。它包含了非常先進的音頻/視頻編解碼庫libavcodec,為了保證高可移植性和編解碼質量,libavcodec里很多code都是從頭開發的。
框圖如圖所示:
二、編解碼基礎知識
(1)封裝格式
所謂封裝格式是指音視頻的組合格式,例如最常見的封裝格式有mp4、mp3、flv等。簡單來說,我們平時接觸到的帶有后綴的音視頻文件都是一種封裝格式。
(2)編碼格式
以mp4為例,通常應該包含有視頻和音頻。視頻的編碼格式為YUV420P,音頻的編碼格式為PCM。再以YUV420編碼格式為例。我們知道通常圖像的顯示為RGB(紅綠藍三原色),在視頻壓縮的時候會首先將代表每一幀畫面的RGB壓縮為YUV,再按照關鍵幀(I幀),過渡幀(P幀或B幀)進行運算和編碼。解碼的過程正好相反,解碼器會讀到I幀,并根據I幀運算和解碼P幀以及B幀。并最終根據視頻文件預設的FPS還原每一幀畫面的RGB數據。最后推送給顯卡。所以通常我們說的編碼過程就包括:畫面采集、轉碼、編碼再封裝。
(3)視頻解碼和音頻解碼有什么區別
FPS是圖像領域中的定義,是指畫面每秒傳輸幀數,通俗來講就是指動畫或視頻的畫面數。FPS太低畫面會感覺閃爍不夠連貫,FPS越高需要顯卡性能越好。一些高速攝像機的采集速度能夠達到11000幀/秒,那么在播放這類影片的時候我們是否也需要以11000幀/秒播放呢?當然不是,通常我們會按照25幀/秒或者60幀/秒設定圖像的FPS值。但是由于視頻存在關鍵幀和過渡幀的區別,關鍵幀保存了完整的畫面而過渡幀只是保存了與前一幀畫面的變化部分,需要通過關鍵幀計算獲得。因此我們需要對每一幀都進行解碼,即獲取畫面的YUV數據。同時只對我們真正需要顯示的畫面進行轉碼,即將YUV數據轉換成RGB數據,包括計算畫面的寬高等。
三、代碼實現
(1)注冊FFmpeg組件
//注冊和初始化FFmpeg封裝器和網絡設備
(2)打開文件和創建輸入設備
AVFormatContext 表示一個封裝器,
在讀取多媒體文件的時候,它負責保存與封裝和編解碼有關的上下文信息。
(3)遍歷流并初始化解碼器
封裝器中保存了各種流媒體的通道,通常視頻通道為0,音頻通道為1。
除此以外可能還包含字幕流通道等。
第2步和第3步基本就是打開多媒體文件的主要步驟,
解碼和轉碼的所有參數都可以在這里獲取。
接下來我們就需要循環進行讀取、解碼、轉碼直到播放完成。
(4)讀取壓縮數據
/*之所以稱為壓縮數據主要是為了區分AVPacket和AVFrame兩個結構體。
AVPacket表示一幅經過了關鍵幀或過渡幀編碼后的畫面,
AVFrame表示一個AVPacket經過解碼后的完整YUV畫面*/
(5)解碼
(6)視頻轉碼
// 720p輸出標準
/*
這里需要解釋一下outWidth * outHeight * 4計算理由:
720p標準的視頻畫面包含720 * 480個像素點,
每一個像素點包含了RGBA4類數據,每一類數據分別由1個byte即8個bit表示。
因此一幅完整畫面所占的大小為outWidth * outHeight * 4。
(7)音頻轉碼
四、代碼地址
基于qt的FFmpeg客戶端(Linux版本):
服務端可采用LIVE555服務器 ,參考博文:
零 背景知識
本章主要介紹一下FFMPEG都用在了哪里(在這里僅列幾個我所知的,其實遠比這個多)。說白了就是為了說明:FFMPEG是非常重要的。
使用FFMPEG作為內核視頻播放器:
使用FFMPEG作為內核的Directshow Filter:
使用FFMPEG作為內核的轉碼工具:
事實上,FFMPEG的視音頻編解碼功能確實太強大了,幾乎囊括了現存所有的視音頻編碼標準,因此只要做視音頻開發,幾乎離不開它。
FFmpeg項目由以下幾部分組成:
1.2 誰在使用ffmpeg
2.如何安裝
FFmpeg可以在Windows、Linux還有Mac OS等多種操作系統中進行安裝和使用。
FFmpeg分為3個版本:Static、 Shared、 Dev
3.怎么使用
3.1 命令行工具的使用
3.11 ffmpeg.exe
用于轉碼的應用程序:
ffmpeg -i input.avi -b:v 640k output.ts
具體用法參考: ffmpeg參數中文詳細解釋
詳細的使用說明(英文):http://ffmpeg.org/ffmpeg.html
3.12 ffplay.exe
主要用于播放的應用程序
播放test.avi
ffplay test.avi
具體的使用方法可以參考:ffplay的快捷鍵以及選項
3.13 ffprobe.exe
ffprobe是用于查看文件格式的應用程序。
3.2 使用ffmpeg庫進行開發
To Be Continue...
FFmpeg基本環境搭建及編譯
FFmpeg的解封裝基本處理
FFmpeg用于硬件設備解碼的關鍵擴展數據處理
FFmpeg用于硬件的track mode基本控制
虛擬機安裝
由于是在自己家里,不是工作環境,電腦還是裝的windows7系統,于是開始安裝虛擬機,我平時一直都喜歡用VMWare這個虛擬機,上次買了新電腦后一直都沒有安裝,這次必須先安裝上。先是安裝了最新的VMWare Workstation 11 + Ubuntu14.04,發現跑起來巨慢無比,難道是我的電腦落伍了?沒有辦法,也不想去折騰這個事情,還是老老實實換了一個VMWare Workstation 10.0.1 build-1379776 + Ubuntu-12.04.4-alternate-i386,最好跑起來還湊合。具體虛擬機和Ubuntu的安裝過程就不詳述了,網上文章一大堆。
配置并編譯
下載最新版本的ffmpeg,目前穩定版本是ffmpeg-2.6.1。進入虛擬機解壓:
配置
然后進行make編譯,最后出現錯誤:
原來忽略了直接在windows的共享目錄中,解壓到Linux目錄中便不會出現這個問題了。當然如果我們編譯的不是共享庫,而是靜態庫,也不會出現這個問題,因為沒有Linux的鏈接文件。
在Linux目錄下,編譯成功,生成我們的動態庫:
這樣我們生產了我們需要的動態庫和頭文件。
大家可能糊涂了,我現在是在pc上編譯的,不能用于嵌入式設備上。這個我知道,我也沒有辦法,現在我已經沒有以前的那些ARM的編譯環境。大家如果是在實際的交叉環境下,配置ffmpeg的configure時指定交叉編譯參數,估計大概如下面的配置:
./configure --prefix=./install --disable-static --enable-shared --enable-gpl --enable-pthreads --cross-prefix=arm-none-linux-gnueabi- --enable-cross-compile --target-os=linux --extra-cflags="-mcpu=arm9 -W -Wall -Wpointer-arith -Wstrict-prototypes -Winline -Wundef -O2 -Wall" --arch=armv4l --cpu=arm9
當然這些既是根據具體的環境修改了。這里就不多說,本文只有在PC上來講解。
視頻大小
ntsc:408P,對應分辨率為720*480,建議碼率為1800Kbps
snits:對應分辨率640*480
hd720:720P,對應分辨率為1280*720,建議碼率為3500Kbps
hd1080:1080P,對應分辨率為1920*1080,建議碼率為8500Kbps
可變碼率(VBR):動態比特率編碼,指編碼器的輸出碼率可以根據編碼器輸入源信號的復雜度自適應調整,目前是達到輸出質量保持不變。VBR適于存儲,不適合流式傳輸,它能有效利用有限空間。
固定碼率(CBR):指編碼器輸出碼率固定,不適合存儲,CBR對于復雜內容可能沒有足夠碼率進行編碼,
幀數:每秒鐘播放的圖片數(fps)。高的幀率可以得到更流暢、更逼真的畫面。但是幀率很大會浪費圖形處理的能力,因為顯示器不能以更快的速度更新,則超過刷新率的幀率就浪費掉。同一視頻,統一碼率情況下,幀數越多,畫質越不好。因為每張畫面會分擔每秒有限的文件體積,如果畫面越多,那么每張畫面所能表現的內容越有限。一般30fps就基本流暢,50fps就有行云流水感覺,很難區分60fps與100fps區別。
分辨率:畫面大小,單位是像素。和編碼率的關系:越高的分辨率,需要越高的編碼率。因為圖像細節多,需要文件體積大。同一碼率,畫面越大,圖像馬賽克程度越明顯。
采樣率:每秒鐘對音頻信號的采樣次數,采樣率越高聲音還原度越高,聲音越自然,單位Hz。一般音頻文件采樣率44100Hz,即1秒鐘采樣44100次。低于這個值,聲音會有明顯損失,高于這個值,人耳難以分辨,同時會增加音頻文件所占用的空間。
參考資料 :私信‘資料'可MF領取相關資料,C++、linux,
第一時間獲得博客更新提醒,以及更多技術信息分享,歡迎關注私信我,
1.直接幫你解答ffmpeg相關疑問c++。linux,TCP。
2.第一時間獲得業內十多個領域技術文章
3.針對文章內疑點提出問題,第一時間回復你,幫你耐心解答
4.讓你和原創作者成為很好的朋友,拓展自己的人脈資源
Fmpeg簡介
FFmpeg既是一款音視頻編解碼工具,同時也是一組音視頻編解碼開發套件,作為編解碼開發套件,它為開發者提供了豐富的音視頻處理的調用接口。 FFmpeg提供了多種媒體格式的封裝和解封裝,包括多種音視頻編碼、多種協議的流媒體、多種色彩格式轉換、多種采樣率轉換、多種碼率轉換等。FFmpeg框架提供了多種豐富的插件模塊,包含封裝與解封裝的插件、編碼與解碼的插件等。
開發環境
本次編譯的環境如下:
首先下載ndk,建議不要使用Android Studio自帶的ndk-bundle,然后配置ndk的全局環境,在.bash_profile中添加一下配置:
export ANDROID_NDK_ROOT=/Users/jiangshuaijie/android-ndk-r14b/build
export PATH=${PATH}:${ANDROID_NDK_ROOT}
然后在命令行中輸入ndk-build測試環境是否配置成功。
下載FFmpeg源碼
FFmpeg的源碼可以在 https://ffmpeg.org/download.html#releases 中下載,也可以使用git clone https://git.ffmpeg.org/ffmpeg.git ffmpeg 克隆到本地。建議下載3.3.x版本的庫,最新的庫編譯的問題比較多,各種路徑不正常等問題。
相關學習資料推薦,點擊下方鏈接免費報名,先碼住不迷路~】
音視頻免費學習地址:FFmpeg/WebRTC/RTMP/NDK/Android音視頻流媒體高級開發
【免費分享】音視頻學習資料包、大廠面試題、技術視頻和學習路線圖,資料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以點擊788280672加群免費領取~
修改configure文件
下載FFmpeg源代碼之后,首先需要對源代碼中的configure文件進行修改。由于編譯出來的動態庫文件名的版本號在.so之后(例如“libavcodec.so.5.100.1”),而android平臺不能識別這樣文件名,所以需要修改這種文件名。在configure文件中找到下面幾行代碼:
SLIBNAME_WITH_MAJOR='$(SLIBNAME).$(LIBMAJOR)'
LIB_INSTALL_EXTRA_CMD='?(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_VERSION)'
SLIB_INSTALL_LINKS='$(SLIBNAME_WITH_MAJOR)$(SLIBNAME)'
替換成
SLIBNAME_WITH_MAJOR='$(SLIBPREF)$(FULLNAME)-$(LIBMAJOR)$(SLIBSUF)'
LIB_INSTALL_EXTRA_CMD='?(RANLIB)"$(LIBDIR)/$(LIBNAME)"'
SLIB_INSTALL_NAME='$(SLIBNAME_WITH_MAJOR)'
SLIB_INSTALL_LINKS='$(SLIBNAME)'
在ffmpeg中創建一個build_android.sh的腳本,并賦予可執行的權限,腳本內容如下:
#!/bin/bash
make clean
# NDK的路徑,根據自己的安裝位置進行設置
export TMPDIR=/Users/jiangshuaijie/ffmpeg-3.3.7/ffmpeg_install
export NDK=/Users/jiangshuaijie/android-ndk-r14b
export SYSROOT=$NDK/platforms/android-21/arch-arm/
export TOOLCHAIN=$NDK/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64
export CPU=arm
export PREFIX=$(pwd)/android/$CPU
export ADDI_CFLAGS="-marm"
function build_one
{
./configure \
--prefix=$PREFIX \
--target-os=linux \
--cross-prefix=$TOOLCHAIN/bin/arm-linux-androideabi- \
--arch=arm \
--sysroot=$SYSROOT \
--extra-cflags="-Os -fpic $ADDI_CFLAGS" \
--extra-ldflags="$ADDI_LDFLAGS" \
--cc=$TOOLCHAIN/bin/arm-linux-androideabi-gcc \
--nm=$TOOLCHAIN/bin/arm-linux-androideabi-nm \
--enable-shared \
--enable-runtime-cpudetect \
--enable-gpl \
--enable-small \
--enable-cross-compile \
--disable-debug \
--disable-static \
--disable-doc \
--disable-asm \
--disable-ffmpeg \
--disable-ffplay \
--disable-ffprobe \
--disable-ffserver \
--enable-postproc \
--enable-avdevice \
--disable-symver \
--disable-stripping \
$ADDITIONAL_CONFIGURE_FLAG
sed -i '' 's/HAVE_LRINT 0/HAVE_LRINT 1/g' config.h
sed -i '' 's/HAVE_LRINTF 0/HAVE_LRINTF 1/g' config.h
sed -i '' 's/HAVE_ROUND 0/HAVE_ROUND 1/g' config.h
sed -i '' 's/HAVE_ROUNDF 0/HAVE_ROUNDF 1/g' config.h
sed -i '' 's/HAVE_TRUNC 0/HAVE_TRUNC 1/g' config.h
sed -i '' 's/HAVE_TRUNCF 0/HAVE_TRUNCF 1/g' config.h
sed -i '' 's/HAVE_CBRT 0/HAVE_CBRT 1/g' config.h
sed -i '' 's/HAVE_RINT 0/HAVE_RINT 1/g' config.h
make clean
# 這里是定義用幾個CPU編譯,我用4個,一般在5分鐘之內編譯完成
make -j4
make install
}
build_one
其中:
在ffmpeg目錄中,執行終端命令:
./build_android.sh
即可編譯,然后等待生成so文件即可。
原文 Mac中編譯FFmpeg教程(Android版) - 掘金
*請認真填寫需求信息,我們會在24小時內與您取得聯系。