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

Android平台下VR头显如何低延迟播放4K以上超高分辨率RTSP|RTMP流

技术背景

VR头显需要更高的分辨率以提供更清晰的视觉体验、满足沉浸感的要求、适应透镜放大效应以及适应更广泛的可视角度,超高分辨率的优势如下:

  1. 提供更清晰的视觉体验:VR头显的分辨率直接决定了用户所看到的图像的清晰度。更高的分辨率意味着更多的像素数,可以呈现更细腻、更逼真的图像,从而提升用户的视觉体验,更高的分辨率可以进一步减少图像中的颗粒感和纱窗效应,让用户感受到更加真实的虚拟世界。
  2. 满足沉浸感的要求:VR头显的主要目的是为用户提供沉浸式的体验,使用户感觉自己完全置身于虚拟环境中。为了达到这种效果,头显需要能够呈现足够清晰、细腻的图像,以便用户能够清晰地看到虚拟环境中的各种细节。更高的分辨率可以确保用户在头部移动或转动时,依然能够保持画面的清晰度和稳定性,从而增强沉浸感。
  3. 适应透镜放大效应:VR头显通过透镜将小屏幕放大至用户眼前,以模拟大屏幕的效果。然而,这种放大效应会导致图像的像素密度降低,使得图像看起来相对模糊。因此,为了保持放大后的图像依然清晰,VR头显需要更高的分辨率来弥补透镜放大带来的像素密度降低问题。
  4. 适应更广泛的可视角度:一些VR头显设计倾向于在画质可以接受的情况下,尽量增大可视角度,以便用户能够更自然地观察虚拟环境。然而,这也会导致图像在边缘区域出现拉伸和变形。为了保持这些区域依然清晰可辨,VR头显需要更高的分辨率来确保整个画面的清晰度和稳定性。

技术实现

实际上,大牛直播SDK在2018年就发布了Unity的RTSP|RTMP的播放模块,平台陆续覆盖了Windows、Android、iOS和Linux,Unity下播放RTSP|RTMP流,原理很简单,底层原生模块,把RTSP|RTMP流拉过来,做解析解码回调YUV或RGB数据到上层,Unity环境下,做绘制即可。说来容易,难点在于,如果需要更好的解码效率、资源占用和低延迟,需要确保每个环节都做到极致,总体延迟可以达到200-400ms。

目前我们实现的功能如下:

  •  [支持播放协议]高稳定、超低延迟(毫秒级延迟,行业内几无效果接近的播放端)、业内首屈一指的RTMP、RTSP直播播放SDK;
  •  [多实例播放]支持多实例播放;
  •  [事件回调]支持网络状态、buffer状态等回调;
  •  [视频格式]支持RTMP扩展H.265,H.264;
  •  [音频格式]支持AAC/PCMA/PCMU/Speex;
  •  [H.264/H.265软解码]支持H.264/H.265软解;
  •  [H.264硬解码]Android/iOS支持H.264特定机型硬解;
  •  [H.265硬解]Android/iOS支持H.265特定机型硬解;
  •  [RTSP模式设置]支持RTSP TCP/UDP模式设置;
  •  [RTSP TCP/UDP自动切换]支持RTSP TCP、UDP模式自动切换;
  •  [RTSP超时设置]支持RTSP超时时间设置,单位:秒;
  •  [RTSP 401认证处理]支持上报RTSP 401事件,如URL携带鉴权信息,会自动处理;
  •  [缓冲时间设置]支持buffer time设置;
  •  [首屏秒开]支持首屏秒开模式;
  •  [低延迟模式]支持超低延迟模式设置;
  •  [复杂网络处理]支持断网重连等各种网络环境自动适配;
  •  [快速切换URL]支持播放过程中,快速切换其他URL,内容切换更快;
  •  [实时静音]支持播放过程中,实时静音/取消静音;
  •  [实时快照]支持播放过程中截取当前播放画面;
  •  [渲染角度]支持0°,90°,180°和270°四个视频画面渲染角度设置;
  •  [渲染镜像]支持水平反转、垂直反转模式设置;
  •  [实时下载速度更新]支持当前下载速度实时回调(支持设置回调时间间隔);
  •  [音视频自适应]支持播放过程中,音视频信息改变后自适应播放;
  •  [扩展录像功能]完美支持和录像模块组合使用。

废话不多说,上代码,先说开始播放:

/** SmartPlayerAndroidMono.cs* Author: daniusdk.com* Created on 2018/05/10.*/
public void Play()
{if (is_running){Debug.Log("已经在播放。。");   return;}//获取输入框的urlstring url = input_url_.text.Trim();OpenPlayer();if ( player_handle_ == 0 )return;NT_U3D_Set_Game_Object(player_handle_, game_object_);/* ++ 播放前参数配置可加在此处 ++ */int is_using_tcp = 0;        //TCP/UDP模式设置NT_U3D_SetRTSPTcpMode(player_handle_, is_using_tcp);int is_report = 0;int report_interval = 1;NT_U3D_SetReportDownloadSpeed(player_handle_, is_report, report_interval);  //下载速度回调NT_U3D_SetBuffer(player_handle_, play_buffer_time_);                        //设置buffer timeNT_U3D_SetPlayerLowLatencyMode(player_handle_, is_low_latency_ ? 1 : 0);    //设置是否启用低延迟模式NT_U3D_SetMute(player_handle_, is_mute_ ? 1 : 0);                           //是否启动播放的时候静音NT_U3D_SetAudioVolume(player_handle_, cur_audio_volume_);                   //设置播放音量NT_U3D_SetVideoDecoderMode(player_handle_, is_hw_decode_ ? 1 : 0);          //设置H.264软硬解模式NT_U3D_SetVideoHevcDecoderMode(player_handle_, is_hw_decode_ ? 1 : 0);          //设置H.265软硬解模式int is_output = 1;int disable_use_image_planes = 0;bool is_supports_texture_format = SystemInfo.SupportsTextureFormat(TextureFormat.RG16);Debug.Log("is_supports_texture_format: " + is_supports_texture_format);int is_supported_multiple_format = is_supports_texture_format? 1:0;int max_images = 3;int buffer_pool_max_size = 0;NT_U3D_SetImageReaderOutput(player_handle_, is_output, disable_use_image_planes, is_supported_multiple_format, max_images, buffer_pool_max_size);  //硬解码image readerint is_fast_startup = 1;NT_U3D_SetFastStartup(player_handle_, is_fast_startup);                     //设置快速启动模式int rtsp_timeout = 10;NT_U3D_SetRTSPTimeout(player_handle_, rtsp_timeout);                        //设置RTSP超时时间int is_auto_switch_tcp_udp = 1;NT_U3D_SetRTSPAutoSwitchTcpUdp(player_handle_, is_auto_switch_tcp_udp);    //设置TCP/UDP模式自动切换int is_audiotrack = 1;NT_U3D_SetAudioOutputType(player_handle_, is_audiotrack);                   //设置音频输出模式: if 0: 自动选择; if with 1: audiotrack模式NT_U3D_SetUrl(player_handle_, videoUrl);/* -- 播放前参数配置可加在此处 -- */int flag = NT_U3D_StartPlay(player_handle_);if (flag  == DANIULIVE_RETURN_OK){is_need_get_frame_ = true;Debug.Log("播放成功");}else{is_need_get_frame_ = false;Debug.LogError("播放失败");}is_running = true;  
}

对应的OpenPlayer实现如下:

private void OpenPlayer()
{if ( java_obj_cur_activity_ == null ){Debug.LogError("getApplicationContext is null");return;}player_handle_ = NT_U3D_Open();if (player_handle_ != 0)Debug.Log("open success");elseDebug.LogError("open fail");
}

ClosePlayer实现如下:

private void ClosePlayer()
{is_need_get_frame_ = false;is_need_init_texture_ = false;int flag = NT_U3D_StopPlay(player_handle_);if (flag == DANIULIVE_RETURN_OK){Debug.Log("停止成功");}else{Debug.LogError("停止失败");}flag = NT_U3D_Close(player_handle_);if (flag == DANIULIVE_RETURN_OK){Debug.Log("关闭成功");}else{Debug.LogError("关闭失败");}player_handle_ = 0;NT_U3D_UnInit();is_running = false;video_format_ = VideoFrame.FORMAT_UNKNOWN;video_width_ = 0;video_height_ = 0;
}

总结

VR头显下播放超高分辨率的RTSP或RTMP,实现低延迟的播放,意义很大,比如平衡操控场景下,可以远程操控挖掘机等危险设备,提高工作效率、改善工作环境、降低安全风险、节约人力成本。在虚拟仿真、无人机操控等场景下也意义重大,感兴趣的开发者,可以单独跟我交流。

http://www.lryc.cn/news/380758.html

相关文章:

  • WHAT - NextJS 系列之 Rendering - Server Components
  • Web项目部署后浏览器刷新返回Nginx的404错误对应解决方案
  • 视频与音频的交响:探索达摩院VideoLLaMA 2的技术创新
  • 更改ip后还被封是ip质量的原因吗?
  • 【Oracle】调用HTTP接口
  • Minillama3->sft训练
  • 【教师资格证考试综合素质——法律专项】学生伤害事故处理办法以及未成人犯罪法笔记相关练习题
  • Vite: 关于静态资源的处理机制
  • React之useEffect
  • 测试辅助工具(抓包工具)的使用3 之 弱网测试
  • 【Redis】基于Redission实现分布式锁(代码实现)
  • websocket 安全通信
  • 代码生成技术技术-janino
  • QT事件处理系统之四:自定义事件的注册及拦截、发送
  • vs2022 studio控制台出现中文乱码解决
  • 支持向量机介绍
  • 电压互感器在线监测的原理
  • 算法训练与程序竞赛题目集合(L4)
  • Selenium进行Web自动化测试
  • 模拟算法讲解
  • Leetcode 3196. Maximize Total Cost of Alternating Subarrays
  • Elasticsearch**Elasticsearch自定义插件开发入门
  • 在Ubuntu中创建Ruby on Rails项目并搭建数据库
  • 微信小程序反编译 2024 unveilr.exe
  • 测试测量-DMM直流精度
  • AGV机器人的调度开发分析(2)- 内核中的调度
  • HTTP详细总结
  • 【Android】代码中将 SVG 图像转换颜色
  • 网络故障排查-TCP标志位
  • [Vue3+Vite+TS] Windows用户设置 VITE_CJS_TRACE=true 标志运行你的脚本来记录堆栈跟踪