nginx搭建rtmp流服務器並opencv等處理後(音頻、視頻)實時推出

一、流服務器搭建

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、實時推出

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章