.环境准备
先看看一个流媒体服务器应用场景,如下是一个安防场景。
服务器: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小时内与您取得联系。