wpf下如何实现超低延迟的RTMP或RTSP播放

技术背景

我们在做Windows平台RTMP和RTSP播放模块对接的时候,有开发者需要在wpf下调用,如果要在wpf下使用,只需要参考C#的对接demo即可,唯一不同的是,视频流数据显示的话,要么通过控件模式,要么可以让RTMP、RTSP播放模块回调rgb数据上来,在wpf直接绘制即可。

技术实现

本文以大牛直播SDK的Windows平台SmartPlayer为例,回调数据的模式,其他不再说明,只要处理好上来的数据就好:

播放之前,设置回调,选择NT_SP_E_VIDEO_FRAME_FORMAT_RGB32:

video_frame_call_back_ = new SP_SDKVideoFrameCallBack(SetVideoFrameCallBack);NTSmartPlayerSDK.NT_SP_SetVideoFrameCallBack(player_handle_, (Int32)NT.NTSmartPlayerDefine.NT_SP_E_VIDEO_FRAME_FORMAT.NT_SP_E_VIDEO_FRAME_FORMAT_RGB32, IntPtr.Zero, video_frame_call_back_);

处理rgb数据回调:

       /** nt_player_wrapper.cs* Author: daniusdk.com*/public void SetVideoFrameCallBack(IntPtr handle, IntPtr userData, UInt32 status, IntPtr frame){if (frame == IntPtr.Zero){return;}//如需直接处理RGB数据,请参考以下流程NT_SP_VideoFrame video_frame = (NT_SP_VideoFrame)Marshal.PtrToStructure(frame, typeof(NT_SP_VideoFrame));if (video_frame.format_ != (Int32)NT.NTSmartPlayerDefine.NT_SP_E_VIDEO_FRAME_FORMAT.NT_SP_E_VIDEO_FRAME_FORMAT_RGB32)return;NT_SP_VideoFrame pVideoFrame = new NT_SP_VideoFrame();pVideoFrame.format_ = video_frame.format_;pVideoFrame.width_ = video_frame.width_;pVideoFrame.height_ = video_frame.height_;pVideoFrame.timestamp_ = video_frame.timestamp_;pVideoFrame.stride0_ = video_frame.stride0_;pVideoFrame.stride1_ = video_frame.stride1_;pVideoFrame.stride2_ = video_frame.stride2_;pVideoFrame.stride3_ = video_frame.stride3_;Int32 argb_size = video_frame.stride0_ * video_frame.height_;pVideoFrame.plane0_ = Marshal.AllocHGlobal(argb_size);CopyMemory(pVideoFrame.plane0_, video_frame.plane0_, (UInt32)argb_size);}

另外一种,可以用picturebox,在MainWindow.xaml 做以下设置:

        <WindowsFormsHost HorizontalAlignment="Left" Height="338" Margin="10,10,0,0" VerticalAlignment="Top" Width="480" Background="Black"><wf:PictureBox x:Name="RealPlayWnd"></wf:PictureBox></WindowsFormsHost>

为了便于多实例集成参考,以播放2路为例(一路2560*1440,一路1920*1080):

具体实现如下:

       /** MainWindow.xaml.cs* Author: daniusdk.com*/public MainWindow(){InitializeComponent();if (!InitSDK())return;UIDispatcher = Dispatcher.CurrentDispatcher;player1_ = new nt_player_wrapper(RealPlayWnd, UIDispatcher);player1_.EventGetPlayerEventMsg += new DelGetPlayerEventMsg(GetPlayerEventMsgInfo);player1_.EventGetVideoSize += new DelGetVideoSize(GetVideoSize);player2_ = new nt_player_wrapper(RealPlayWnd1, UIDispatcher);player2_.EventGetPlayerEventMsg += new DelGetPlayerEventMsg(GetPlayerEventMsgInfo);player2_.EventGetVideoSize += new DelGetVideoSize(GetVideoSize);}private void GetPlayerEventMsgInfo(IntPtr handle, String msg){this.Dispatcher.Invoke((Action)delegate(){event_label.Content = msg;});}private void GetVideoSize(IntPtr handle, String size){this.Dispatcher.Invoke((Action)delegate(){video_size.Content = size;});}private bool InitSDK(){if (!is_player_sdk_init_){UInt32 isPlayerInited = NT.NTSmartPlayerSDK.NT_SP_Init(0, IntPtr.Zero);if (isPlayerInited != 0){MessageBox.Show("调用NT_SP_Init失败..");return false;}is_player_sdk_init_ = true;}return true;}private void Button_Click_1(object sender, RoutedEventArgs e){if (!player1_.IsPlaying()){player1_.SetBuffer(0);bool is_mute = true;if (!player1_.StartPlay("rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream", false, is_mute))return;btn_playback1.Content = "停止播放";}else{player1_.StopPlay();btn_playback1.Content = "开始播放";}}private void Button_Click_2(object sender, RoutedEventArgs e){if (!player2_.IsPlaying()){player2_.SetBuffer(0);bool is_mute = true;if (!player2_.StartPlay("rtsp://admin:admin123456@192.168.0.121:554/cam/realmonitor?channel=1&subtype=0", false, is_mute))return;btn_playback2.Content = "停止播放";}else{player2_.StopPlay();btn_playback2.Content = "开始播放";}}protected override void OnClosing(System.ComponentModel.CancelEventArgs e){if (MessageBox.Show("确定要关闭窗口吗?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes){// 如果用户选择“否”,取消关闭e.Cancel = true;}if (player1_.IsPlaying()){player1_.StopPlay();}player1_.Dispose();if (player2_.IsPlaying()){player2_.StopPlay();}player2_.Dispose();if (is_player_sdk_init_){NTSmartPlayerSDK.NT_SP_UnInit();is_player_sdk_init_ = false;}    base.OnClosing(e);}

延迟依旧毫秒级,CPU占用如下,如果用硬解码,体验会更好:

SmartPlayer以跨平台的RTSP播放器为例,我们实现的功能如下,如不单独说明,系Windows、Linux、Android、iOS全平台支持:

  • [支持播放协议]高稳定、超低延迟、业内首屈一指的RTSP直播播放器SDK;
  •  [多实例播放]支持多实例播放;
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [视频格式]支持H.265、H.264,此外,还支持RTSP MJPEG播放;
  •  [音频格式]支持AAC/PCMA/PCMU;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Windows/Android/iOS支持特定机型H.264硬解;
  •  [H.265硬解]Windows/Android/iOS支持特定机型H.265硬解;
  •  [H.264/H.265硬解码]Android支持设置Surface模式硬解和普通模式硬解码;
  •  [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  •  [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  •  [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  •  [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [音视频多种render机制]Android平台,视频:surfaceview/OpenGL ES,音频:AudioTrack/OpenSL ES;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时音量调节]支持播放过程中实时调节音量;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [只播关键帧]Windows平台支持实时设置是否只播放关键帧;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [等比例缩放]支持图像等比例缩放绘制(Android设置surface模式硬解模式不支持);
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [解码前视频数据回调]支持H.264/H.265数据回调;
  •  [解码后视频数据回调]支持解码后YUV/RGB数据回调;
  •  [解码前音频数据回调]支持AAC/PCMA/PCMU数据回调;
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应;
  •  [扩展录像功能]完美支持和录像模块组合使用。

总结

Windows平台下如果需要wpf播放,如果需要更灵活,可以采用回调rgb数据的模式,上层直接绘制,只是低延迟的播放出来画面,采用上述控件模式亦可,除了wpf外,我们提供了C++和C#的接口和demo,感兴趣的开发者,可以尝试看看,有问题可以单独跟我沟通。

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

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

相关文章

【黑马头条】-day09用户行为-精度丢失-点赞收藏关注

文章目录 1 long类型精度丢失问题1.1 解决1.2 导入jackson序列化工具1.3 自定义注解1.4 原理1.5 测试 2 用户行为要求3 创建微服务behavior3.1 微服务创建3.2 添加启动类3.3 创建bootstrap.yml3.4 在nacos中配置redis3.5 引入redis依赖3.6 更新minio 4 跳过 1 long类型精度丢失…

小红的白色字符串

题目描述 小红拿到了一个字符串&#xff0c;她准备将一些字母变成白色&#xff0c;变成白色的字母看上去就和空格一样&#xff0c;这样字符串就变成了一些单词。 现在小红希望&#xff0c;每个单词都满足以下两种情况中的一种&#xff1a; 1.开头第一个大写&#xff0c;其余为…

01、ArcGIS For JavaScript 4.29对3DTiles数据的支持

综述 Cesium从1.99版本开始支持I3S服务的加载&#xff0c;到目前位置&#xff0c;已经支持I3S的倾斜模型、3D Object模型以及属性查询的支持。Cesium1.115又对I3S标准的Building数据实现了加载支持。而ArcGIS之前一直没有跨越对3DTiles数据的支持&#xff0c;所以在一些开发过…

抖音滑块验证码加密的盐的位置

最近更新后之前很容易找到盐的位置的方法变了&#xff0c;抖音特意把盐隐藏起来了 {"reply": "RJC","models": "yAd8rl","in_modal": "DTn0nD2","in_slide": "ou7H0Ngda","move": …

Vue2(十五):replace属性、编程式路由导航、缓存路由组件、路由组件独有钩子、路由守卫、history与hash

一、router-link的replace属性 1、作用&#xff1a;控制路由跳转时操作浏览器历史记录的模式 2、浏览器的历史记录有两种写入方式&#xff1a;分别为push和replace&#xff0c;push是追加历史记录&#xff0c;replace是替换当前记录。路由跳转时候默认为push 3、如何开启repla…

环信 IM 客户端将适配鸿蒙 HarmonyOS

自华为推出了自主研发操作系统鸿蒙 HarmonyOS 后&#xff0c;国内许多应用软件开始陆续全面兼容和接入鸿蒙操作系统。环信 IM 客户端计划将全面适配统鸿蒙 HarmonyOS &#xff0c;助力开发者快速实现社交娱乐、语聊房、在线教育、智能硬件、社交电商、在线金融、线上医疗等广泛…

基于java+springboot+vue实现的网上购物系统(文末源码+Lw+ppt)23-42

摘 要 随着我国经济的高速发展与人们生活水平的日益提高&#xff0c;人们对生活质量的追求也多种多样。尤其在人们生活节奏不断加快的当下&#xff0c;人们更趋向于足不出户解决生活上的问题&#xff0c;网上购物系统展现了其蓬勃生命力和广阔的前景。与此同时&#xff0c;为…

我与C++的爱恋:类与对象(二)

​ ​ &#x1f525;个人主页&#xff1a;guoguoqiang. &#x1f525;专栏&#xff1a;我与C的爱恋 ​ 本篇着重介绍构造函数和析构函数&#xff0c;剩余内容在下篇解答。 一、类的默认成员函数 如果一个类中什么成员都没有&#xff0c;简称为空类。 任何类在什么都不写时…

GFS部署实验

目录 1、部署环境 ​编辑 2、更改节点名称 3、准备环境 4、磁盘分区&#xff0c;并挂载 5. 做主机映射--/etc/hosts/ 6. 复制脚本文件 7. 执行脚本完成分区 8. 安装客户端软件 1. 安装解压源包 2. 创建gfs 3. 安装 gfs 4. 开启服务 9、 添加节点到存储信任池中 1…

RUM 最佳实践-交互延迟的探索与发现

FID 在互联网高速发展的时代&#xff0c;用户体验已成为企业竞争的关键所在。网页性能作为用户体验的重要组成部分&#xff0c;直接影响着用户的满意度和工作效率。First Input Delay&#xff08;FID&#xff09;作为衡量网页性能的重要指标&#xff0c;越来越受到业界关注。今…

【Linux学习笔记】安卓运行C可执行文件No such file or directory

文章目录 开发环境运行失败现象解决办法方法一&#xff1a;使用静态库方法二&#xff1a;使用动态库创建lib查找依赖库复制需要注意的事情 开发环境 开发板&#xff1a;正点原子RK3568开发板安卓版本&#xff1a;11可执行程序命名&#xff1a;ledApp需加载模块&#xff1a;dts…

SpringBoot3 + uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作(最新)

SpringBoot3 uniapp 对接 阿里云0SS 实现上传图片视频到 0SS 以及 0SS 里删除图片视频的操作 最终效果图uniapp 的源码UpLoadFile.vuedeleteOssFile.jshttp.js SpringBoot3 的源码FileUploadController.javaAliOssUtil.java 最终效果图 uniapp 的源码 UpLoadFile.vue <tem…

云服务器环境web环境搭建之JDK、redis、mysql

一、Linux安装jdk&#xff0c;手动配置环境 链接: https://pan.baidu.com/s/1LRgRC5ih7B9fkc588uEQ1whttps://pan.baidu.com/s/1LRgRC5ih7B9fkc588uEQ1w 提取码: 0413 tar -xvf 压缩包名 修改配置文件/etc/profile 二、安装redis环境 方案一&#xff1a; Linux下安装配置r…

clickhouse深入浅出

基础知识原理 极致压缩率 极速查询性能 列式数据库管理 &#xff0c;读请求多 大批次更新或无更新 读很多但用很少 大量的列 列的值小数值/短字符串 一致性要求低 DBMS&#xff1a;动态创建/修改/删除库 表 视图&#xff0c;动态查/增/修/删&#xff0c;用户粒度设库…

数据治理专家岗位的能力模型

数据治理专家的角色要求其具备全方位的专业素养与技能&#xff0c;不仅要有深厚的业务理解与数据技术功底&#xff0c;还需展现出卓越的领导力、团队协作与沟通能力&#xff0c;以驱动组织内部数据治理工作的高效运行与持续优化。以下是对数据治理专家各项能力的深入解读&#…

mac 配置前端开发环境brew,git,nvm,nrm

我的电脑是mac 3 pro 一、配置Homebrew 打开终端&#xff0c;执行指令 /bin/zsh -c "$(curl -fsSL https://gitee.com/cunkai/HomebrewCN/raw/master/Homebrew.sh)"查看版本 brew -v 安装nvm brew install nvm 再执行 brew reinstall nvm 我这边安装好了…

JavaScript中的Blob、Buffer、ArrayBuffer和TypedArray详解

文章的更新路线&#xff1a;JavaScript基础知识-Vue2基础知识-Vue3基础知识-TypeScript基础知识-网络基础知识-浏览器基础知识-项目优化知识-项目实战经验-前端温习题&#xff08;HTML基础知识和CSS基础知识已经更新完毕&#xff09; 正文 摘要&#xff1a;本文详细介绍了JavaS…

kafka学习记录

文章目录 windows单机版kafka搭建步骤主题的增删改查操作消息的生产与消费 Windows集群版kafka搭建步骤 prettyZoo 尚硅谷Kafka教程&#xff0c;2024新版kafka视频&#xff0c;零基础入门到实战 【尚硅谷】Kafka3.x教程&#xff08;从入门到调优&#xff0c;深入全面&#xff0…

python使用uiautomator2操作雷电模拟器9并遇到解决adb 连接emulator-5554 unauthorized问题

之前写过一篇文章 python使用uiautomator2操作雷电模拟器_uiautomator2 雷电模拟器-CSDN博客 上面这篇文章用的是雷电模拟器4&#xff0c;雷电模拟器4.0.78&#xff0c;android版本7.1.2。 今天有空&#xff0c;再使用雷电模拟器9&#xff0c;android版本9来测试一下 uiauto…

谷歌不收录怎么办?

谷歌不收录首先你要确认自己网站有没有出问题&#xff0c;比如你的网站是否已经公开&#xff0c;rboot是否允许搜索引擎进来&#xff0c;网站架构有没有问题&#xff0c;面包屑的结构是否有问题&#xff0c;确保你的网站没问题 接下来就是优化这个过程&#xff0c;有内容&#…