前言

单位最近好像有网络直播的需要,说起网络直播,最常见的就是通过RTMP协议进行网络推流。 ffmpeg是一款开源的图像处理项目,可以方便的进行图像视频处理,推送操作,当然我们需要的推送RTMP流功能也可以很好的实现。 本文就以ffmpeg为工具进行RTMP的推送。

安装ffmpeg

  1. 在官网下载ffmpeg压缩包:下载链接
  2. 解压到本地磁盘
  3. 将解压后的bin文件夹路径配置到系统环境变量中
  4. 打开cmd输入ffmpeg –version,可以看到ffmpeg的相关信息即可

配置RTMP服务器

  1. 安装nginx,下载地址
  2. 下载nginx-rtmp,下载地址下载后解压放到与nginx的同级目录
  3. 复制nginx的conf文件夹中的nginx-win.conf文件,在其末尾添加
rtmp {
server {
listen 1935;#监听端口,若被占用,可以更改
chunk_size 4000;#上传flv文件块儿的大小
application live { #创建一个叫live的应用
live on;#开启live的应用
allow publish 127.0.0.1;#
allow play all;
}
}
}

示例代码

以下代码可以实现将本地的视频以RTMP流的方式推送到RTMP服务器,实现网络直播。

import cv2
import subprocess

camera_path = r"本地视频地址"

# 视频读取对象
cap = cv2.VideoCapture(camera_path)

# 读取一帧
ret, frame = cap.read()

# 推流地址
rtmp = "RTMP服务器地址"

fps = int(cap.get(cv2.CAP_PROP_FPS))
width = int(cap.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT))
# 推流参数
command = ['D:\\ffmpeg\\bin\\ffmpeg.exe',
'-y',
'-f', 'rawvideo',
'-vcodec','rawvideo',
'-pix_fmt', 'bgr24',
'-s', "{}x{}".format(width, height),
'-r', str(fps),
'-i', '-',
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'flv',
rtmp]

# 创建、管理子进程
pipe = subprocess.Popen(command, stdin=subprocess.PIPE)
size = (int(cap.get(cv2.CAP_PROP_FRAME_WIDTH)),
int(cap.get(cv2.CAP_PROP_FRAME_HEIGHT)))

# 循环读取
while cap.isOpened():
# 读取一帧
ret, frame = cap.read()
if frame is None:
print('read frame err!')
continue

# 显示一帧
cv2.imshow("frame", frame)

# 按键退出
if cv2.waitKey(1) & 0xFF == ord('q'):
break

# 读取尺寸、推流
img=cv2.resize(frame,size)
pipe.stdin.write(img.tobytes())

cv2.destroyAllWindows()

cap.release()

启动程序后,使用VLC或者Potplayer等软件读取RTMP地址即可播放。

ffmpeg-python包

通过以上代码确实能够实现ffmpeg的推流,不过实际上只是调用了ffmpeg自带的命令行工具,更改参数什么的不太方便,后来了解到python有ffmpeg的包。

pip install ffmpeg-python

关于ffmpeg包的使用,下次再另写一篇文章。