如何使用OpenCV RTMP直播推流

本文前提

安装Python环境、安装OpenCV、安装安装FFmpeg并添加到系统环境变量;

如果是Linux,可以直接安装:

sudo apt install ffmpeg

Python代码

# 需先自行安装FFmpeg,并添加环境变量
import cv2
import subprocess
 
# FFmpeg官方文档:http://ffmpeg.org/ffmpeg.html

# RTMP服务器地址
rtmp_server = r'rtmp://live-push.bilivideo.com/live-bvc/'
# RTMP推流码
rtmp_key = '?streamname=live_xxx'
# 读取视频并获取属性,摄像头就写0,视频文件就写文件名
cap = cv2.VideoCapture(0)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)), int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))
sizeStr = str(size[0]) + 'x' + str(size[1])
command = ['ffmpeg',
    '-y', '-an',            # 无需询问即可覆盖输出文件
    '-f', 'rawvideo',       # 强制输入或输出文件格式
    '-vcodec','rawvideo',   # 设置视频编解码器。这是-codec:v的别名
    '-pix_fmt', 'bgr24',    # 设置像素格式
    '-s', sizeStr,          # 设置图像大小
    '-r', '25',             # 设置帧率
    '-i', '-',              # 输入
    '-c:v', 'libx264',      # 编解码器
    '-pix_fmt', 'yuv420p',  # 像素格式
    '-preset', 'ultrafast', # 调节编码速度和质量的平衡
    '-f', 'flv',            # 强制输入或输出文件格式
    '-tune', 'zerolatency', # 视频类型和视觉优化
    rtmp_server+rtmp_key]
pipe = subprocess.Popen(command, shell=False, stdin=subprocess.PIPE)

# 用来实现循环播放
frame_counter = 0

while cap.isOpened():
    success, frame = cap.read()
    # 如果帧尾,就重新开始;
    # 如果不需要循环播放,就把这部分删掉。
    frame_counter += 1
    if frame_counter == int(cap.get(cv2.CAP_PROP_FRAME_COUNT)):
        frame_counter = 0
        cap.set(cv2.CAP_PROP_POS_FRAMES, 0)

    if success:
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
        pipe.stdin.write(frame.tostring())
cap.release()
pipe.terminate()

推流测试

哔哩哔哩平台为例。

如何使用OpenCV RTMP直播推流_第1张图片

如何使用OpenCV RTMP直播推流_第2张图片

参数详解

此部分来自: FFmpeg X264编码参数 - 掘金

【免费分享】音视频学习资料包、大厂面试题、技术视频和学习路线图,资料包括(C/C++,Linux,FFmpeg webRTC rtmp hls rtsp ffplay srs 等等)有需要的可以点击788280672加群免费领取~

如何使用OpenCV RTMP直播推流_第3张图片

码率控制

X264提供三种码率控制的方式:bitrate, qp, crf。这三种方式是互斥的,使用时设置其中之一即可。
(1)bitrate
x264会尝试把给定的比特率作为整体平均值来编码,这意味着最终编码文件的大小是已知的,但最终的品质未知。
此选项通常与-pass(两阶段编码)一起使用。
注意,ffmpeg中设置bitrate的具体参数为bit_rate,对应音轨和视轨可以分别通过-a:v和-b:v单独设置,单位是bits/s;而x264里面对应参数i_bitrate的单位则是kbits/s, 1kbits为1000bits而非1024bits.
(2)qp
使用qp选项时,表示P帧的量化值为qp。I帧和B帧的量化值则是从--ipratio和--pbratio中取得。可使用默认参数,也可自己设定。使用qp模式,即固定量化值,意味着停用自适应量化(aq_mode)。
当qp为0时,为无损编码。

(3)crf
固定比特率系数,Constant Rate factor,可用的值从1到51,越小编码质量越好,码率越高。一般使用16到24,可以为浮点。(crf并不是恒定质量的方式,同一Slice同一crf值,其他参数不同可能码率和质量差较大,不同的Slice之间就更没有可比性了)
此模式把某个“质量”作为编码目标,根据Slice质量自动分配码率的vbr(Variable Bit Rate 动态比特率)。X264中构想是让crf n提供与qp n相当的视觉品质,但编码文件更小一些。
CRF是借由降低“较不重要”帧的品质来达到此目的。在此情况下,“较不重要”是指在复杂或高动态场景的帧,其品质不是很耗费比特数就是不易察觉,所以会提高它们的量化值。从这些帧里所节省下来的比特数被重新分配到可以更有效利用的帧。
当crf为0时,与qp 0相同,实现无损编码。

X264的preset和tune
鉴于x264的参数众多,各种参数的配合复杂,为了使用者方便,x264建议如无特别需要可使用preset和tune设置。这套开发者推荐的参数较为合理,可在此基础上在调整一些具体参数以符合自己需要,手动设定的参数会覆盖preset和tune里的参数。

--preset的参数主要调节编码速度和质量的平衡,有ultrafast、superfast、veryfast、faster、fast、medium、slow、slower、veryslow、placebo这10个选项,从快到慢。
--tune的参数主要配合视频类型和视觉优化的参数。如果视频的内容符合其中一个可用的调整值又或者有其中需要,则可以使用此选项,否则建议不使用(如tune grain是为高比特率的编码而设计的)。tune的值有:

  • film: 电影、真人类型;
  • animation: 动画;
  • grain: 需要保留大量的grain时用;
  • stillimage: 静态图像编码时使用;
  • psnr: 为提高psnr做了优化的参数;
  • ssim: 为提高ssim做了优化的参数;
  • fastdecode: 可以快速解码的参数;
  • zerolatency:零延迟,用在需要非常低的延迟的情况下,比如电视电话会议的编码。

参数优化

FFmpeg针对rtmp协议的参数:

如何使用OpenCV RTMP直播推流_第4张图片

. 关闭sync-lookahead
. 降低rc-lookahead,但别小于10,默认是-1
. 降低threads(比如从12降到6)
. 禁用rc-lookahead
. 禁用b-frames
. 缩小GOP,
. 开启x264的 -preset fast/faster/verfast/superfast/ultrafast参数
. 使用-tune zerolatency 参数
更多优化,仍可继续参考:FFmpeg X264编码参数 - 掘金

一般概念
RTMP是什么?
 

如何使用OpenCV RTMP直播推流_第5张图片

RTMP是Real Time Messaging Protocol(实时消息传输协议)的首字母缩写。该协议基于TCP,是一个协议族,包括RTMP基本协议及RTMPT/RTMPS/RTMPE等多种变种。RTMP是一种设计用来进行实时数据通信的网络协议,主要用来在Flash/AIR平台和支持RTMP协议的流媒体/交互服务器之间进行音视频和数据通信。支持该协议的软件包括Adobe Media Server/Ultrant Media Server/red5等。RTMP与HTTP一样,都属于TCP/IP四层模型的应用层。

树莓派是什么?
 

如何使用OpenCV RTMP直播推流_第6张图片

Raspberry Pi(中文名为“树莓派”,简写为RPi,(或者RasPi / RPI)是为学习计算机编程教育而设计),只有信用卡大小的微型电脑,其系统基于Linux。随着Windows 10 IoT的发布,我们也将可以用上运行Windows的树莓派。

作者:小锋学长生活大爆炸
原文 如何使用OpenCV RTMP直播推流

你可能感兴趣的:(opencv,人工智能,计算机视觉)