Qt音视频开发44-本地摄像头推流(支持分辨率/帧率等设置/实时性极高)
一、前言
本地摄像头推流和本地桌面推流类似,无非就是采集的设备源头换成了本地摄像头设备而不是桌面,其他代码完全一样。采集本地摄像头实时视频要注意的是如果设置分辨率和帧率,一定要是设备本身就支持的,如果不支持那就歇菜,比如设备本身最大分辨率到1280x720,你主动设置要采集1080x720分辨率的图像,那是采集不到的,会失败的,如果默认不设置,一般会采用640x480分辨率以及25帧率去采集。采集本地摄像头设备命令行是 ffmpeg -f dshow -i video=“USB Video Device”:audio=“麦克风 (USB Audio Device)” -vcodec libx264 -preset:v ultrafast -tune:v zerolatency -f rtsp rtsp://192.168.0.110:6907/stream ,可以指定带上麦克风,这样音视频都有。
采集大致步骤:
- 查找格式 av_find_input_format,参数 dshow/v4l2/avfoundation
- 打开桌面 avformat_open_input,参数 video=USB Video Device
- 查找视频流 av_find_best_stream
- 查找解码器 avcodec_find_decoder
- 打开解码器 avcodec_open2
- 循环读取 av_read_frame
- 解码视频 avcodec_send_packet/avcodec_receive_frame
- 关闭释放 avcodec_free_context/avformat_close_input
推流大致步骤:
- 创建输出 avformat_alloc_output_context2
- 创建视频流 avformat_new_stream
- 打开输出 avio_open,参数填推流完整地址
- 写入开始符 avformat_write_header
- 写入帧数据 av_interleaved_write_frame
- 关闭释放 avio_close/avformat_free_context
二、效果图

三、体验地址
- 国内站点:https://gitee.com/feiyangqingyun
- 国际站点:https://github.com/feiyangqingyun
- 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
- 体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_push。
四、相关代码
void FFmpegThread::initInputFormat()
{//本地摄像头/桌面录屏if (videoType == VideoType_Camera) {
#if defined(Q_OS_WIN)//ifmt = av_find_input_format("vfwcap");ifmt = av_find_input_format("dshow");
#elif defined(Q_OS_LINUX)//可以打开cheese程序查看本地摄像头(如果是在虚拟机中需要设置usb选项3.1)//ifmt = av_find_input_format("v4l2");ifmt = av_find_input_format("video4linux2");
#elif defined(Q_OS_MAC)ifmt = av_find_input_format("avfoundation");
#endif} else if (videoType == VideoType_Desktop) {
#if defined(Q_OS_WIN)ifmt = av_find_input_format("gdigrab");
#elif defined(Q_OS_LINUX)ifmt = av_find_input_format("x11grab");
#elif defined(Q_OS_MAC)ifmt = av_find_input_format("avfoundation");
#endif}
}bool FFmpegThread::initInput()
{//实例化格式处理上下文formatCtx = avformat_alloc_context();//设置超时回调(有些不存在的地址或者网络不好的情况下要卡很久)formatCtx->interrupt_callback.callback = FFmpegHelper::avinterruptCallBackFun;formatCtx->interrupt_callback.opaque = this;//打开输入(通过标志位控制回调那边做超时判断)//其他地方调用 formatCtx->url formatCtx->filename 可以拿到设置的地址(两个变量值一样)tryOpen = true;QByteArray urlData = VideoHelper::getRightUrl(videoType, videoUrl).toUtf8();int result = avformat_open_input(&formatCtx, urlData.data(), ifmt, &options);tryOpen = false;if (result < 0) {debug("打开出错", "错误: " + FFmpegHelper::getError(result));return false;}//根据自己项目需要开启下面部分代码加快视频流打开速度//开启后由于值太小可能会出现部分视频流获取不到分辨率if (decodeType == DecodeType_Fastest && videoType == VideoType_Rtsp) {//接口内部读取的最大数据量(从源文件中读取的最大字节数)//默认值5000000导致这里卡很久最耗时(可以调小来加快打开速度)formatCtx->probesize = 50000;//从文件中读取的最大时长(单位为 AV_TIME_BASE units)formatCtx->max_analyze_duration = 5 * AV_TIME_BASE;//内部读取的数据包不放入缓冲区//formatCtx->flags |= AVFMT_FLAG_NOBUFFER;//设置解码错误验证过滤花屏//formatCtx->error_recognition |= AV_EF_EXPLODE;}//获取流信息result = avformat_find_stream_info(formatCtx, NULL);if (result < 0) {debug("找流失败", "错误: " + FFmpegHelper::getError(result));return false;}//解码格式formatName = formatCtx->iformat->name;//某些格式比如视频流不做音视频同步(响应速度快)if (formatName == "rtsp" || videoUrl.endsWith(".sdp")) {useSync = false;}//设置了最快速度则不启用音视频同步if (decodeType == DecodeType_Fastest) {useSync = false;}//有些格式不支持硬解码if (formatName.contains("rm") || formatName.contains("avi") || formatName.contains("webm")) {hardware = "none";}//本地摄像头设备解码出来的直接就是yuv显示不需要硬解码if (videoType == VideoType_Camera || videoType == VideoType_Desktop) {useSync = false;hardware = "none";}//过低版本不支持硬解码
#if (FFMPEG_VERSION_MAJOR < 3)hardware = "none";
#endif//获取文件时长(这里获取到的是秒)double length = (double)formatCtx->duration / AV_TIME_BASE;duration = length * 1000;this->checkVideoType();//有时候网络地址也可能是纯音频if (videoType == VideoType_FileHttp) {onlyAudio = VideoHelper::getOnlyAudio(videoUrl, formatName);}if (getIsFile()) {//文件必须要音视频同步useSync = true;//发送文件时长信号emit receiveDuration(duration > 0 ? duration : 0);}QString msg = QString("格式: %1 时长: %2 秒 加速: %3").arg(formatName).arg(duration / 1000).arg(hardware);debug("媒体信息", msg);return true;
}
五、功能特点
5.1 文件推流
- 指定网卡和监听端口,接收网络请求推送音视频等各种文件。
- 实时统计显示每个文件对应的访问数量、总访问数量、不同IP地址访问数量。
- 可指定多种模式,0-直接播放、1-下载播放。
- 实时打印显示各种收发请求和应答数据。
- 每个文件对应MD5加密的唯一标识符,用于请求地址后缀区分访问哪个文件。
- 支持各种浏览器(谷歌chromium/微软edge/火狐firefox等)、各种播放器(vlc/mpv/ffplay/potplayer/mpchc等)打开请求。
- 播放过程中可以任意切换播放进度,支持倍速播放。
- 需要推流的文件名称历史记录自动存储和打开加载应用。
- 切换文件获取访问地址,自动拷贝地址到剪切板方便直接粘贴测试使用。
- 极低CPU占用,128路1080P同时推流不到1%CPU占用,异步发送数据机制。
- 纯QTcpSocket通信,不依赖流媒体服务程序,核心源码不到500行,注释详细,功能完整。
- 支持Qt4/Qt5/Qt6任意版本,支持任意系统(windows/linux/macos/android/嵌入式linux等)。
5.2 网络推流
- 支持各种本地视频文件和网络视频文件。
- 支持各种网络视频流,网络摄像头,协议包括rtsp、rtmp、http。
- 支持将本地摄像头设备推流,可指定分辨率和帧率等。
- 支持将本地桌面推流,可指定屏幕区域和帧率等。
- 自动启动流媒体服务程序,默认mediamtx(原rtsp-simple-server),可选用srs、EasyDarwin、LiveQing、ZLMediaKit等。
- 可实时切换预览视频文件。
- 推流的清晰度和质量可调。
- 可动态添加文件、目录、地址。
- 视频文件自动循环推流,如果视频源是视频流,在掉线后会自动重连。
- 网络视频流自动重连,重连成功自动继续推流。
- 网络视频流实时性极高,延迟极低,延迟时间大概在100ms左右。
- 推流后除了用rtmp地址访问以外,还支持直接hls/webrtc访问,可以直接浏览器打开看实时画面。
- 支持Qt4/Qt5/Qt6任意版本,支持任意系统(windows/linux/macos/android/嵌入式linux等)。
相关文章:
Qt音视频开发44-本地摄像头推流(支持分辨率/帧率等设置/实时性极高)
一、前言 本地摄像头推流和本地桌面推流类似,无非就是采集的设备源头换成了本地摄像头设备而不是桌面,其他代码完全一样。采集本地摄像头实时视频要注意的是如果设置分辨率和帧率,一定要是设备本身就支持的,如果不支持那就歇菜&a…...
SpringCloud学习(七)——统一网关Gateway
文章目录 1. 网关介绍2. 网关搭建2.1 引入依赖2.2 创建启动类2.3 编写配置2.4 测试 3. 路由断言工厂4. 路由过滤器4.1 过滤器配置4.2 全局过滤器4.3 过滤器执行顺序 5. 跨域问题处理 1. 网关介绍 到现在,我们可以使用Nacos对不同的微服务进行注册并管理配置文件&am…...
《花雕学AI》31:ChatGPT--用关键词/咒语/提示词Prompt激发AI绘画的无限创意!
你有没有想过用AI来画画?ChatGPT是一款基于GPT-3的聊天模式的AI绘画工具,它可以根据你输入的关键词/咒语/提示词Prompt来生成不同风格和主题的画作。Prompt是一些简短的文字,可以用来指导ChatGPT的创作过程。在这篇文章中,我将展示…...
计算机组成原理9控制单元的结构
9.1操作命令的分析 取值周期间址周期执行周期中断周期 取指周期数据流 PC存放下条指令的地址给MAR访问存储器相应单元,将数据取出来送给MDR寄存器,MDR取出来的内容送给IR指令寄存器,然后对指令进行译码,把指令的操作码部分取出…...
MySQL数据备份和恢复
MySQL数据备份和恢复 数据备份 mysqldump是MySQL数据库备份工具,可以备份MySQL数据库中的数据和结构,生成.sql文件,方便数据的迁移和恢复。 使用mysqldump工具前一定要配置环境变量 打开开始菜单,搜索“环境变量”。点击“编辑…...
数据结构与算法之链表: Leetcode 237. 删除链表中的节点 (Typescript版)
删除链表中的节点 https://leetcode.cn/problems/delete-node-in-a-linked-list/ 描述 有一个单链表的 head,我们想删除它其中的一个节点 node。 给你一个需要删除的节点 node 。你将 无法访问 第一个节点 head。 链表的所有值都是 唯一的,并且保证给…...
继承的相关介绍---C++
一、概念及定义 概念: 继承(inheritance)机制是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加功能,这样产生新的类,称派生类。继承呈现了面向对象程序设计的层次结…...
Java多线程深入探讨
1. 线程与进程2. 创建和管理线程2.1. 继承Thread类2.2. 实现Runnable接口2.3 利用Callable、FutureTask接口实现。2.4 Thread的常用方法 3. 线程同步3.1. synchronized关键字3.1.1同步代码块:3.1.2 同步方法: 3.2. Lock接口 4. 线程间通信5. 线程池5.1 使…...
SpringCloud全面学习笔记之进阶篇
目录 前言微服务保护初识Sentinel雪崩问题及解决方案雪崩问题超时处理仓壁模式熔断降级流量控制总结 服务保护技术对比Sentinel介绍和安装微服务整合Sentinel 流量控制快速入门流控模式关联模式链路模式小结 流控效果warm up排队等待 热点参数限流全局参数限流热点参数限流案例…...
英语中主语从句的概念及其用法,例句(不断更新)
主语从句的原理 主语从句是一种充当整个句子主语的从句,主语从句构成的句子,是要以引导词开头的。它可以用名词性从属连词、关系代词或关系副词引导。主语从句通常位于谓语动词之前,用于表示动作、状态或事件的主体。 以下是一些常用的引导主…...
数组的子数组(亚阵列)、子序列,字符串的子串、子序列
数组 子数组 一个或连续多个数组中的元素组成一个子数组 子数组最少包含一个元素 数组 {1, 2, 3} 的子数组是 {1}, {1, 2}, {1, 2, 3}, {2}, {2, 3}, 和 {3}. 子序列 子序列就是在原来序列中找出一部分组成的序列 子序列不一定连续 相对位置还是不变 但是ÿ…...
MySQL 知识:迁移数据目录到其他路径
一、系统环境 操作系统:Centos 7 已安装环境:MySQL 8.0.26 二、开始操作 2.1 关闭SELinux 为了提高 Linux 系统的安全性,在 Linux 上通常会使用 SELinux 或 AppArmor 实现强制访问控制(Mandatory Access Control MACÿ…...
Go | 一分钟掌握Go | 8 - 并发
作者:Mars酱 声明:本文章由Mars酱编写,部分内容来源于网络,如有疑问请联系本人。 转载:欢迎转载,转载前先请联系我! 前言 当今编程界,一个好的编译型语言如果不支持并发,…...
【滤波】多元高斯
本文主要翻译自rlabbe/Kalman-and-Bayesian-Filters-in-Python的第5章节05-Multivariate-Gaussians(多元高斯)。 %matplotlib inline#format the book import book_format book_format.set_style()简介 上一篇文章中的技术非常强大,但它们只…...
单源最短路问题
全部代码 全部代码在github acwing 上 正在更新 https://github.com/stolendance/acwing 图论 欢迎大家star与fork 单源最短路问题 先用spfa算法 不行再换其他的 spfa-超级万能 说不定比dijsktra还快 dis[] 代表第k到某一点的最短距离 queue 代表刚被更新的点 它有可能更…...
Security方法注解权限控制过程及自定义权限表达式
文章目录 使用内置的权限表达式PreAuthorizePermissionEvaluator 自定义权限表达式SysMethodSecurityExpressionHandler源码流程 SysMethodSecurityExpressionRoot 使用内置的权限表达式 PreAuthorize 这个用来判断超级管理员的话,还得在表达式上加上或 Permissi…...
vue 省市县三级联动
1、 <template><div>所在省<el-select popper-class"eloption" :popper-append-to-body"true"change"getShiList(obj.province)" v-model"obj.province" placeholder"请选择所在省" clearableclear"re…...
ChatGPT实现编程语言转换
编程语言转换 对于程序员来说,往往有一类工作,是需要将一部分业务逻辑实现从服务端转移到客户端,或者从客户端转移到服务端。这类工作,通常需要将一种编程语言的代码转换成另一种编程语言的代码,这就需要承担这项工作…...
浅拷贝和深拷贝
浅拷贝: 定义:浅拷贝(Shallow Copy)是一种简单的对象复制方式,将一个对象的数据成员直接复制给另一个对象(通常是通过默认的复制构造函数或赋值运算符实现),这些数据成员可以是基本…...
进程地址空间与页表方面知识点(缺页中断及写时拷贝部分原理)
谢谢阅读,如有错误请大佬留言!! 目录 谢谢阅读,如有错误请大佬留言!! 抛出总结 开始介绍 发现问题 进程地址空间(虚拟地址) 页表 物理内存与进程地址空间映射 缺页中断基本…...
SkyWalking 10.2.0 SWCK 配置过程
SkyWalking 10.2.0 & SWCK 配置过程 skywalking oap-server & ui 使用Docker安装在K8S集群以外,K8S集群中的微服务使用initContainer按命名空间将skywalking-java-agent注入到业务容器中。 SWCK有整套的解决方案,全安装在K8S群集中。 具体可参…...
Linux相关概念和易错知识点(42)(TCP的连接管理、可靠性、面临复杂网络的处理)
目录 1.TCP的连接管理机制(1)三次握手①握手过程②对握手过程的理解 (2)四次挥手(3)握手和挥手的触发(4)状态切换①挥手过程中状态的切换②握手过程中状态的切换 2.TCP的可靠性&…...
从深圳崛起的“机器之眼”:赴港乐动机器人的万亿赛道赶考路
进入2025年以来,尽管围绕人形机器人、具身智能等机器人赛道的质疑声不断,但全球市场热度依然高涨,入局者持续增加。 以国内市场为例,天眼查专业版数据显示,截至5月底,我国现存在业、存续状态的机器人相关企…...
Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...
dedecms 织梦自定义表单留言增加ajax验证码功能
增加ajax功能模块,用户不点击提交按钮,只要输入框失去焦点,就会提前提示验证码是否正确。 一,模板上增加验证码 <input name"vdcode"id"vdcode" placeholder"请输入验证码" type"text&quo…...
Java入门学习详细版(一)
大家好,Java 学习是一个系统学习的过程,核心原则就是“理论 实践 坚持”,并且需循序渐进,不可过于着急,本篇文章推出的这份详细入门学习资料将带大家从零基础开始,逐步掌握 Java 的核心概念和编程技能。 …...
免费数学几何作图web平台
光锐软件免费数学工具,maths,数学制图,数学作图,几何作图,几何,AR开发,AR教育,增强现实,软件公司,XR,MR,VR,虚拟仿真,虚拟现实,混合现实,教育科技产品,职业模拟培训,高保真VR场景,结构互动课件,元宇宙http://xaglare.c…...
打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用
一、方案背景 在现代生产与生活场景中,如工厂高危作业区、医院手术室、公共场景等,人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式,存在效率低、覆盖面不足、判断主观性强等问题,难以满足对人员打手机行为精…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
《Docker》架构
文章目录 架构模式单机架构应用数据分离架构应用服务器集群架构读写分离/主从分离架构冷热分离架构垂直分库架构微服务架构容器编排架构什么是容器,docker,镜像,k8s 架构模式 单机架构 单机架构其实就是应用服务器和单机服务器都部署在同一…...
