使用python读取网络视频流或者本地视频进行RTMP流的生成,并对视频源的每一帧做剪切处理
使用python读取网络视频流或者本地视频进行RTMP流的生成,并对视频源的每一帧做剪切处理
python读取网络视频流或者本地视频进行RTMP流的生成
想要获得RTMP推流的功能其实是可以用ffmpeg+ffserver通过命令行方式实现的,但是我为了对原视频流的帧做剪切处理,所以使用python调用ffmpeg来推流,这里只是生成推流,这是不够的,需要有一个代理服务器来接收推流并推向网络,关于代理服务器的配置请看文末的链接
以下是全部代码,需要注意以下几点:
- 主体是两个函数,通过两个线程调用,线程之间通过队列进行通信,读流线程将读取到的帧放入队列中,推流线程将队列中的帧取出来进行剪切处理并推流。
- 在处理帧的时候一定要注意将处理后的帧的fps设置为ffmpeg command中设置的width,height,不然推流会失败。 就是这一句代码:
image = cv2.resize(frame[int(left_x):int(right_x)][int(left_y):int(right_y)], (width, height))
- 不知道为什么在队列不为空的时候会出现队列中帧对象为NoneType的问题,所以在处理的时候我加了个判断条件。如果有大佬知道原因请在评论区留言,欢迎交流。
- 适应项目要求我剪切帧需要的参数是从文件中读取的,使用时可换成别的方式
import subprocess as sp
import cv2
import sys
import queue
import threading
frame_queue = queue.Queue()
rtmpUrl = "rtmp://IP地址/live/test"
camera_path = 'rtmp://58.200.131.2:1935/livetv/hunantv' #这是湖南台的实时直播流
#获取摄像头参数
cap = cv2.VideoCapture(camera_path)
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))
#print(fps, width, height)
# ffmpeg command
command = ['ffmpeg',
'-y',
'rawvideo',
'-vcodec', 'rawvideo',
'-pix_fmt', 'bgr24',
'-s', "{}x{}".format(width, height),
'-r', str(fps),
'-c:v', 'libx264',
'-pix_fmt', 'yuv420p',
'-preset', 'ultrafast',
'-f', 'flv',
'-g', '5',
rtmpUrl]
#读流函数
def Video():
vid = cv2.VideoCapture(camera_path)
if not vid.isOpened():
raise IOError("could't open webcamera or video")
while(vid.isOpened()):
ret,frame = vid.read()
#下面注释的代码是为了防止摄像头打不开而造成断流
#if not ret:
#vid = cv2.VideoCapture(camera_path)
#if not vid.isOpened():
#raise IOError("couldn't open webcamera or video")
#continue
frame_queue.put(frame)
def push_stream(left_x,left_y,right_x,right_y):
# 管道配置
while True:
if len(command)>0:
p = sp.Popen(command, stdin=sp.PIPE)
break
while True:
if not frame_queue.empty():
frame = frame_queue.get()
if frame is not None:
#我这里出现了frame为NoneType的情况,所以判断一下
image = cv2.resize(frame[int(left_x):int(right_x)][int(left_y):int(right_y)], (width, height))
p.stdin.write(image.tostring())
def run(left_x,left_y,right_x,right_y):
thread_video = threading.Thread(target=Video,)
thread_push = threading.Thread(target=push_stream,args=(left_x,left_y,right_x,right_y,))
thread_video.start()
thread_push.start()
if __name__ == "__main__":
with open("zoomfile.txt", "r") as f: # 打开文件
data = f.read() # 读取文件
zoom = data.split("_")
left_x = zoom[0]
left_y = zoom[1]
right_x = zoom[2]
right_y = zoom[3]
with open("zoomfile.txt","w") as f:
f.write("0")
run(left_x,left_y,right_x,right_y)
python代码参考了以下几篇博客:
python利用ffmpeg进行rtmp推流直播
Python 通过ffmpeg实现实时推流(ubuntu16+ffmpeg+nginx)
以下三篇博客是关于nginx服务器和RTMP配置的,都很有参考价值
Ubuntu安装nginx+rtmp
利用nginx搭建RTMP视频点播、直播、HLS服务器
使用 nginx 和 rtmp 插件搭建视频直播和点播服务器
最新文章
- java中的反射机制是什么
- KPM算法详解(Next数组)
- 栅栏密码(The Rail
- 点球大战
- C++中的fstreamifstreamofstream和MFC中的CFileCStdioFile
- 使用CStdioFile操作文件
- 【基础】BMP格式
- JMeter怎么用
- redis的hash怎么实现以及 rehash过程是怎样的?和JavaHashMap的rehash有什么区别,与ConcurrentHashMap扩容的策略比较?
- C#使用EmguCV库(图像读取、显示、保存)(二)
- mysql 1142 问题解决
- mysql error 1142
- 目标检测目标的统计
- 1个人做自媒体,就选这4个领域,变现容易,操作简单
- TensorFlow Lite 开发手册(5)——TensorFlow Lite模型使用实例(分类模型)
- PTA题目 计算分段函数[3]
- Msfvenom使用指南
- Hadoop安装与部署
- 王勇杰《音乐漫步》1
- js中call()方法的用法