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)是一种简单的对象复制方式,将一个对象的数据成员直接复制给另一个对象(通常是通过默认的复制构造函数或赋值运算符实现),这些数据成员可以是基本…...
进程地址空间与页表方面知识点(缺页中断及写时拷贝部分原理)
谢谢阅读,如有错误请大佬留言!! 目录 谢谢阅读,如有错误请大佬留言!! 抛出总结 开始介绍 发现问题 进程地址空间(虚拟地址) 页表 物理内存与进程地址空间映射 缺页中断基本…...
IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...
【碎碎念】宝可梦 Mesh GO : 基于MESH网络的口袋妖怪 宝可梦GO游戏自组网系统
目录 游戏说明《宝可梦 Mesh GO》 —— 局域宝可梦探索Pokmon GO 类游戏核心理念应用场景Mesh 特性 宝可梦玩法融合设计游戏构想要素1. 地图探索(基于物理空间 广播范围)2. 野生宝可梦生成与广播3. 对战系统4. 道具与通信5. 延伸玩法 安全性设计 技术选…...
如何在网页里填写 PDF 表格?
有时候,你可能希望用户能在你的网站上填写 PDF 表单。然而,这件事并不简单,因为 PDF 并不是一种原生的网页格式。虽然浏览器可以显示 PDF 文件,但原生并不支持编辑或填写它们。更糟的是,如果你想收集表单数据ÿ…...
HashMap中的put方法执行流程(流程图)
1 put操作整体流程 HashMap 的 put 操作是其最核心的功能之一。在 JDK 1.8 及以后版本中,其主要逻辑封装在 putVal 这个内部方法中。整个过程大致如下: 初始判断与哈希计算: 首先,putVal 方法会检查当前的 table(也就…...
管理学院权限管理系统开发总结
文章目录 🎓 管理学院权限管理系统开发总结 - 现代化Web应用实践之路📝 项目概述🏗️ 技术架构设计后端技术栈前端技术栈 💡 核心功能特性1. 用户管理模块2. 权限管理系统3. 统计报表功能4. 用户体验优化 🗄️ 数据库设…...
Spring是如何解决Bean的循环依赖:三级缓存机制
1、什么是 Bean 的循环依赖 在 Spring框架中,Bean 的循环依赖是指多个 Bean 之间互相持有对方引用,形成闭环依赖关系的现象。 多个 Bean 的依赖关系构成环形链路,例如: 双向依赖:Bean A 依赖 Bean B,同时 Bean B 也依赖 Bean A(A↔B)。链条循环: Bean A → Bean…...
LangFlow技术架构分析
🔧 LangFlow 的可视化技术栈 前端节点编辑器 底层框架:基于 (一个现代化的 React 节点绘图库) 功能: 拖拽式构建 LangGraph 状态机 实时连线定义节点依赖关系 可视化调试循环和分支逻辑 与 LangGraph 的深…...
shell脚本质数判断
shell脚本质数判断 shell输入一个正整数,判断是否为质数(素数)shell求1-100内的质数shell求给定数组输出其中的质数 shell输入一个正整数,判断是否为质数(素数) 思路: 1:1 2:1 2 3:1 2 3 4:1 2 3 4 5:1 2 3 4 5-------> 3:2 4:2 3 5:2 3…...
2025 后端自学UNIAPP【项目实战:旅游项目】7、景点详情页面【完结】
1、获取景点详情的请求【my_api.js】 // 引入公共的请求封装 import http from ./my_http.js// 登录接口(适配服务端返回 Token) export const login async (code, avatar) > {const res await http(/login/getWXSessionKey, {code,avatar}); };//…...
break 语句和 continue 语句
break语句和continue语句都具有跳转作用,可以让代码不按既有的顺序执行 break break语句用于跳出代码块或循环 1 2 3 4 5 6 for (var i 0; i < 5; i) { if (i 3){ break; } console.log(i); } continue continue语句用于立即终…...
