目录
windows平台
拉流
ffmpeg安装
推流服务器配置
nginx服务器配置
lalserver服务器配置(rtsp)
rtsp推流
Linux平台(ubuntu18.04)
换源
编译ffmpeg
下载源码
安装依赖库
配置并编译
配置环境
虚拟机推流
边缘计算推流
隐蔽的小坑
花屏问题
最近在工作上需要学习ffmpeg的推流,故撰写此文,以备日后之需。
windows平台
既然要推流,那肯定需要先拉流。由于我是刚接触这一块内容,没有使用IP摄像机,用的是USB摄像机,不过基本逻辑与方法大同小异(指在csdn上抄别人代码)。
拉流
拉流用的是opencv包,这里要注意安装的命令应该是pip install opencv-contrib-python 如果输入pip install opencv -python 安装的包在我的pc上不能读取摄像头数据。
通过cv2对摄像机图像信息进行补货,和IP摄像机不同的就是你的rtspurl是数字0或者1,取决于你的电脑有几个摄像头。
ffmpeg安装
今天不知道为什么我进不去这个界面,我从站里盗一张图(
下载完就是这个压缩包
找一个文件夹解压,之后把bin目录加入环境变量就行了。至此,windows平台的ffmpeg安装就ok了。
推流服务器配置
nginx服务器配置
刚开始我觉得rtsp和rtmp差不多,百度搜到一个rtmp的推流就用了。rtmp推流需要安装nginx服务器。基本流程如下:
1.下载nginx,下载nginx 1.7.11.3 Gryphon或更高版本,反正得是Gryphon这个。解压到你新建的文件夹里就行。这里举个例子就解压到nginx文件夹里了。不要着急双击nginx.exe,可能会有问题。
2.下载nginx-rtmp-module,解压后文件夹改名为nginx-rtmp-module,github下载后不是后面有个master嘛。改名后放到nginx文件夹里。
3.把nginx文件夹加入到环境变量。
4.进入nginx文件夹,找到conf文件夹里的 nginx.conf 文件并改名为nginx-win.conf。修改里面的配置文件。
监听端口还是80,rtmp的端口是默认的1935,想修改的可以自己改。
5.开启服务器
在nginx文件夹的地址栏输入cmd,在弹出的窗口里用命令开启服务器
输入之后没有弹出的信息,cmd窗口关了也不会关闭服务器。如果要彻底关闭可以用命令或者去任务管理器里面直接结束进程,一般都会有很多nginx.exe。如果你开启不了服务器也可以看看任务管理器里面有没有进程,都退了再用命令开启。然后在浏览器地址栏输入127.0.0.1如果看到下图就说明开启成功了。
这里有一个小坑,服务器只要打开过一次,在退出之后这个界面还会显示,多刷新两次看看还能不能显示。
lalserver服务器配置(rtsp)
因为我最终目的是进行rtsp推流,用nginx服务器不能推rtsp,只能推rtmp流。于是我在github上找到了一个非常好用的rtsp服务器,作者真的很厉害。
下载地址
官方文档
官方文档写的很详细,我再写就有点关公面前耍大刀的感觉了。 唯一要注意的就是在windows平台运行的时候我们不方便编译,就下载作者编译好的可执行二进制文件。下载好之后,把lalserver改后缀为.exe,然后把conf文件夹放在bin目录下。
在bin文件夹里面执行cmd,输入
就能开启服务器,非常简单吧。看看官方文档,还能加入鉴权防盗链,直接就把USB摄像机的功能提升到了IP摄像机的高度,好强的作者。
rtsp推流
这个问题站内全都是,直接搬运
这个里面用线程的那个思路很好,相当于建立了一个缓冲区。
直接上代码,功能为自动检测屏幕分辨率展示摄像机图像,综合了不少高人的代码用了一下。这里的地址是本机地址,/live/是推流的文件路径,不用管。后面的stream?这里是我用lalserver对推流操作进行了加密,官方文档里都有的。
connand_out的配置非常关键,80%的错都出在这了我。ffmpeg的路径我在windows平台下必须是绝对路径才能用。-i上面是解码,下面是编码。因为ffmpeg的原理就是解复用-解码-编码。
这一段代码的shell=True一定要有,这样才能调用命令行启动ffmpeg。
代码里有加互斥锁,展示的部分注释掉了。推流之后用imshow()去接收看看就好
按q可以退出。
Linux平台(ubuntu18.04)
由于第一次使用布谷鸟ADU502的边缘计算。属实有点难搞。在Linux平台下可以很方便的用源码进行ffmpeg的编译。不过之前需要先做一些准备工作。
换源
默认源是真的慢,安装配置环境本来就要很多,速度慢根本受不了。由于是ARM,换源的时候不要换成x86的了,不然还是不行。另外经过测试,清华源有点小问题,有的包apt还是找不到。所以我换了阿里源。
打开下载源,换成下面的。不过还是建议去阿里源自己找,万一更新了。
然后输入
结束了之后我们就能开始编译ffmpeg了。
编译ffmpeg
下载源码
终端输入,下载源码并解压。
在下载文件保存界面打开终端解压
安装依赖库
有一个库是ffplay,就是ffmpeg的播放器需要安装的依赖库,我安装的时候失败了。不过你如果不用ffplay,完全无伤大雅。
配置并编译
build是编译后的文件夹,名字可以自己改,后面--enable的是你编译之后希望ffmpeg额外具有的编码功能,我需要libx264,必须要加上,所以依赖库里面必须安装libx264-dev。
下面列出编译的选项,源链接
安装libx265
H.265/HEVC 视频编码器。版本 ≥ 68。
需要 ffmpeg 编译选项配置 --enable-gpl 和 --enable-libx265。
sudo apt-get install libx265-dev libnuma-dev
安装libvpx
VP8/VP9 视频编码、解码器。版本 ≥ 1.4.0。需要 ffmpeg 编译选项配置 --enable-libvpx。sudo apt-get install libvpx-dev
安装libfdk-aac
AAC 音频编码器。需要 ffmpeg 编译选项配置 --enable-libfdk-aac(如果配置包含了 --enable-gpl 需要同时添加 --enable-nonfree)。sudo apt-get install libfdk-aac-dev
安装libmp3lame
mp3 音频编码器。版本 ≥ 3.98.3。需要 ffmpeg 编译选项配置 --enable-libmp3lamesudo apt-get install libmp3lame-dev
安装libopus
Opus音频解码器和编码器。版本 ≥ 1.1。需要 ffmpeg 编译选项配置 --enable-libopus。`sudo apt-get install libopus-dev
配置环境
和在windows环境中一样,需要配置环境才能使用。先增加安装目录的动态链接库
在末尾加上你编译好的ffmpeg的lib路径,按照咱们的流程,路径就是:
保存后,输入
这里不设置,会报错找不到lib
然后把bin文件添加到环境变量中
在末尾加入
最后在终端输入
激活之后再终端输入ffmpeg,会显示版本信息,就说明搞定了。如果不行,重启终端在试试。
虚拟机推流
有个大佬写了多线程队列的推流方法,非常巧妙。贴一下他的链接。
在虚拟机环境下和window环境下的最大不同就是摄像机地址和管道的配置,先上代码
通过以下命令获得摄像机编号
这样就能在linux环境下找到摄像机地址。然后在虚拟机环境下ffmpeg的路径也要是绝对路径,不知道为什么,明明环境变量都添加了。
还有就是这个里面的shell一定要是False,不然不能运行。
边缘计算推流
这下代码就不一样了,这里也是坑比较多的地方
首先,我在windows平台通过
先查看设备名称,然后输入
查看你的摄像头支持的格式和分辨率,如下图
我之前设置的1080p,推流只有3帧数。我用top命令发现是一核有难七核围观,我以为是占用太高,用多进程试了一下还是3帧。太神奇了,还好我灵机一动觉得事情不是这么简单,感觉冥冥之中有人在限制我的帧率。一看这个明白了。
由于我们推流前要先拉流,推流的目的是尽量要保持原视频的清晰度,出现低帧数之后通过cv2查看了获得的视频帧数和大小,认为是拉流端出了问题,分析得出摄像机默认编码格式不是mjpeg,于是利用cv2给他在拉流的时候设置一下。
这下好了,用多线程就30帧了,但是多进程队列的帧数还是12帧,原因我也不知道。
直接上代码
可以看到在ARM上配好的ffmpeg环境就不需要用绝对路径了。
隐蔽的小坑
进程设置的代码,在windows平台没问题,在linux平台用的时候请注释,错都不报。
这句报错一般会提示管道损坏,往上翻一下就能看见其他的错误,一般是说输入输出的编解码格式有错,重新检查ffmpeg的配置格式。看看你传的服务器是什么,传的数据是什么。Ffmpeg的原理是“解复用-解码-编码-复用器”,看一下哪里少了。还有一种情况是配置ffmpeg时候的参数出错了,填了根本没有的参数。
当然,这句代码版本太低了可以换成
花屏问题
基本都会报这个错,我看网上有人说改默认UDP的缓冲大小,我试了,也重新编译了。没啥用,我又看有人说删除解码错误帧,找了半天没有合适教程。我又看见有人说用tcp,我试了一下还真行,就是在 command_out 里面加一句
说句实话,就是这玩意儿你发送的太大了,改了tcp也不一定下次还有用。删除错误帧还会引起跳帧。不如直接压缩一下文件
这个参数我调到20就不会花屏,18就会,因为18是ffmpeg尽量无损地进行了压制。