服务器端
开源的rtmp服务器在网上主要有这样几种:crtmpserver,nginx-rtmp-module,Red5,FluorineFx等。
crtmpserver
在ubuntu下,获取软件自然先从apt-get开始。
$ sudo apt-get install crtmpserver
使用apt-get方式安装的crtmpserver默认配置在/etc/crtmpserver目录下。此时,这个服务器已经可以运行。
apt-get所下载下来的长时间运行的程序基本上会在/etc/init.d下有一个接受start, stop, restart等命令的脚本,而crtmpserver也不例外。所以,直接使用该脚本启动服务器即可。
$ sudo /etc/init.d/crtmpserver start
* Starting c++ RTMP Server crtmpserver [ OK ]
但为了确保服务器的运行符合我们的预期,需要检查一下配置文件。通过查看 /etc/init.d/crtmpserver 脚本,可以看到默认配置文件为 /etc/crtmpserver/crtmpserver.lua。
再通过查看配置文件,最终定位到applications目录下的appselector.lua文件。文件内容如下
application =
{
......
default = true,
acceptors =
{
{
ip = "0.0.0.0",
prot = 1935,
protocol = "inboundRtmp"
}
......
}
}
以上配置文件说明,该applications为默认app,接受所有的连接请求,同时,绑定本机所有ip上的1935端口,协议为Rtmp协议。该配置满足我们的要求。
至此,一个支持rtmp协议的服务器已经搭建完毕。
Nginx
Nginx也包括在在ubuntu下的包管理器中,但是,从服务器下载的是已经编译好的Nginx。而Nginx添加模块的方式需要重新编译,此时,我们需要自己编译Nginx。
编译步骤也很简单,按照rtmp-module Github页面上的流程进行即可。
$ cd /path/to/nginx_source_code
$ ./configure --add-module=/path/to/nginx-rtmp-module
$ make
$ make install
make install之后,Nginx被安装到了/usr/local/nginx目录下,通过编辑./conf/nginx.conf配置文件,即可使用rtmp模块。
......
rtmp {
server {
listen 1935;
chunk_size 4096;
application live{
live on;
record off;
}
}
}
如上的配置表示这是一个rtmp模块,监听端口1935,直播模式为开,并且不记录为文件。该application接受型为rtmp://xx.xx.xx.xx:1935/live/xxxx的地址。
配置完成后使用命令打开服务器,即可开始使用Nginx服务器。
$ /usr/local/nginx/sbin/nginx -t
客户端
当然,口说无凭,服务器能否使用自然需要一些方式来验证。由于rtmp协议有着三方的共同参与:服务器、推流和拉流。所以,为验证服务器的可用性需要构建出一个推流端以及至少一个拉流端进行验证。
拉流
获取总是比创造容易。视频直播流的获取也比发送方便很多。
推荐使用VLC与SRS播放器。VLC在ubuntu下可以由apt-get获取。
推流
推流的工具有很多,常见的有图形化的OBS以及命令行下的FFmpeg。
OBS
该软件被用于各大视频网站的直播中,支持摄像头捕获、屏幕分享等各种常用功能。
最简单的获取方式依然是apt-get包管理器。
$ sudo add-apt-repository ppa:obsproject/obs-studio
$ sudo apt-get update && sudo apt-get install obs-studio
下载完毕之后,需要进行配置后才可使用。首先,在 File/Settings 选项卡中,选择Stream配置项。将Stream Type改为Custom Streaming Server。而后url填写crtmpserver的端口地址即可。
此时,OBS会将流量发送至rtmp://127.0.0.1:1935/livd/test这个地址,而拉流也是通过这个地址。
FFmpeg
我们的应用的需求并没有涉及到复杂的视频处理,而仅仅只是捕获摄像头数据并按照rtmp格式传输即可。同时,并不是每一个客户端均支持图形化配置运行界面,所以,可能需要一个新的选择。
而FFmpeg作为一个老牌的多媒体编解码框架,同时也提供了发送流媒体的能力,与我们的需求吻合。
$ ls /dev/video*
/dev/video0
$ ffmpeg -f v4l2 -list_formats all -i /dev/video0
[video4linux2,v4l2 @ 0x2074920] Raw : yuyv422 : YUV 4:2:2 (YUYV) : 640x480 352x288 320x240 176x144 160x120 1280x720 640x480
[video4linux2,v4l2 @ 0x2074920] Compressed: mjpeg : MJPEG : 640x480 352x288 320x240 176x144 160x120 1280x720 640x480
/dev/video0: Immediate exit requested
$ ffmpeg -f v4l2 -video_size 640x480 -i /dev/video0 -f flv rtmp://127.0.0.1:1935/live/test
以上命令获取了当前电脑的视频设备,并通过ffmpeg查看了具体的摄像机细节。最后一条命令则是开始向地址rtmp://127.0.0.1:1935/live/test进行推流。
当然,ffmpeg也可以使用文件作为流输入。
$ ffmpeg -i 这个杀手不太冷.rmvb -f flv rtmp://127.0.0.1:1935/live/test
一些问题
在实践过程中,可能会发生FFmpeg与crtmpserver不兼容的问题,例如说
[rtmp @ 0x18aa360] Server error: Specified stream not found in call to releaseStream
[rtmp @ 0x18aa360] Sending publish command for 'test2'
[rtmp @ 0x18aa360] Server error: call to function _checkbw failed
或者
HandShake: client signature does not match!
此时可以试着使用
ffmpeg ... ... -f flv -metadata streanName="test" tcp://localhost:6666
来尝试解决。此时6666端口使用的是crtmpserver所带的application文件flvplayback.lua。而原来所使用的1935端口是在appselector.lua中定义。
同时,还可以修改上述两个配置文件中的validateHandshake字段为false放行未匹配的客户端。但是,就我本人实验而言,没有特别大效果。
最终项目使用以下命令成功在树莓派上实现摄像头推流。
raspivid -t -1 -w 960 -h 540 -fps 25 -b 500000 -vf -o - | ffmpeg -i - -vcodec copy -an -r 25 -f flv -metadata streamName=test tcp://remote_server_ip:6666
参考资料
- crtmpserver流媒体服务器的介绍与搭建
- crtmpserver配置文件分析
- Nginx rtmp协议的流媒体服务器
- nginx+nginx-rtmp-module+ffmpeg搭建流媒体服务器
- ubuntu下安装nginx + nginx-rtmp-module
- Github: nginx-rtmp-module
- 斗鱼游戏直播教程-OBS直播软件篇
- FFMpeg处理RTMP流的总结
- FFMPEG 摄像头 命令行参数 录像 直播 rtmp
- FFmpeg wiki: Capture / Webcam
- FFmpeg wiki: StreamingGuide
- Streaming Raspberry Pi Camera H264 into HTML over RTMP