麒麟操作系统|Linux下低延时RTMP|RTSP直播播放实现

背景

        国产操作系统多为以Linux为基础二次开发的操作系统。2014年4月8日起,美国微软公司停止了对Windows XP SP3操作系统提供服务支持,这引起了社会和广大用户的广泛关注和对信息安全的担忧。而2020年对Windows7服务支持的终止再一次推动了国产系统的发展。
        工信部对此表示,将继续加大力度,支持Linux的国产操作系统的研发和应用,并希望用户可以使用国产操作系统。随着信息技术和互联网的快速发展普及,电子商务已经成为不可抗拒的现代商业潮流,云计算、大数据应用日趋成熟,但随之带来了许多问题和挑战。为全面响应国家“互联网+”战略的提出和深入贯彻落实国家“十二五”规划纲要,帮助传统企业开展“商务智慧转型”,加强电子商务深入应用,特别是移动电子商务发展中的环境保障建设,促进电子商务行业健康有序发展,使电子商务相关的技术和经济、法律和规则、诚信和信誉及如何建立一个安全、可靠、可信的电子商务环境,保障电子商务活动中系统、交易的安全性,信息的保密性,已经成为当前亟待需要探讨和解决的重要课题。

国产操作系统|Linux下RTMP|RTSP直播播放

        在发布国产操作系统|Linux平台的RTMP|RTSP直播播放SDK之前,大牛直播SDK(官方)的直播播放SDK无需赘述,采用自研内核框架,功能齐全、高稳定、超低延迟、超低资源占用,覆盖Windows、Android和iOS平台。

        本次发布的可用于国产操作系统和Linux上的的RTMP|RTSP直播播放SDK, 视频绘制使用XLib相关库实现, 音频输出使用PulseAudio和Alsa Lib实现,除了常规功能如实时静音、快照、buffer time设定、网络自动重连等,RTMP支持扩展H265播放, RTSP也支持H265播放。

        播放器接口和调用都比较简单,集成复杂度低,且不依赖于QT。

相关DEMO

        大牛直播SDK发布的Linux平台播放器SDK支持多实例播放,以单个窗体播放为例,相关代码如下:

const char* player_url_ = "rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream";int main(int argc, char *argv[])
{XInitThreads(); // X支持多线程, 必须调用NT_SDKLogInit();// SDK初始化SmartPlayerSDKAPI player_api;if (!NT_PlayerSDKInit(player_api)){fprintf(stderr, "SDK init failed.\n");return 0;}auto display = XOpenDisplay(nullptr);if (!display){fprintf(stderr, "Cannot connect to X server\n");player_api.UnInit();return 0;}display_ = display;auto screen = DefaultScreen(display);auto root = XRootWindow(display, screen);XWindowAttributes root_win_att;if (!XGetWindowAttributes(display, root, &root_win_att)){fprintf(stderr, "Get Root window attri failed\n");player_api.UnInit();XCloseDisplay(display);return 0;}if (root_win_att.width < 100 || root_win_att.height < 100){fprintf(stderr, "Root window size error.\n");player_api.UnInit();XCloseDisplay(display);return 0;}fprintf(stdout, "Root Window Size:%d*%d\n", root_win_att.width, root_win_att.height);int main_w = root_win_att.width / 2, main_h = root_win_att.height / 2;auto black_pixel = BlackPixel(display, screen);auto white_pixel = WhitePixel(display, screen);main_wid_ = XCreateSimpleWindow(display, root, 0, 0, main_w, main_h, 0, white_pixel, black_pixel);if (!main_wid_){fprintf(stderr, "Cannot Create Main Window\n");player_api.UnInit();XCloseDisplay(display);return 0;}XSelectInput(display, main_wid_, StructureNotifyMask | KeyPressMask);auto sub_wid = CreateSubWindow(display, screen, main_wid_);if (!sub_wid){fprintf(stderr, "Cannot Create Render Window\n");player_api.UnInit();XDestroyWindow(display, main_wid_);XCloseDisplay(display);return 0;}XMapWindow(display, main_wid_);XStoreName(display, main_wid_, win_base_title);XMapWindow(display, sub_wid);NT_HANDLE handle = nullptr;// 打开一个播放实例,可以Open多个播放实例, 然后播放多路if (NT_ERC_OK != player_api.Open(&handle, 0, nullptr)){player_api.UnInit();fprintf(stderr, "player_api.Open failed!\n");XDestroyWindow(display, sub_wid);XDestroyWindow(display, main_wid_);XCloseDisplay(display);return 0;}player_api.SetEventCallBack(handle, nullptr, &NT_OnSDKEventHandle);player_api.SetVideoSizeCallBack(handle, nullptr, &NT_SDKVideoSizeHandle);player_api.SetReportDownloadSpeed(handle, 1, 5); // 5秒上报一次下载速度player_api.SetRtspTimeout(handle, 15);player_api.SetRtspAutoSwitchTcpUdp(handle, 1);player_api.SetBuffer(handle, 0); // 设置缓存player_api.SetIsOutputAudioDevice(handle, 1);player_api.SetAudioOutputLayer(handle, 0); // 使用pluse 或者 alsa播放, 两个可以选择一个//player_api.SetAudioVolume(handle, 100);player_api.SetURL(handle, player_url_); // 设置播放地址, rtsp或者rtmp地址player_api.SetXDisplay(handle, display);player_api.SetXScreenNumber(handle, screen);player_api.SetRenderXWindow(handle, sub_wid); // 设置绘制的X窗口player_api.SetRenderScaleMode(handle, 1); // 按比例绘制或者全填充player_api.SetRenderTextureScaleFilterMode(handle, 3); player_api.SetFastStartup(handle, 1);player_api.SetLowLatencyMode(handle, 0);if (NT_ERC_OK != player_api.StartPlay(handle)){player_api.Close(handle);handle = nullptr;player_api.UnInit();fprintf(stderr, "player_api.StartPlay failed!\n");XDestroyWindow(display, sub_wid);XDestroyWindow(display, main_wid_);XCloseDisplay(display);return 0;}while (true){while (MY_X11_Pending(display, 10)){XEvent xev;memset(&xev, 0, sizeof(xev));XNextEvent(display, &xev);if (xev.type == ConfigureNotify){if (xev.xconfigure.window == main_wid_){if (xev.xconfigure.width != main_w || xev.xconfigure.height != main_h){main_w = xev.xconfigure.width;main_h = xev.xconfigure.height;XMoveResizeWindow(display, sub_wid, 0, 0, main_w-4, main_h-4);}}else{if (sub_wid == xev.xconfigure.window){player_api.OnWindowSize(handle, xev.xconfigure.width, xev.xconfigure.height);}}}else if (xev.type == KeyPress){if (xev.xkey.keycode == XKeysymToKeycode(display, XK_Escape)){fprintf(stdout, "ESC Key Press\n");if (handle != nullptr){player_api.StopPlay(handle); // 停止播放player_api.Close(handle);handle = nullptr;}XDestroyWindow(display, sub_wid);XDestroyWindow(display, main_wid_);XCloseDisplay(display);player_api.UnInit();fprintf(stdout, "Close Player....\n");return 0;}}}}
}

日志设置和SDK Init相关

void NT_SDKLogInit()
{SmartLogAPI log_api;memset(&log_api, 0, sizeof(log_api));GetSmartLogAPI(&log_api);log_api.SetLevel(SL_INFO_LEVEL);log_api.SetPath((NT_PVOID)"./");
}bool NT_PlayerSDKInit(SmartPlayerSDKAPI& player_api)
{memset(&player_api, 0, sizeof(player_api));GetSmartPlayerSDKAPI(&player_api);auto ret = player_api.Init(0, nullptr);if (NT_ERC_OK != ret){fprintf(stderr, "player_api.Init failed!\n");return false;}else{fprintf(stdout, "player_api.Init ok!\n");}return true;
}

窗体相关

Display* display_ = nullptr;
Window   main_wid_ = None;const char* win_base_title = "Rtmp/Rtsp Live Player Demo";int EventPoll(int fd, bool is_write, int timeout_ms)
{int result;do{struct pollfd info;info.fd = fd;if (is_write){info.events = POLLOUT;}else{info.events = POLLIN | POLLPRI;}result = poll(&info, 1, timeout_ms);} while (result < 0 && errno == EINTR);return result;
}bool MY_X11_Pending(Display* display, int timeout_ms)
{XFlush(display);if (XEventsQueued(display, QueuedAlready) > 0){return true;}if (EventPoll(ConnectionNumber(display), false, timeout_ms)){if (XPending(display) > 0){return true;}}return false;
}Window CreateSubWindow(Display* display, int screen, Window parent)
{XWindowAttributes  parent_win_att;XGetWindowAttributes(display, parent, &parent_win_att);fprintf(stdout, "parent w:%d, h:%d\n", parent_win_att.width, parent_win_att.height);XSetWindowAttributes swa;swa.border_pixel = WhitePixel(display, screen);swa.event_mask = KeyPressMask | StructureNotifyMask;return XCreateWindow(display, parent, 0, 0, parent_win_att.width-4, parent_win_att.height-4,2, parent_win_att.depth, InputOutput, parent_win_att.visual, CWEventMask | CWBorderPixel, &swa);
}

Event回调

void NT_OnSDKEventHandle(NT_HANDLE handle, NT_PVOID user_data,NT_UINT32 event_id,NT_INT64  param1,NT_INT64  param2,NT_UINT64 param3,NT_PCSTR  param4,NT_PCSTR  param5,NT_PVOID  param6)
{if (NT_SP_E_EVENT_ID_DOWNLOAD_SPEED == event_id){fprintf(stdout, "OnSDKEventHandle handle:%p speed:%lldkbps, %lldKB/s. \r", handle, (param1 * 8) / 1000, param1 / 1024);fflush(stdout);}
}

视频分辨率回调

void NT_SDKVideoSizeHandle(NT_HANDLE handle, NT_PVOID userData,NT_INT32 width, NT_INT32 height)
{if (display_ && main_wid_){std::ostringstream ss;ss << win_base_title << "  [Video Size: " << width << "*" << height << " ]";XStoreName(display_, main_wid_, ss.str().c_str());}
}

相关界面

 总结

国产操作系统|Linux下的RTMP、RTSP直播播放,经实际测试,延迟和Windows平台一样,毫秒级,随着国产操作系统在无纸化同屏等行业的推进,越来越多的场景需要这样一款稳定性高延迟低的RTMP|RTSP播放器,本文抛砖引玉,感兴趣的开发者可酌情参考。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/552909.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于RTMP实现Linux|麒麟操作系统下屏幕|系统声音采集推送

背景 Windows操作系统自问世以来&#xff0c;以其简单易用的图形化界面操作受到大众追捧&#xff0c;为计算机的普及、科技的发展做出了不可磨灭的功绩&#xff0c;也慢慢的成为人们最依赖的操作系统。在中国&#xff0c;90&#xff05;以上的办公环境都是Windows&#xff0c;…

如何快速实现Android平台前端设备接入能力

技术背景 SIP(会话初始化协议)是在 IP网络上进行多媒体通信的应用层控制协议&#xff0c;以几种RFC的形式提供&#xff0c;其中最重要的是包含核心协议规范的RFC3261。该协议用于创建&#xff0c;修改和终止与一个或多个参与者的会话。通过会话&#xff0c;我们了解了一组进行…

长安渝北工厂机器人_长安工厂探秘!解密CS75 PLUS究竟是怎样造出来的

长安CS75 PLUS自打上市以来&#xff0c;销量真的是有目共睹&#xff0c;仅仅一个半月就有3万多的订单&#xff0c;这辆车真的很火很爆款。但我不仅要提出一些疑问了&#xff0c;CS75 PLUS卖这么好&#xff0c;制造工艺怎么样呢&#xff1f;它又是怎么造出来的呢&#xff1f;带着…

threadlocal存连接对象的目的_终于懂了ThreadLocal,不再害怕面试官问了

ThreadLocal解析synchronized和ThreadLocal的区别&#xff1a;synchronized:以时间换空间&#xff0c;只提供一份变量&#xff0c;让不同的线程排队访问&#xff0c;失去了并发性&#xff0c;降低了程序效率&#xff0c;着重对各线程之间访问资源的同步性ThreadLocal:以空间换时…

主板后置音频接口图解_颜值出众、用料靠谱——华擎(ASRock)Z490 Extreme4极限玩家主板 简析...

一、前言你们能想象嘛&#xff0c;那种主板已经到了&#xff0c;处理器却没抢到的感觉。刚开始看到Plus会员提前抢的时候&#xff0c;我心里面还有一些放心&#xff0c;但当时间刚过秒变无货的时候&#xff0c;一切又已回到当初&#xff0c;难受&#xff01;居然没有首发抢到10…

中查出所有姓张的学生为啥查不出来_只有笔试成绩没有面试成绩是什么原因 教师资格面试成绩怎么查...

[闽南网]对于很多同学来说&#xff0c;今晚是个不眠夜。就在几个小时前&#xff0c;教师资格证面试成绩查询入口开通了&#xff0c;相比之前发布的消息&#xff0c;成绩公布提前了很多。参加了这次教师资格证考试的同学&#xff0c;一得到消息就忙着查成绩&#xff0c;毕竟面试…

c++用模板实现稀疏多项式_用线性表实现一元多项式及相加运算

“ 本文主要讨论线性表在多项式计算中的应用&#xff0c;讨论内容涉及到一元n次多项式在计算机中的表示&#xff0c;及多项式相加运算。”01在数学上&#xff0c;一个一元n次多项式可以按照升幂写成Pn(x) p0 p1x p2x2 …… pnxn它由n1个系数唯一确定。因此&#xff0c;一个…

cdh mysql sqoop 驱动_大数据技术之Sqoop学习——原理、安装、使用案例、常用命令...

第1章 Sqoop 简介Sqoop 是一款开源的工具&#xff0c;主要用于在 Hadoop(Hive) 与传统的数据库 (mysql,postgresql,...) 间进行数据的高校传递&#xff0c;可以将一个关系型数据库(例如&#xff1a;MySQL,Oracle,Postgres等)中的数据导入到 Hadoop 的 HDFS 中&#xff0c;也可以…

邮票的孔怎么做出来的_金银花茶是怎么做出来的呢

花期爱亦长&#xff0c;变换自然妆。蝶恋金银露&#xff0c;风柔满院香。说起金银花&#xff0c;可能大家都不陌生&#xff0c;它无论是作为观赏性盆景还是作为金银花养生茶都是非常适宜的。金银花被称为夏天第一花&#xff0c;夏天喝不仅能清热解暑&#xff0c;还能去除许多小…

github上成员贡献量_真祖传代码!你的GitHub代码已打包运往北极,传给1000年后人类...

公众号关注 “ML_NLP”设为 “星标”&#xff0c;重磅干货&#xff0c;第一时间送达&#xff01;晓查 发自 凹非寺 量子位 报道 | 公众号 QbitAI程序员们&#xff0c;激动的消息来了&#xff01;GitHub刚刚公布了一组照片&#xff0c;你的代码上周已经被打包运往北极保存。只要…

握手失败_主人用吃的训练小柴犬握手,老柯基看到后的表现出了吃货的本能!...

贪吃和贪玩是狗狗的天性&#xff0c;也是作为宠物狗它应该做的事情&#xff0c;没有哪一条狗是不贪吃的&#xff0c;如果有&#xff0c;那么肯定是条假狗&#xff01;养狗的人肯定都知道&#xff0c;只要在家你发出一丁点儿口袋的声音&#xff0c;你家狗子当时不管在干什么&…

indesign照片放入太大_猪肚鸡做法复杂,量太大,那来个简易版,用上大厨教的妙招更香了...

【猪肚鸡做法复杂&#xff0c;量太大&#xff0c;那来个简易版&#xff0c;用上大厨教的妙招更香了】天气越来越冷了&#xff0c;今天准备炖鸡汤&#xff0c;正好老妈给了小半个已经处理好的猪肚&#xff0c;所以决定炖个简易版胡椒猪肚鸡。说实话外面的胡椒猪肚鸡做法是比较复…

天气预测频繁2项集_986天气| 今年冬天比往年更冷?官方回应来了

4日下午&#xff0c;中国气象局召开新闻发布会&#xff0c;国家气候中心副主任贾小龙介绍&#xff0c;根据会商意见&#xff0c;我国今冬总体冷空气比较频繁&#xff0c;势力偏强&#xff0c;北方可能出现大范围低温雨雪天气过程。1隆冬季节北方或现大范围低温雨雪天气贾小龙表…

anaconda中安装xgboost_Anaconda是什么?Anconda下载安装教程 - python基础入门(16)

文章首发微信公众号&#xff0c;微信搜索&#xff1a;猿说python一.如果从事Python开发&#xff0c;配置环境需要安装两个包&#xff1a;第一个安装开发工具&#xff0c;俗称IDE : 推荐使用 Pycharm第二个安装开发工具包: Anacondaps:Windows 下 Pycharm下载/Anaconda安装详细步…

matlab非同秩矩阵相乘_线性代数精华——讲透矩阵的初等变换与矩阵的秩

这篇文章和大家聊聊矩阵的初等变换和矩阵的秩。矩阵的初等变换这个概念可能在很多人听来有些陌生&#xff0c;但其实我们早在初中的解多元方程组的时候就用过它。只不过在课本当中&#xff0c;这种方法叫做消元法。我们先来看一个课本里的例子&#xff1a;假设我们要解这个方程…

手持巡检仪_专业的三防产品设计-电力巡检仪设计

我个人认为所有科技的发展都是建立在人们的需求而产生的。让人们更加方便快捷舒适。在电力巡检的问题上&#xff0c;为了减少值班员抄表和记录因此设计出这款电力巡检仪设计。用于记录设备的运行、检修、备用状态,可查询当天的漏检项目情况&#xff0c;确保点检内容无遗漏&…

thinkphp v5.0.11漏洞_ThinkPHP5丨远程代码执行漏洞动态分析

ThinkPHP是为了简化企业级应用开发和敏捷WEB应用开发而诞生的&#xff0c;在保持出色的性能和至简代码的同时&#xff0c;也注重易用性。但是简洁易操作也会出现漏洞&#xff0c;之前ThinkPHP官方修复了一个严重的远程代码执行漏洞。这个漏洞的主要原因是由于框架对控制器名没有…

本地提交spark_Spark 数据本地化级别

​​RDD 源码大家可以看到源码中的第五条注释说明&#xff0c;翻译过来的大概意思是提供一系列的最佳计算位置。我之前一直不太清楚 spark 是如何内部实现的&#xff0c;今天就带领大家来看一看 spark 的本地数据化级别在任务执行中的演变过程。1 数据的本地化级别有哪些&#…

街舞中的rolling机器人_首家!爆点!奈雪の茶、蛙小侠..开业倒计时!街舞PK…这个六一就差你来围观了...

说起济南的各大shopping mall世茂广场绝对是最得人心的总能迅速集结当下最火爆的品牌各种线上线下活动也是搞得新颖又有趣五一的“刘看山”还没结束呢这就马不停蹄的要上新活动了前方预警⚠奈雪の茶等一大波新店又要入驻啦 还有 “奔跑吧爸爸”亲子活动、街舞大赛 ……统统都在…

简述isodata算法的原理_基于UWB技术的室内定位方法简述

1. UWB室内定位概述&#xff1a;UWB室内定位技术与传统通信技术有极大的差异&#xff0c;它不需要使用传统通信体制中的载波&#xff0c;而是通过发送和接收具有纳秒或纳秒级以下的极窄脉冲来传输数据&#xff0c;从而具有GHz量级的带宽。超宽带室内定位可用于各个领域的室内精…