当前位置: 首页 > news >正文

使用 Python结合ffmpeg 实现单线程和多线程推流

一、引言

在本文中,我们将详细介绍如何使用 Python 进行视频的推流操作。我们将通过两个不同的实现方式,即单线程推流和多线程推流,来展示如何利用 cv2(OpenCV)和 subprocess 等库将视频帧推送到指定的 RTMP 地址。这两种方式都涉及到从摄像头读取视频帧,以及使用 ffmpeg 命令行工具将视频帧进行编码和推流的过程。

二、单线程推流

以下是单线程推流的代码:

import cv2 as cv
import subprocess as spdef push_stream():# 视频读取对象cap = cv.VideoCapture(0) fps = int(cap.get(cv.CAP_PROP_FPS))w = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))h = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))ret, frame = cap.read()# 推流地址rtmpUrl = "rtmp://192.168.3.33:1935/live/"# 推流参数command = ['ffmpeg','-y','-f', 'rawvideo','-vcodec','rawvideo','-pix_fmt', 'bgr24','-s', "{}x{}".format(w, h),'-r', str(fps),'-i', '-','-c:v', 'libx264','-pix_fmt', 'yuv420p','-preset', 'ultrafast','-f', 'flv', rtmpUrl]# 创建、管理子进程pipe = sp.Popen(command, stdin=sp.PIPE, bufsize=10 ** 8)# 循环读取while cap.isOpened():# 读取一帧ret, frame = cap.read()if frame is None:print('read frame err!')continue# 显示一帧cv.imshow("frame", frame)# 按键退出if cv.waitKey(1) & 0xFF == ord('q'):break# 读取尺寸、推流# img=cv.resize(frame,size)pipe.stdin.write(frame) # 关闭窗口cv.destroyAllWindows()# 停止读取cap.release()

在这个单线程的实现中,我们执行以下步骤:

  1. 初始化视频读取对象
    • 使用 cv2.VideoCapture(0) 来打开默认的摄像头设备。
    • 获取摄像头的帧率 fps、宽度 w 和高度 h 等参数。
  2. 设置推流地址和参数
    • 定义 rtmpUrl 作为推流的目标地址。
    • 构造 ffmpeg 的命令列表 command,该列表包含了一系列的参数,如 -y 表示覆盖输出文件、-f rawvideo 表示输入格式为原始视频等。
    • 使用 sp.Popen 创建一个子进程,将 ffmpeg 命令作为子进程运行,并且将其输入管道 stdin 连接到我们的程序。
  3. 循环读取和推流
    • 在一个 while 循环中,不断读取摄像头的帧。
    • 若读取失败,打印错误信息并继续。
    • 使用 cv2.imshow 显示当前帧,同时监听 q 键,按下 q 键时退出程序。
    • 将读取到的帧通过管道发送给 ffmpeg 进行推流。

三、多线程推流

以下是多线程推流的代码:

import queue
import threading
import cv2 as cv
import subprocess as spclass Live(object):def __init__(self):self.frame_queue = queue.Queue()self.command = ""# 自行设置self.rtmpUrl = ""self.camera_path = ""def read_frame(self):print("开启推流")cap = cv.VideoCapture(self.camera_path)# Get video informationfps = int(cap.get(cv.CAP_PROP_FPS))width = int(cap.get(cv.CAP_PROP_FRAME_WIDTH))height = int(cap.get(cv.CAP_PROP_FRAME_HEIGHT))# ffmpeg commandself.command = ['ffmpeg','-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', self.rtmpUrl]# read webcamerawhile(cap.isOpened()):ret, frame = cap.read()if not ret:print("Opening camera is failed")break# put frame into queueself.frame_queue.put(frame)def push_frame(self):# 防止多线程时 command 未被设置while True:if len(self.command) > 0:# 管道配置p = sp.Popen(self.command, stdin=sp.PIPE)breakwhile True:if self.frame_queue.empty()!= True:frame = self.frame_queue.get()# process frame# 你处理图片的代码# write to pipep.stdin.write(frame.tostring())def run(self):threads = [threading.Thread(target=Live.read_frame, args=(self,)),threading.Thread(target=Live.push_frame, args=(self,))][thread.setDaemon(True) for thread in threads][thread.start() for thread in threads]

在这个多线程的实现中,我们使用了 threadingqueue 库:

  1. 类的初始化
    • 创建一个 Live 类,在 __init__ 方法中初始化帧队列 frame_queuecommandrtmpUrlcamera_path 等变量。
  2. 读取帧的线程方法
    • read_frame 方法中,使用 cv2.VideoCapture(self.camera_path) 打开摄像头。
    • 获取摄像头的参数,并构造 ffmpeg 命令。
    • 不断从摄像头读取帧,并将帧放入队列 frame_queue 中。
  3. 推流的线程方法
    • push_frame 方法中,等待 command 被设置,然后使用 sp.Popen 启动 ffmpeg 子进程。
    • 从帧队列中取出帧,并将其写入 ffmpeg 的输入管道进行推流。
  4. 启动线程
    • run 方法创建并启动两个线程,一个用于读取帧,一个用于推流,并且将它们设置为守护线程。

四、代码解释和注意事项

单线程推流

  • 这种方式相对简单,适合初学者理解。但由于是单线程操作,在处理复杂任务时可能会导致性能瓶颈,特别是在同时进行视频显示、读取和推流的情况下,可能会出现卡顿现象。

多线程推流

  • 利用多线程可以将不同的任务分配给不同的线程,提高性能。
  • frame_queue 是一个线程安全的队列,用于在两个线程之间传递帧数据,避免了数据竞争问题。
  • setDaemon(True) 使得线程在主线程结束时自动终止,防止程序无法正常退出。

五、总结

通过上述代码和解释,我们可以看到如何使用 Python 进行单线程和多线程的视频推流操作。单线程代码简单明了,但性能可能受限;多线程代码可以更好地处理高负载,但也需要注意线程安全和资源管理等问题。在实际应用中,我们可以根据具体的需求和硬件性能来选择合适的推流方式。同时,我们可以进一步优化代码,例如添加异常处理、优化帧处理逻辑等,以提高程序的稳定性和性能。

相关文章:

使用 Python结合ffmpeg 实现单线程和多线程推流

一、引言 在本文中,我们将详细介绍如何使用 Python 进行视频的推流操作。我们将通过两个不同的实现方式,即单线程推流和多线程推流,来展示如何利用 cv2(OpenCV)和 subprocess 等库将视频帧推送到指定的 RTMP 地址。这…...

Linux一些问题

修改YUM源 Centos7将yum源更换为国内源保姆级教程_centos使用中科大源-CSDN博客 直接安装包,走链接也行 Index of /7.9.2009/os/x86_64/Packages 直接复制里面的安装包链接,在命令行直接 yum install https://vault.centos.org/7.9.2009/os/x86_64/Pa…...

在 Ubuntu 24.04.1 LTS | Python 3.12 环境下部署 Crypto 库

测试一些密码学方案需要用到 Crypto 库,网上教程大多针对 Windows 和 Python 3.10 或以下的环境,所以写下了这篇博文。 部署与使用 首先执行 su 输入密码进入超级用户,部署完 Python 3.12 环境后,执行以下命令进行安装&#xff…...

HTML5实现好看的二十四节气网页源码

HTML5实现好看的新年春节元旦网站源码 前言一、设计来源1.1 主界面1.2 关于我们界面1.3 春季节气界面1.4 夏季节气界面1.5 秋季节气界面1.6 冬季节气界面 二、效果和源码2.1 动态效果2.2 源代码 源码下载结束语 HTML5实现好看的二十四节气网页源码,春季节气&#xf…...

C++(9)—类和对象(上) ②实例化

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、实例化概念二、对象大小 1.对象存储2.内存对齐规则总结 前言 提示:以下是本篇文章正文内容,下面案例可供参考 一、实例化概念 • …...

Effective C++读书笔记——item2(const,enum,inlines取代#define)

关于用常量取代 #define 的总体原则 在编程中,应尽量减少预处理器(特别是 #define)的使用,可通过合适的替代方式来避免 #define 带来的诸多问题,虽然不能完全消除预处理器相关指令(如 #include、#ifdef/#i…...

如何科学评估与选择新版本 Python 编程语言和工具

文章目录 摘要引言评估新版本的关键因素适用性评估成本与收益分析 新版本功能的实际应用示例代码模块详细解析示例代码模块代码模块解析实际应用场景如何运行与配图 QA环节总结参考资料 摘要 随着技术的快速发展,编程语言和软件工具不断推出新版本,带来…...

第十届“挑战杯”大学生课外学术科技作品竞赛解析及资料

“挑战杯”被誉为大学生科技创新创业的“奥林匹克”盛会,它汇聚了来自各个学科、各个年级的精英人才。在这里,同学们带着对未知的好奇和对知识的渴望,组成一个个团队,向难题发起挑战。现在,第十届“挑战杯”大学生课外…...

【门铃工作原理】2021-12-25

缘由关于#门铃工作原理#的问题,如何解决?-嵌入式-CSDN问答 4 RST(复位)当此引脚接高电平时定时器工作,当此引脚接地时芯片复位,输出低电平。 按钮按下给电容器充电并相当与短路了R1改变了频率,按…...

Chain of Agents(COA):大型语言模型在长文本任务中的协作新范式

随着人工智能技术的飞速发展,大型语言模型(LLM)在自然语言处理领域的应用日益广泛。然而,LLM在处理长文本任务时仍面临诸多挑战。传统的解决方案,如截断输入上下文或使用基于检索增强生成(RAG)的…...

业务模型与UI设计

业务数据模型的设计、UI设计这应该是程序设计中不可缺少的部分。做程序设计的前提应该先把这两块设计好,那么,来一个实际案例,看看这2块的内容。 汽车保养记录业务模型与UI设计: 一、【车辆清单】 记录车辆相关的数据&#xff0…...

Apache SeaTunnel深度优化:CSV字段分割能力的增强

Apache SeaTunnel深度优化:CSV字段分割能力的增强 一、Apache SeaTunnel与CSV处理 1.1 Apache SeaTunnel简介 Apache SeaTunnel(原名Waterdrop)是一个分布式、高性能的数据集成平台,支持海量数据的实时同步。它允许用户通过配置…...

免费下载 | 2024年具身大模型关键技术与应用报告

这份报告的核心内容涉及具身智能的关键技术与应用,主要包括以下几个方面: 具身智能的定义与重要性: 具身智能是基于物理身体进行感知和行动的智能系统,通过与环境的交互获取信息、理解问题、做出决策并实现行动,产生智…...

SSM-Spring-AOP

目录 1 AOP实现步骤(以前打印当前系统的时间为例) 2 AOP工作流程 3 AOP核心概念 4 AOP配置管理 4-1 AOP切入点表达式 4-1-1 语法格式 4-1-2 通配符 4-2 AOP通知类型 五种通知类型 AOP通知获取数据 获取参数 获取返回值 获取异常 总结 5 …...

jenkins修改端口以及开机自启

修改Jenkins端口 方式一:通过配置文件修改(以CentOS为例) 找到配置文件:在CentOS系统中,通常可以在/etc/sysconfig/jenkins文件中修改Jenkins的配置。如果没有这个文件,也可以查看/etc/default/jenkins&…...

按照人们阅读Excel习惯来格式化BigDecimal

1、环境/问题描述 使用springboot发送邮件(附件)的方式将月度报表发送给领导查阅,数据是准确的,领导基本满意。 就是对一些数字的格式化提出了改进建议,比如不要让大数字自动转为科学计数法、浮点数小数点后都是0就不要带出来,根…...

IDEA开发Java应用的初始化设置

一、插件安装 如下图所示: 1、Alibaba Java Coding Guidelines 2.1.1 阿里开发者规范,可以帮忙本地自动扫描出不符合开发者规范的代码,甚至是代码漏洞提示。 右击项目,选择《编码规约扫描》,可以进行本地代码规范扫…...

Java网络套接字

在Java的开发中,有一个很重要!很重要!很重要!的东西,叫做网络套接字,它被广泛的用来二次开发服务,比如大数据中台的服务链路调用等。 它的实现原理是依靠三次握手来完成通信的建立,…...

2025差旅平台推荐:一体化降本30%

医药行业因其高度专业化的特点,同时在运营过程中又极为依赖供应链和销售网络,因此差旅管理往往成为成本控制的重要环节。本期,我们以差旅平台分贝通签约伙伴——某知名药企为例,探讨企业如何通过差旅一体化管理,在全流…...

多个DataV遍历生成

DataV是数据可视化工具 与Echart类似 相对Echart图标边框 装饰可选官网DataV 安装 npm install kjgl77/datav-vue3main.ts import DataVVue3 from kjgl77/datav-vue3 app.use(DataVVue3)多个DataV遍历生成 Vue3viteDataV为例:<template><div w50rem h25rem flex&qu…...

mysql_real_connect的概念和使用案例

mysql_real_connect 是 MySQL C API 中的一个函数&#xff0c;用于建立一个到 MySQL 数据库服务器的连接。这个函数尝试建立一个连接&#xff0c;并根据提供的参数进行连接设置。 概念 以下是 mysql_real_connect 函数的基本概念&#xff1a; 函数原型&#xff1a;MYSQL *my…...

Python性能分析深度解析:从`cProfile`到`line_profiler`的优化之路

《Python OpenCV从菜鸟到高手》带你进入图像处理与计算机视觉的大门! 解锁Python编程的无限可能:《奇妙的Python》带你漫游代码世界 在软件开发过程中,性能优化是提升应用质量和用户体验的关键环节。Python作为广泛应用的高级编程语言,其性能分析工具为开发者提供了强大的…...

Momentum Contrast for Unsupervised Visual Representation Learning论文笔记

文章目录 论文地址动量队列对比学习的infoNCE loss为什么需要动量编码器对比学习moco方法中的动量Encoder为什么不能与梯度Encoder完全相同为什么动量编码器和梯度编码器不能完全相同&#xff1f;总结&#xff1a; 我理解&#xff0c;正负样本应该经过同一个encoder&#xff0c…...

用户界面的UML建模07

4.2 抽象表示层的行为&#xff08;Abstract Presentation Behaviour&#xff09; AbstractForm 类定义了一组如下所示的四种操作&#xff1a; showForm() &#xff0c; getData() &#xff0c; sendConfirmation() 和sendCancellation()。在该阶段的设计过程&#xff08;desig…...

Node.js中使用Joi 和 express-joi-validation进行数据验证和校验

在进行项目开发的过程中&#xff0c;很多时候系统对用户输入的数据会进行严格校验的&#xff0c;通常我们会以“前端校验为辅&#xff0c;后端校验为主”的思想进行校验处理。 后端接口校验的时候&#xff0c;是只能一直使用if进行逻辑判断呢&#xff0c;还是有更加方便的方法…...

InstructGPT:基于人类反馈训练语言模型遵从指令的能力

大家读完觉得有意义记得关注和点赞&#xff01;&#xff01;&#xff01; 大模型进化树&#xff0c;可以看到 InstructGPT 所处的年代和位置。来自 大语言模型&#xff08;LLM&#xff09;综述与实用指南&#xff08;Amazon&#xff0c;2023&#xff09; 目录 摘要 1 引言 …...

jrc水体分类对水体二值掩码修正

使用deepwatermap生成的水体二值掩码中有部分区域由于被云挡住无法识别&#xff0c;造成水体不连续是使用jrc离线数据进行修正&#xff0c;jrc数据下载连接如下&#xff1a;https://global-surface-water.appspot.com/download 选择指定区域的数据集合下载如图&#xff1a; 使…...

营销/CDP/MA/SCRM

最近几年面向企业用户的营销系统&#xff0c;cdp&#xff0c;ma&#xff0c;scrm等发展迅速&#xff0c;下面就简单介绍一下这些系统。 架构图 架构图中显示了CDP&#xff0c;MA&#xff0c;SCRM的核心功能&#xff0c;其实还有基础底座的功能。 比如统一登录&#xff0c;权限…...

免费CDN加速,零成本提升网站速度!

1. 起因 免备案的服务器要么在海外&#xff0c;要么是国内通过内网穿透才能访问&#xff0c;这两种方法好处是免费&#xff0c;坏处是延迟太高&#xff0c;有的地区延迟能到四五百甚至超时&#xff0c;这样明显是不行的。 所以需套一个cdn来加速&#xff0c;在2024年&#xff0…...

2024-12-29-sklearn学习(25)无监督学习-神经网络模型(无监督) 烟笼寒水月笼沙,夜泊秦淮近酒家。

文章目录 sklearn学习(25) 无监督学习-神经网络模型&#xff08;无监督&#xff09;25.1 限制波尔兹曼机25.1.1 图形模型和参数化25.1.2 伯努利限制玻尔兹曼机25.1.3 随机最大似然学习 sklearn学习(25) 无监督学习-神经网络模型&#xff08;无监督&#xff09; 文章参考网站&a…...