因为要把多个输入源整合成一路视频传输,还要做一些处理,需要OpenCV+Python
要用RTMP推流,所以还需要Nginx,记录一下过程。
软件准备:
本文写于2020年9月28日,都用最新的(不过系统为了兼容性,还是使用Ubuntu18)。
安装Python3+PpenCV
python3 用anaconda装
opencv用pip装
https://pypi.org/project/opencv-python/#files
pip install opencv_python-4.4.0.44-cp36-cp36m-manylinux2014_x86_64.whl
安装Nginx+RTMP
下载最新的软件组件,放在一个文件夹下面:
Nginx:
http://nginx.org/download/nginx-1.19.2.tar.gz
Nginx-RTMP:
https://github.com/arut/nginx-rtmp-module/archive/master.zip
OpenSSL:
git clone --branch OpenSSL_1_1_1-stable https://github.com/openssl/openssl
三个下载好以后,放在一个文件夹下面
进入nginx-1.19.2文件夹,配置编译环境
./configure --prefix=/usr/local/nginx --with-openssl=../openssl --add-module=../nginx-rtmp-module
然后就:
sudo make -j4
sudo make install
就装好了。
测试一下下面的几个命令
启动
sudo /usr/local/nginx/sbin/nginx
停止
sudo /user/local/nginx/sbin/nginx -s stop
重新载入
sudo /usr/local/nginx/sbin/nginx -s reload
修改配置
sudo gedit /usr/local/nginx/conf/nginx.conf
插入rtmp配置:
rtmp {
server {
listen 1980;
application live {
live on;
}
application vod {
play /tmp/video;
}
}
}
重新加载配置
sudo /usr/local/nginx/sbin/nginx -s reload
查看一下网络监听的端口们:
netstat -ltn
说明启动起来了
文件推流测试
用FFMPG推流试试,mp4文件是我自己的视频文件。
ffmpeg -re -i /home/guo/Videos/20200924_155520.mp4 -vcodec libx264 -vprofile baseline -acodec aac -ar 44100 -strict -2 -ac 1 -f flv -s 1280x720 -q 10 rtmp://127.0.0.1:1980/live/test
打开后,就开始推流了,然后打开VLC播放器,将URL输入,就可以看到自己推流的视频了。
说明推流没问题了,都装好了。
OpenCV推流
用视频文件或者USB摄像头为视频源
import cv2
import subprocess
src="/home/guo/Videos/20200924_155520.mp4"
rtmp = 'rtmp://127.0.0.1:1980/live/test'
cap = cv2.VideoCapture(src)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
size = (int(640), int(480))
sizeStr = str(size[0]) + 'x' + str(size[1])
command = ['ffmpeg',
'-y', '-an',
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-pix_fmt', 'bgr24',
'-s', sizeStr,
'-r', '25',
'-i', '-',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'flv',
rtmp]
pipe = subprocess.Popen(command
, shell=False
, stdin=subprocess.PIPE
)
while cap.isOpened():
success,frame = cap.read()
if success==False:
print("Err")
break
img=cv2.resize(frame,size)
pipe.stdin.write(img.tostring())
cap.release()
pipe.terminate()
这里原始图像的尺寸比较大,进行了缩放。推流同样可以看到结果。
终于调通了。