nginx搭建rtmp流服务器并opencv等处理后(音频、视频)实时推出

前提是你 提交于 2020-03-03 16:10:11

一、流服务器搭建

1、安装

参考文章

sudo apt-get install software-properties-common python-software-properties
sudo add-apt-repository ppa:nginx/stable
sudo apt-get update
sudo apt-get install nginx
sudo apt-get install libnginx-mod-rtmp

2、配置文件修改

sudo gedit /etc/nginx/nginx.conf

添加:

rtmp {
    servername {
        listen 1935;
        chunk_size 4096;
        application live {
            live on;
        }
    }
}
sudo service  nginx restart

然后推出的流地址就可以是: rtmp://ip:1935/servername/name

二、opencv处理视频流并推出

1、读取流

和读取摄像头一样,`cap = cv2.VideoCapture(rtmp_)`
可用的rtmp地址:
  • rtmp://58.200.131.2:1935/livetv/hunantv 湖南卫视
  • rtmp://202.69.69.180:443/webcast/bshdlive-pc 香港财经,很流畅!!!

注意: 抓取rtmp流可能一次抓不到,所以得多抓几次,特别是自己搭的rtmp流更得多抓几次!!
下面是测试rtmp的代码,开始抓出错继续抓,抓到后中断了又继续抓。

rtmp = 'rtmp://192.168.1.18:1935/jiteng/3d'#'rtmp://58.200.131.2:1935/livetv/hunantv'#
# nginx 搭建的rtmp服务器,有时第一次抓不到,要多次抓取。
count_open_cap = 0
print ('开始抓取!')
cap = cv2.VideoCapture(rtmp)
while 1:
  if cap.isOpened():
    w,h,fps = int(cap.get(3)),int(cap.get(4)),cap.get(5)
    print ('抓取成功!',w,h,fps)
    count_open_cap = 0
    break
  else:
    count_open_cap += 1
    print ('尝试抓取第'+str(count_open_cap+1)+'次!')
    cap = cv2.VideoCapture(rtmp)
    if count_open_cap == 4:
      print ('尝试抓取了5次,失败!')
      sys.exit()
      break
    continue
ret,img = cap.read()
if img is not None:
  cv2.imwrite('live_test.jpg',img)
#cv2.namedWindow('live_test',2)
while 1:
  ret,img = cap.read()

  if ret == 0:
    count_open_cap += 1
    cap = cv2.VideoCapture(rtmp)
    print ('中断后,尝试抓取第'+str(count_open_cap+1)+'次!')
    if count_open_cap == 4:
      print ('中断后,尝试抓取了5次,失败!')
      sys.exit()
      break
    continue
  if count_open_cap != 0:
    print ('抓取成功!')

  count_open_cap = 0
  cv2.imshow('live_3d',img)
  if cv2.waitKey(int(1000/fps)) == 27:
    break
 
cv2.destroyAllWindows()
cap.release()

2、处理流

同`ret,img = cap.read()`,然后直接一帧帧处理就好了

3、实时推出

参考文章
原理就是利用FFmpeg将帧进行转码推出,而帧通过subprocess的管道(pipe)进行提取,这样结合就可以处理后实时转码推出了。

import subprocess as sp
    #通过管道pipe来使用了ffmpeg提供的rtmp推流工具,init
    def pipe_init(self):
        # 直播管道输出 
        # ffmpeg推送rtmp 重点 : 通过管道 共享数据的方式
        command = ['ffmpeg',
            '-y',
            '-f', 'rawvideo',
            '-vcodec','rawvideo',
            '-pix_fmt', 'bgr24',
            '-s', str(self.w)+ 'x' +str(self.h),
            '-r', str(self.fps),
            '-i', '-',
            '-c:v 1', 'libx264',
            '-pix_fmt', 'yuv420p',
            '-preset', 'ultrafast',
            '-f', 'flv', 
            self.out_rtmp]
        #管道特性配置
        pipe = sp.Popen(command, stdin=sp.PIPE) #,shell=False  
        return pipe

    #将图片推入管道中
    def frame2pipe(self,pipe,frame):
        # 结果帧处理 存入文件 / 推流 / ffmpeg 再处理
        pipe.stdin.write(frame.tostring())  # 存入管道用于直播

三、音频实时提取与推出

1、python音频实时提取

2、帧音频与图像结合

3、实时推出

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!