一、前言

最近将推流程序完善了很多功能,尤其是增加了对多种流媒体服务程序的支持,目前支持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-推流到各种流媒体服务程序的更多相关文章

  1. WebRTC 音视频开发

    WebRTC 音视频开发 webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译 ...

  2. Android 音视频开发学习思路

    Android 音视频开发这块目前的确没有比较系统的教程或者书籍,网上的博客文章也都是比较零散的.只能通过一点点的学习和积累把这块的知识串联积累起来. 初级入门篇: Android 音视频开发(一) ...

  3. 转:Android IOS WebRTC 音视频开发总结 (系列文章集合)

    随笔分类 - webrtc   Android IOS WebRTC 音视频开发总结(七八)-- 为什么WebRTC端到端监控很关键? 摘要: 本文主要介绍WebRTC端到端监控(我们翻译和整理的,译 ...

  4. Python音视频开发:消除抖音短视频Logo的图形化工具实现

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 在<Python音视频开发:消除抖音短视频Logo和去电视台标的实现详解>节介绍了怎么通过Python+Moviepy+OpenCV实现 ...

  5. Moviepy音视频开发:视频转gif动画或jpg图片exe图形化工具开发案例

    ☞ ░ 前往老猿Python博文目录 ░ 一.引言 老猿之所以学习和研究Moviepy的使用,是因为需要一个将视频转成动画的工具,当时在网上到处搜索查找免费使用工具,结果找了很多自称免费的工具,但转完 ...

  6. 【秒懂音视频开发】02_Windows开发环境搭建

    音视频开发库的选择 每个主流平台基本都有自己的音视频开发库(API),用以处理音视频数据,比如: iOS:AVFoundation.AudioUnit等 Android:MediaPlayer.Med ...

  7. Android音视频开发(1):H264 基本原理

    前言 H264 视频压缩算法现在无疑是所有视频压缩技术中使用最广泛,最流行的.随着 x264/openh264 以及 ffmpeg 等开源库的推出,大多数使用者无需再对H264的细节做过多的研究,这大 ...

  8. Android IOS WebRTC 音视频开发总结(八十五)-- 使用WebRTC广播网络摄像头视频(下)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  9. Android IOS WebRTC 音视频开发总结(八十三)-- 使用WebRTC广播网络摄像头视频(上)

    本文主要介绍WebRTC (我们翻译和整理的,译者:weizhenwei,校验:blacker),最早发表在[编风网] 支持原创,转载必须注明出处,欢迎关注我的微信公众号blacker(微信ID:bl ...

  10. Android IOS WebRTC 音视频开发总结(四六)-- 从另一个角度看国内首届WebRTC大会

    文章主要从开发者角度谈国内首届WebRTC大会,支持原创,文章来自博客园RTC.Blacker,支持原创,转载必须说明出处,更多详见www.rtc.help. -------------------- ...

随机推荐

  1. vue2基于 vue-cropper插件对图片裁剪

    <template> <div id="app"> <div class="model" v-show="model&q ...

  2. linux命令杂记

    chmod 777 lixiangj 修改目录为共享权限cd .. 跳转上一级目录cd - 跳转上一次跳转的目录ll 查看目录下所有文件ctrl+L 清除屏幕内容| head -10 只看结果中的前1 ...

  3. SaaS架构:应用服务、应用结构设计

    大家好,我是汤师爷~ 应用架构设计通常包括以下步骤: 根据业务架构,将业务需求转化为IT系统,识别核心应用服务. 划分应用结构,设计应用结构与业务流程.数据之间的关系. 设计应用结构之间的交互和集成关 ...

  4. 云原生周刊:Kubernetes v1.29 正式发布 | 2023.12.18

    开源项目推荐 Robusta KRR Robusta KRR(Kubernetes Resource Recommender)是一个用于优化 Kubernetes 集群中资源分配的 CLI 工具.它从 ...

  5. 写代码被大语言模型坑之使用LocalDateTime比较两个时间差了几天

    自从去年ChatGPT3.5发布后使用了几次,现在写代码基本上离不开它和它的衍生产品们了.一方面查资料很方便,快速提炼要点总结:另一方面想写什么样的代码一问就能生成出来,功能大差不差,稍微改改就能用, ...

  6. 生成文本聚类java实现1

    本章主要的学习是中文分词 和两种统计词频(传统词频和TF-IDF算法 ) 的方法. 学习目的:通过N多的新闻标题 or 新闻摘要 or 新闻标签,生成基本的文本聚类,以便统计当天新闻的热点内容. 扩展 ...

  7. typescript 编译报错 不能用于索引类型

    Element implicitly has an 'any' type because expression of type 'any' can't be used to index type 't ...

  8. 教程:搭建一个我的世界模组服务器(Linux)

    首先给自己的服务器打个广告 服务器版本1.12.2 地址:www.verysucksminecraftserver.top(好像只有一个月) 所需Mod网盘:https://pan.quark.cn/ ...

  9. reg文件书写规则

    reg文件可以很方便地用来修改注册表,这里记录一下reg文件的书写规则. 注释 分号(;)后面的内容是注释,导入时会忽略这些内容. 文件基本格式 首行写: Windows Registry Edito ...

  10. chrome标签同步神器插件-集装箱!

    前言 最近无法忍受360极速浏览器铺天盖地的广告.也无法忍受火狐浏览器的耗内存打开慢的情况.最终又把浏览器换回了Chrome.总所周知Chrome在国内使用的最大问题是同步书签.扩展等功能受到网络环境 ...