72人参与 • 2024-08-01 • VR/AR虚拟现实
我们在做unity平台rtsp、rtmp播放器的时候,有公司提出来这样的技术需求,希望在头显播放全景的8k rtsp|rtmp直播流,8k的数据,对头显和播放器,都提出了新的要求,我们从几个方面,探讨下vr头显设备如何播放8k的rtsp|rtmp流数据:
本文以大牛直播sdk的android平台unity3d rtsp|rtmp播放模块为例:
开始播放:
/*
* smartplayerandroidmono.cs
* author: daniusdk.com
* qq:89030985
*/
public void play()
{
if (is_running)
{
debug.log("已经在播放。。");
return;
}
//获取输入框的url
string url = input_url_.text.trim();
if (!url.startswith("rtmp://") && !url.startswith("rtsp://"))
{
videourl = "rtsp://admin:daniulive12345@192.168.0.120:554/h264/ch1/main/av_stream";
}
else
{
videourl = url;
}
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 time
nt_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 reader
int 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");
else
debug.logerror("open fail");
}
关闭player:
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;
}
update刷新数据:
private void update()
{
if (!is_need_get_frame_)
return;
if (player_handle_ == 0)
return;
androidjavaobject u3d_video_frame_obj = nt_u3d_getvideoframe(player_handle_);
if (u3d_video_frame_obj == null)
{
return;
}
videoframe converted_video_frame = converttovideoframe(u3d_video_frame_obj);
if (converted_video_frame == null)
{
u3d_video_frame_obj.call("release");
u3d_video_frame_obj = null;
return;
}
if (!is_need_init_texture_)
{
if (converted_video_frame.format_ != video_format_)
{
is_need_init_texture_ = true;
}
else if (converted_video_frame.width_ != video_width_
|| converted_video_frame.height_ != video_height_
|| converted_video_frame.stride0_ != y_row_bytes_
|| converted_video_frame.stride1_ != u_row_bytes_
|| converted_video_frame.stride2_ != v_row_bytes_)
{
is_need_init_texture_ = true;
}
}
if (is_need_init_texture_)
{
if (inityuvtexture(converted_video_frame))
{
is_need_init_texture_ = false;
}
}
updateyuvtexture(converted_video_frame);
converted_video_frame.java_frame_obj_ = null;
converted_video_frame = null;
u3d_video_frame_obj.call("release");
u3d_video_frame_obj = null;
}
vr头显如果需要播放8k的rtsp或rtsp流,对硬件和网络的要求非常高,因此在实际应用中可能会遇到一些挑战。通过实际测试,在quest3头显,配合我们的rtsp|rtmp播放器,在unity下,可以实现毫秒级延迟的8k视频数据播放,以满足平衡操控等对实时性要求非常高的使用场景,感兴趣的开发者,可以单独跟我探讨。
您想发表意见!!点此发布评论
版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。
发表评论