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

Qt/C++音视频开发49-推流到各种流媒体服务程序

一、前言

最近将推流程序完善了很多功能,尤其是增加了对多种流媒体服务程序的支持,目前支持mediamtx、LiveQing、EasyDarwin、nginx-rtmp、ZLMediaKit、srs、ABLMediaServer等,其中经过大量的对比测试,个人比较建议使用mediamtx和ZLMediaKit,因为这两者支持的格式众多,不仅同时支持rtsp/rtmp推流,还支持各种格式rtsp/rtmp/hls/flv/ws-flv/webrtc等拉流,涵盖面非常全,而且拉流的画面非常流畅,在局域网没有出现花屏的现象,对视频文件、视频流支持都非常友好。

为了增强程序的拓展性,以便适应后期增加其他流媒体服务器程序,特意将流媒体服务程序的信息用配置文件存取来,可以自行增删改,推流和拉流对应的端口都可以自行修改,这样非常适用于一台电脑多种流媒体服务,通过配置不同的端口来保证同时推流到多个流媒体服务程序,比如windows系统554端口很可能被系统的进程占用,所以需要更改为其他端口,在流媒体服务程序对应的配置文件更改后,还需要在推流程序对应的配置文件中修改,这样后期如果增加了其他的流媒体服务程序,只需要在配置文件增加即可,程序会自动读取并加载到下拉框。

二、效果图

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

三、体验地址

  1. 国内站点:https://gitee.com/feiyangqingyun
  2. 国际站点:https://github.com/feiyangqingyun
  3. 个人作品:https://blog.csdn.net/feiyangqingyun/article/details/97565652
  4. 体验地址:https://pan.baidu.com/s/1d7TH_GEYl5nOecuNlWJJ7g 提取码:01jf 文件名:bin_video_push。

四、功能特点

  1. 支持各种本地视频文件和网络视频文件。
  2. 支持各种网络视频流,网络摄像头,协议包括rtsp、rtmp、http。
  3. 支持将本地摄像头设备推流,可指定分辨率和帧率等。
  4. 支持将本地桌面推流,可指定屏幕区域和帧率等。
  5. 自动启动流媒体服务程序,默认mediamtx(原rtsp-simple-server),可选用srs、EasyDarwin、LiveQing、ZLMediaKit等。
  6. 可实时切换预览视频文件,可切换视频文件播放进度,切换到哪里就推流到哪里。
  7. 推流的清晰度和质量可调。
  8. 可动态添加文件、目录、地址。
  9. 视频文件自动循环推流,如果视频源是视频流,在掉线后会自动重连。
  10. 网络视频流自动重连,重连成功自动继续推流。
  11. 网络视频流实时性极高,延迟极低,延迟时间大概在100ms左右。
  12. 极低CPU占用,4路主码流推流只需要占用0.2%CPU。理论上常规普通PC机器推100路毫无压力,主要性能瓶颈在网络。
  13. 推流可选推流到rtsp/rtmp两种,推流后的数据支持直接rtsp/rtmp/hls/webrtc四种方式访问,可以直接浏览器打开看实时画面。
  14. 可以推流到外网服务器,然后通过手机、电脑、平板等设备播放对应的视频流。
  15. 每个推流都可以手动指定唯一标识符(方便拉流/用户无需记忆复杂的地址),没有指定则按照策略随机生成hash值。
  16. 自动生成测试网页直接打开播放,可以看到实时效果,自动按照数量对应宫格显示。
  17. 推流过程中可以在表格中切换对应推流项,实时预览正在推流的视频,并可以切换视频文件的播放进度。
  18. 音视频同步推流,符合264/265/aac格式的自动原数据推流,不符合的自动转码再推流(会占用一定CPU)。
  19. 转码策略支持三种,自动处理(符合要求的原数据/不符合的转码),仅限文件(文件类型的转码视频),所有转码。
  20. 表格中实时显示每一路推流的分辨率和音视频数据状态,灰色表示没有输入流,黑色表示没有输出流,绿色表示原数据推流,红色表示转码后的数据推流。
  21. 自动重连视频源,自动重连流媒体服务器,保证启动后,推流地址和打开地址都实时重连,只要恢复后立即连上继续采集和推流。
  22. 提供循环推流示例,一个视频源同时推流到多个流媒体服务器,比如打开一个视频同时推流到抖音/快手/B站等,可以作为录播推流,列表循环,非常方便实用。
  23. 根据不同的流媒体服务器类型,自动生成对应的rtsp/rtmp/hls/flv/ws-flv/webrtc地址,用户可以直接复制该地址到播放器或者网页中预览查看。
  24. 编码视频格式可以选择自动处理(源头是264就264/源头是265就265),转H264(强制转264),转H265(强制转265)。
  25. 支持Qt4/Qt5/Qt6任意版本,支持任意系统(windows/linux/macos/android/嵌入式linux等)。

五、相关代码

QList<QString> VideoPushUrl::listPushType = QList<QString>();
QList<QString> VideoPushUrl::listPullType = QList<QString>();
QList<int> VideoPushUrl::listPullPort = QList<int>();void VideoPushUrl::initServerInfo()
{listPushType.clear();listPullType.clear();listPullPort.clear();listPushType << "mediamtx" << "mediamtx" << "mediamtx" << "mediamtx";listPullType << "rtsp" << "rtmp" << "hls" << "webrtc";listPullPort << 8554 << 1935 << 8888 << 8889;listPushType << "LiveQing" << "LiveQing" << "LiveQing" << "LiveQing" << "LiveQing";listPullType << "rtmp" << "hls" << "flv" << "ws-flv" << "webrtc";listPullPort << 10085 << 18000 << 18000 << 18000 << 18000;listPushType << "EasyDarwin";listPullType << "rtsp";listPullPort << 5541;listPushType << "nginx-rtmp";listPullType << "rtmp";listPullPort << 1935;listPushType << "ZLMediaKit" << "ZLMediaKit" << "ZLMediaKit" << "ZLMediaKit" << "ZLMediaKit" << "ZLMediaKit";listPullType << "rtsp" << "rtmp" << "hls" << "flv" << "ws-flv" << "webrtc";listPullPort << 554 << 1935 << 80 << 80 << 80 << 80;listPushType << "srs" << "srs" << "srs" << "srs";listPullType << "rtmp" << "hls" << "flv" << "webrtc";listPullPort << 1935 << 8080 << 8080 << 8080;listPushType << "ABLMediaServer" << "ABLMediaServer" << "ABLMediaServer" << "ABLMediaServer" << "ABLMediaServer";listPullType << "rtsp" << "rtmp" << "hls" << "flv" << "ws-flv";listPullPort << 554 << 1935 << 9088 << 8088 << 6088;
}void VideoPushUrl::initServerInfo(const QString &fileName)
{listPushType.clear();listPullType.clear();listPullPort.clear();QFile file(fileName);if (file.open(QFile::ReadOnly | QFile::Text)) {while (!file.atEnd()) {QString content = file.readLine();content.replace("\r", "");content.replace("\n", "");if (content.isEmpty()) {continue;}QStringList list = content.split(",");if (list.count() == 3) {listPushType << list.at(0);listPullType << list.at(1);listPullPort << list.at(2).toInt();}}}
}QStringList VideoPushUrl::getPushType()
{QStringList types;foreach (QString type, listPushType) {if (!types.contains(type)) {types << type;}}return types;
}QString VideoPushUrl::getPushPath(const QString &pushUrl)
{//("rtsp:", "", "127.0.0.1:5541") ("rtsp:", "", "127.0.0.1:5541", "live") ("rtsp:", "", "127.0.0.1:5541", "live/test")QString path = "/";QStringList list = pushUrl.split("/");int count = list.count();//从第三位开始后面所有的都是资源目录for (int i = 3; i < count; ++i) {path = path + list.at(i) + "/";}//末尾的斜杠去掉return path.mid(0, path.length() - 1);
}int VideoPushUrl::getPullPort(const QString &pushType, const QString &pullType)
{int port = 80;int count = listPushType.count();for (int i = 0; i < count; ++i) {if (listPushType.at(i) == pushType && listPullType.at(i) == pullType) {port = listPullPort.at(i);break;}}return port;
}//各种拉流协议分析 https://www.cnblogs.com/xi-jie/p/14031604.html
QString VideoPushUrl::getPullUrl(const QString &pushUrl, const QString &pushType, const QString &pullType, const QString &ip, const QString &flag)
{//找到对应服务器类型和拉流类型的端口int port = getPullPort(pushType, pullType);//资源目录(可以为空)QString path = getPushPath(pushUrl);//去掉特殊字符比如?QString name = flag.split("?").first();//根据服务器类型获取对应的地址QString url = QString("://%1:%2%3/%4").arg(ip).arg(port).arg(path).arg(name);if (pushType == "mediamtx") {//同时支持rtsp/rtmp推拉流(非常棒)if (pullType == "rtsp") {url = "rtsp" + url;} else if (pullType == "rtmp") {url = "rtmp" + url;} else if (pullType == "hls") {url = "http" + url;} else if (pullType == "webrtc") {url = "http" + url;}} else if (pushType == "LiveQing") {//只支持rtmp推流if (pullType == "rtmp") {url = QString("rtmp://%1:%2/hls/%3").arg(ip).arg(port).arg(name);} else if (pullType == "hls") {url = QString("http://%1:%2/hls/%3/%3_live.m3u8").arg(ip).arg(port).arg(name);} else if (pullType == "flv") {url = QString("http://%1:%2/flv/hls/%3.flv").arg(ip).arg(port).arg(name);} else if (pullType == "ws-flv") {url = QString("ws://%1:%2/ws-flv/hls/%3.flv").arg(ip).arg(port).arg(name);} else if (pullType == "webrtc") {url = QString("webrtc://%1:%2/rtc/hls/%3").arg(ip).arg(port).arg(name);}} else if (pushType == "EasyDarwin") {//只支持rtsp推流拉流if (pullType == "rtsp") {url = "rtsp" + url;}} else if (pushType == "nginx-rtmp") {//只支持rtmp推流拉流if (pullType == "rtmp") {url = "rtmp" + url;}} else if (pushType == "ZLMediaKit") {//同时支持rtsp/rtmp推拉流(名气最大/用户最多)if (pullType == "rtsp") {url = "rtsp" + url;} else if (pullType == "rtmp") {url = "rtmp" + url;} else if (pullType == "hls") {url = "http" + url + "/hls.m3u8";} else if (pullType == "flv") {url = "http" + url + ".live.flv";} else if (pullType == "ws-flv") {url = "ws" + url + ".live.flv";} else if (pullType == "webrtc") {}} else if (pushType == "srs") {//不支持rtsp推流拉流(以前支持/后面都移除了)if (pullType == "rtmp") {url = "rtmp" + url;} else if (pullType == "hls") {url = "http" + url + ".m3u8";} else if (pullType == "flv") {url = "http" + url + ".flv";} else if (pullType == "webrtc") {url = "webrtc" + url;}} else if (pushType == "ABLMediaServer") {//支持rtsp/rtmp推流拉流(目前还不稳定/兼容性不够好)if (pullType == "rtsp") {url = "rtsp" + url;} else if (pullType == "rtmp") {url = "rtmp" + url;} else if (pullType == "hls") {url = "http" + url + ".m3u8";} else if (pullType == "flv") {url = "http" + url + ".flv";} else if (pullType == "ws-flv") {url = "ws" + url + ".flv";}} else if (pushType == "Monibuca") {//支持rtsp/rtmp推流拉流(拉流格式众多/各种插件/性能很强劲/具体有待验证)if (pullType == "rtsp") {url = "rtsp" + url;} else if (pullType == "rtmp") {url = "rtmp" + url;} else if (pullType == "hls") {url = QString("http://%1:%2/hls%3/%4.m3u8").arg(ip).arg(port).arg(path).arg(name);} else if (pullType == "flv") {url = QString("http://%1:%2/hdl%3/%4.flv").arg(ip).arg(port).arg(path).arg(name);} else if (pullType == "ws-flv") {url = QString("ws://%1:%2/jessica%3/%4.flv").arg(ip).arg(port).arg(path).arg(name);} else if (pullType == "webrtc") {url = QString("webrtc://%1:%2/webrtc/play%3/%4").arg(ip).arg(port).arg(path).arg(name);}}return url;
}

相关文章:

Qt/C++音视频开发49-推流到各种流媒体服务程序

一、前言 最近将推流程序完善了很多功能&#xff0c;尤其是增加了对多种流媒体服务程序的支持&#xff0c;目前支持mediamtx、LiveQing、EasyDarwin、nginx-rtmp、ZLMediaKit、srs、ABLMediaServer等&#xff0c;其中经过大量的对比测试&#xff0c;个人比较建议使用mediamtx和…...

深度学习学习笔记——解决过拟合问题的方法:权重衰减和暂退法,与正则化之间的关系

解决过拟合问题是机器学习和深度学习中关键的任务之一&#xff0c;因为它会导致模型在训练数据上表现良好&#xff0c;但在未见数据上表现不佳。以下是一些解决过拟合问题的常见方法&#xff1a; 增加训练数据&#xff1a; 增加更多的训练数据可以帮助模型更好地捕捉数据的真实…...

【Leetcode Sheet】Weekly Practice 5

Leetcode Test 823 带因子的二叉树(8.29) 给出一个含有不重复整数元素的数组 arr &#xff0c;每个整数 arr[i] 均大于 1。 用这些整数来构建二叉树&#xff0c;每个整数可以使用任意次数。其中&#xff1a;每个非叶结点的值应等于它的两个子结点的值的乘积。 满足条件的二…...

STM32 SPI对存储芯片发送写是能命令后一直忙等待

我采用CUBE配置的SPI外设&#xff0c;对NSS引脚选择了硬件输出&#xff0c;这种方式对读取命令没有影响&#xff0c;但是对写命令有&#xff0c;当我发送写是能命令后&#xff0c;读取状态寄存器的值一直都是忙&#xff0c;我猜测这可能是硬件控制NSS引脚后&#xff0c;对于HAL…...

MySql学习笔记01——SQL的相关术语

SQL&#xff08;相关术语&#xff09; 数据库database 有组织的存储数据的容器&#xff0c;通常是一个文件或者一组文件 表table 存储数据的文件称为表&#xff0c;表是某种特定数据的结构化清单。 表可以保存顾客清单、产品目录&#xff0c;或者其他信息清单。 要注意的是&am…...

SpringMVC入门指南

目录 前言 一、什么是SpringMVC 二、MVC架构模式 三、SpringMVC的工作流程 四、SpringMVC核心组件 五、SpringMVC的优势 六、SpringMVC的配置与常用注解 七、SpringMvc请求处理流程、 控制器的编写 、视图的渲染 1.请求处理流程&#xff1a; 2.控制器的编写&#xff1…...

mysql忘记root密码如何解决?

第一步&#xff1a;首先右键此电脑打开管理器&#xff0c;查看mysql是否运行 第二步&#xff1a;用管理员模式打开命令框 输入net stop mysql暂停mysql运行 net stop mysql 然后输入下面指令 mysql --console --skip-grant-tables --shared-memory 显示如下 第三步&…...

ChatGPT可以生成Windows密钥

ChatGPT 可以回答许多问题、生成和修改代码&#xff0c;最近还可以生成 Windows 10 和 Windows 11 的许可证密钥。自从 OpenAI 的 ChatGPT 推出以来&#xff0c;人工智能已成为许多用户面临的挑战。 他们不断地试图削弱这种智力&#xff0c;或者想尝试它的局限性和可能性。例如…...

jupyter notebook内核启动报错:ImportError: DLL load failed while importing _device

1.报错信息 File “D:\Programs\Programming\Anaconda3\envs\pytorch_mis\lib\site-packages\zmq\backend\cython_init_.py”, line 6, in from . import ( ImportError: DLL load failed while importing _device: 找不到指定的模块。 2.解决方案 pyzmq版本冲突&#xff0…...

蓝桥杯备赛(Day5)——二叉树

二叉树存储 普通做法&#xff0c;二叉树一个节点包括结点的数值以及指向左右子节点的指针 在class Node中 def __init__(self,s,lNone,rNone):self.valNoneself.llself.rr 在竞赛中&#xff0c;我们往往使用静态数组实现二叉树&#xff0c;定义一个大小为N的静态结构体数组…...

实现Android APK瘦身99.99%

摘要&#xff1a; 如何瘦身是 APK 的重要优化技术。APK 在安装和更新时都需要经过网络下载到设备&#xff0c;APK 越小&#xff0c;用户体验越好。本文作者通过对 APK 内在机制的详细解析&#xff0c;给出了对 APK 各组成成分的优化方法及技术&#xff0c;并实现了一个基本 APK…...

webScoket长连接人性化解读

今天我们来整理一下webScoket&#xff0c;首先 webScoket是HTML5提出的一个基于TCP的一个全双工可靠通讯协议&#xff0c;处在应用层。很多人喜欢说webScoket是一次连接&#xff0c;这是误区&#xff0c;其实他是基于TCP的只不过将三次握手与四次挥手进行隐藏&#xff0c;封装。…...

ESDA in PySal (1) 利用 A-DBSCAN 聚类点并探索边界模糊性

ESDA in PySAL (1) 利用 A-DBSCAN 聚类点并探索边界模糊性 在本例中,我们将以柏林的 AirBnb 房源样本为例,说明如何使用 A-DBSCAN (Arribas-Bel et al., 2019)。A-DBSCAN 可以让我们做两件事: 识别高密度 AirBnb 房源集群并划定其边界探索这些边界的稳定性%matplotlib inli…...

利用GitHub实现域名跳转

利用GitHub实现域名跳转 一、注册一个 github账号 你需要注册一个 github账号,最好取一个有意义的名字&#xff0c;比如姓名全拼&#xff0c;昵称全拼&#xff0c;如果被占用&#xff0c;可以加上有意义的数字. 本文中假设用户名为 UNIT-wuji(也是我的博客名) 地址: https:/…...

【Linux详解】——共享内存

&#x1f4d6; 前言&#xff1a;本期介绍共享内存。 目录 &#x1f552; 1. 共享内存的原理&#x1f552; 2. 共享内存的概念&#x1f558; 2.1 接口认识&#x1f558; 2.2 演示生成key的唯一性&#x1f558; 2.3 再谈key &#x1f552; 3. 共享内存相关命令&#x1f552; 4. 利…...

Golang 几个不错的实用函数库

文章目录 samber/lothoas/go-funkduke-git/lancetelliotchance/piegookit/goutildablelv/cyan 大咖好呀&#xff0c;我是恋喵大鲤鱼。 Golang 标准库是 Go 语言自带的一组核心功能库&#xff0c;功能全面&#xff0c;易于使用。 在 Golang 标准库的基础上&#xff0c;还可以进…...

【Linux】地址空间概念

目录 前言&#xff1a; 地址空间回顾 验证&#xff1a;一个变量是否会有两个值&#xff1f; 一. 什么是地址空间 虚拟地址与物理地址之间的关系 二. 地址空间是如何设计的 1. 回答一个变量两个值 2.扩展 继续深入理解 三. 为什么要有地址空间 原因&#xff1a; 1. 使…...

视频集中存储/直播点播平台EasyDSS点播文件分类功能新升级

视频推拉流EasyDSS视频直播点播平台&#xff0c;集视频直播、点播、转码、管理、录像、检索、时移回看等功能于一体&#xff0c;可提供音视频采集、视频推拉流、播放H.265编码视频、存储、分发等视频能力服务。 TSINGSEE青犀视频的EasyDSS平台具有点播文件分类展示方法&#xf…...

JavaScript基础06——let和var两个关键字有啥不同

哈喽&#xff0c;小伙伴们大家好&#xff0c;我是雷工&#xff01; 每日学习一点点&#xff0c;今天继续学习JavaScript基础知识&#xff0c;下面是学习笔记。 1、变量的本质 内存&#xff1a;计算机中存储数据的地方&#xff0c;相当于一空间。 变量的本质&#xff1a;是程序…...

Apache Doris 2.0.1 1.2.7 版本正式发布!

亲爱的社区小伙伴们&#xff0c;我们很高兴的宣布&#xff0c;2023 年 9 月 4 日 我们正式发布了 Apache Doris 2.0.1 和 Apache Doris 1.2.7 这两个版本&#xff0c;这两个版本由上百名位贡献者共同努力完成的&#xff0c;提供了更多有用的新特性&#xff0c;同时修复了若干已…...

Linux 文件类型,目录与路径,文件与目录管理

文件类型 后面的字符表示文件类型标志 普通文件&#xff1a;-&#xff08;纯文本文件&#xff0c;二进制文件&#xff0c;数据格式文件&#xff09; 如文本文件、图片、程序文件等。 目录文件&#xff1a;d&#xff08;directory&#xff09; 用来存放其他文件或子目录。 设备…...

label-studio的使用教程(导入本地路径)

文章目录 1. 准备环境2. 脚本启动2.1 Windows2.2 Linux 3. 安装label-studio机器学习后端3.1 pip安装(推荐)3.2 GitHub仓库安装 4. 后端配置4.1 yolo环境4.2 引入后端模型4.3 修改脚本4.4 启动后端 5. 标注工程5.1 创建工程5.2 配置图片路径5.3 配置工程类型标签5.4 配置模型5.…...

(十)学生端搭建

本次旨在将之前的已完成的部分功能进行拼装到学生端&#xff0c;同时完善学生端的构建。本次工作主要包括&#xff1a; 1.学生端整体界面布局 2.模拟考场与部分个人画像流程的串联 3.整体学生端逻辑 一、学生端 在主界面可以选择自己的用户角色 选择学生则进入学生登录界面…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

微服务商城-商品微服务

数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

C# 求圆面积的程序(Program to find area of a circle)

给定半径r&#xff0c;求圆的面积。圆的面积应精确到小数点后5位。 例子&#xff1a; 输入&#xff1a;r 5 输出&#xff1a;78.53982 解释&#xff1a;由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982&#xff0c;因为我们只保留小数点后 5 位数字。 输…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

【C++进阶篇】智能指针

C内存管理终极指南&#xff1a;智能指针从入门到源码剖析 一. 智能指针1.1 auto_ptr1.2 unique_ptr1.3 shared_ptr1.4 make_shared 二. 原理三. shared_ptr循环引用问题三. 线程安全问题四. 内存泄漏4.1 什么是内存泄漏4.2 危害4.3 避免内存泄漏 五. 最后 一. 智能指针 智能指…...