Google VR技术大揭秘

VR

虚拟现实(Virtual Reality)技术是一种可以创建和体验虚拟世界的计算机仿真系统,它利用计算机生成一种模拟环境,是一种多源信息融合的、交互式的三维动态视景和实体行为的系统仿真, 使用户沉浸到该环境中。

附:Wikipedia

VR产品

Google VR
Oculus
HTC Vivi

Google VR for Android

Google VR SDK同时支持DayDream和CardBoard。 包含了一些用于创建App的简单API和支持DayDream手机、DayDream控制器的复杂API。同时涵盖了Android、iOS、Unity三大平台。

SDK下载

sdk地址:

git clone https://github.com/googlevr/gvr-android-sdk.git

运行官网项目

在使用之前,我们先运行下官网的项目。导入gvr-android-sdk到Android Studio, 同步的过程中需要下载很多库所以会比较耗时,另外可能出现build失败的情况,这时可以尝试使用本地的gradle来编译。
gradle版本最好为最新版本。

项目展示了印加文明遗迹马丘比丘的全景图(Panorama):

在真机上运行时,会有一个Cardboard选项。点击上图红色框中的按钮即可进入Cardboard模式。

Demo代码的主要逻辑就是加载一张全景图放入VrPanoramaView中。

panoOptions = new Options();
panoOptions.inputType = Options.TYPE_STEREO_OVER_UNDER;//图像类型为立体图像
istr = assetManager.open("andes.jpg");//加载assets目录下的全景图
panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions);

全景图片andes是由两张图片组成,上面一张是给左眼看,下面一张是给右眼看。

Demo的声音的实现是加载assets目录下的congo.mp4视频到VrVideoView中。

videoWidgetView.loadVideoFromAsset("congo.mp4", options);

congo.mp4的视频内容也是分为上下部分,上面给左眼看,下面给右眼看。

treasurehunt

treasurehunt展示了一个简单到离谱的寻宝游戏,当vr世界中矩形变成金黄色时,点击手机屏幕或者使用Daydream的控制器,即可完成寻宝。游戏还伴有音效。

controllerclient

接收DayDream控制器输入示例

videoplayer

使用Asynchronous Reprojection播放视频示例

全景图(PanoramaActivity)

1. 配置build.gradle

//修改minSDK为19
minSdkVersion 19
//添加依赖
compile 'com.google.vr:sdk-panowidget:1.20.0'

2. 配置AndroidManifest.xml

由于全景图占内存较大,当加载多张全景图时可能存在内存溢出的情况,所以这里开启largeHeap。

<application android:largeHeap="true"></application>

3. 加载全景图

private class LoadPanoramaImageTask extends AsyncTask<Void, Void, Bitmap> {

    @Override
    protected Bitmap doInBackground(Void... params) {
        try {
            //加载assets目录下的全景图片
            AssetManager assetManager = getAssets();
            InputStream open = assetManager.open("andes.jpg");
            return BitmapFactory.decodeStream(open);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    protected void onPostExecute(Bitmap bitmap) {
        VrPanoramaView.Options options = new VrPanoramaView.Options();
        //图片类型为立体图像
        options.inputType = VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER;
        mVrPanoramaView.loadImageFromBitmap(bitmap, options);
    }
}

4. 生命周期管理

@Override
protected void onPause() {
    mVrPanoramaView.pauseRendering();
    super.onPause();
}

@Override
protected void onResume() {
    super.onResume();
    mVrPanoramaView.resumeRendering();
}

@Override
protected void onDestroy() {
    // Destroy the widget and free memory.
    mVrPanoramaView.shutdown();
    // The background task has a 5 second timeout so it can potentially stay alive for 5 seconds
    // after the activity is destroyed unless it is explicitly cancelled.
    if (mLoadPanoramaImageTask != null) {
        mLoadPanoramaImageTask.cancel(true);
    }
    super.onDestroy();
}

5. 事件监听

mVrPanoramaView.setEventListener(mVrPanoramaEventListener);

private VrPanoramaEventListener mVrPanoramaEventListener = new VrPanoramaEventListener() {
    /**
     * 点击回调
     */
    @Override
    public void onClick() {
        super.onClick();
    }

    /**
     * 加载数据成功回调
     */
    @Override
    public void onLoadSuccess() {
        super.onLoadSuccess();
    }

    /**
     * 加载数据失败回调
     */
    @Override
    public void onLoadError(String errorMessage) {
        super.onLoadError(errorMessage);
    }
};

360 视频

1. 配置build.gradle

//添加依赖//
minSdkVersion 19
//已经配置则忽略
compile 'com.google.vr:sdk-videowidget:1.20.0'

2. 配置AndroidManifest.xml (已经配置则忽略)

<application android:largeHeap="true"></application>

3. 加载视频

VrVideoView.Options options = new VrVideoView.Options();
//视频类型为立体视频
options.inputType = VrVideoView.Options.TYPE_STEREO_OVER_UNDER;
try {
    mVrVideoView.loadVideoFromAsset("congo.mp4", options);
} catch (IOException e) {
    e.printStackTrace();
}

4. 生命周期管理

@Override
protected void onPause() {
    super.onPause();
    // Prevent the view from rendering continuously when in the background.
    mVrVideoView.pauseRendering();
    // If the video is playing when onPause() is called, the default behavior will be to pause
    // the video and keep it paused when onResume() is called.
    isPaused = true;
}

@Override
protected void onResume() {
    super.onResume();
    mVrVideoView.resumeRendering();
}

@Override
protected void onDestroy() {
    // Destroy the widget and free memory.
    mVrVideoView.shutdown();
    super.onDestroy();
}

5. 事件监听

private VrVideoEventListener mVrEventListener = new VrVideoEventListener() {

    @Override
    public void onLoadError(String errorMessage) {
        Toast.makeText(VrVideoActivity.this, "onLoadError", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLoadSuccess() {
        Toast.makeText(VrVideoActivity.this, "onLoadSuccess", Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onNewFrame() {
    }

    @Override
    public void onCompletion() {
        Toast.makeText(VrVideoActivity.this, "onCompletion", Toast.LENGTH_SHORT).show();
        mVrVideoView.seekTo(0);//播放结束后重新开始播放
    }

    @Override
    public void onClick() {
        togglePause();//点击暂停或者播放
    }
};

Demo

本demo实现一个全景图控制显示的效果。这里主要演示下VrPanoramaView控件的使用。

初始化VrPanoramaView

private void initPanoramaView() {
    mVrPanoramaView = (VrPanoramaView) findViewById(R.id.vr_panorama_view);
    //mVrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_MONO);//全屏模式,弹出一个全屏的Dialog
    mVrPanoramaView.setInfoButtonEnabled(false);//隐藏信息按钮
    mVrPanoramaView.setStereoModeButtonEnabled(false);//隐藏cardboard按钮
    mVrPanoramaView.setFullscreenButtonEnabled(false);//隐藏全屏按钮
    mUrl = getIntent().getStringExtra("url");
    OkGo.get(mUrl).cacheKey(mUrl).tag(mUrl).execute(new BitmapCallback() {

        @Override
        public void onSuccess(Bitmap bitmap, Call call, Response response) {
            VrPanoramaView.Options options = new VrPanoramaView.Options();
            //设置图片类型为单通道图片
            options.inputType = VrPanoramaView.Options.TYPE_MONO;
            mVrPanoramaView.loadImageFromBitmap(bitmap, options);
        }
    });
}

初始化MediaPlayer

/**
 * 如果有音乐数据则播放音乐
 */
private void initMediaPlayer() {
    String mp3 = getIntent().getStringExtra("mp3");
    if (mp3 != null) {
        mMediaPlayer = new MediaPlayer();
        try {
            mMediaPlayer.setDataSource(this, Uri.parse(mp3));
            mMediaPlayer.setOnPreparedListener(mOnPreparedListener);
            mMediaPlayer.prepareAsync();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

生命周期管理

@Override
protected void onResume() {
    super.onResume();
    mVrPanoramaView.resumeRendering();
}

@Override
protected void onPause() {
    super.onPause();
    mVrPanoramaView.pauseRendering();
    if (mMediaPlayer != null) {
        mMediaPlayer.pause();
    }
}

@Override
protected void onDestroy() {
    super.onDestroy();
    mVrPanoramaView.shutdown();
    OkGo.getInstance().cancelTag(mUrl);//取消请求
    if (mMediaPlayer != null) {
        mMediaPlayer.release();
        mMediaPlayer = null;
    }
}

VR View

VR View允许开发者在网站或app中嵌入360度全景多媒体文件(图片和视频)。这个技术主要是提供给传统的开发者,可以通过在app中添加动态内容来提升用户体验。比如旅行或房地产类型的app,可以让用户足不出户就体验到虚拟场景。VR View同时支持web和Native app。
VR View同时支持单声道和立体声的图片和视频,但是图片和视频的存储格式必须为equirectangular-panoramic格式,这是一种常见的摄像头尺寸支持的格式。
VR view是客户端的显示技术,那么我们怎么去拍摄符合VR view要求的内容呢?

真实世界中的拍摄

Cardboard Camera App ,用这个app可以和方便的拍摄360照片,拍摄完成后需要通过conversion tool来创建一个立体声的360照片。

Ricoh Theta 一个非常流行的,相对廉价的用来拍摄单声道相片和视频的设备。

1,CG 拍摄
VR view的图片不仅仅限制在真实世界中拍摄。CGI(计算机合成图像)可以为所有的东西生成360度全景照片和视频,最流行拍摄解决方案如下:

360 Panorama Capture for Unity Unity插件
Unreal 虚幻引擎
Domemaster3D for Maya
Renderman 一个开源库
Rendering Omnidirectional Stereo Content

下面用伪代码展示如何用VrPanoramaView和VrVideoView展示360度图片和视频。

<com.google.vr.sdk.widgets.pano.VrPanoramaView
            android:id="@+id/pano_view"
            android:layout_margin="5dip"
            android:layout_width="match_parent"
            android:scrollbars="@null"
            android:layout_height="250dip"/>

<com.google.vr.sdk.widgets.video.VrVideoView
          android:id="@+id/video_view"
          android:layout_width="match_parent"
          android:scrollbars="@null"
          android:layout_height="250dip"/>
//展示全景图片
 panoWidgetView = (VrPanoramaView) findViewById(R.id.pano_view);
//图片加载结果回调
private class ActivityEventListener extends VrPanoramaEventListener {
    /**
     * Called by pano widget on the UI thread when it's done loading the image.
     */
    @Override
    public void onLoadSuccess() {
      loadImageSuccessful = true;
    }

    /**
     * Called by pano widget on the UI thread on any asynchronous error.
     */
    @Override
    public void onLoadError(String errorMessage) {
      loadImageSuccessful = false;
      Toast.makeText(
          SimpleVrPanoramaActivity.this, "Error loading pano: " + errorMessage, Toast.LENGTH_LONG)
          .show();
      Log.e(TAG, "Error loading pano: " + errorMessage);
    }
  }
//设置图片加载监听
    panoWidgetView.setEventListener(new ActivityEventListener());

//加载图像的Bitmap数据 istr是一个文件输入流
//VrPanoramaView.Options是用来配置图片格式的
// TYPE_MONO 包含单一圆柱的全景图像
// TYPE_STEREO_OVER_UNDER 图像包含了两个大小相等、垂直相交的圆柱全景图像。上图展示给左眼,下图展示给右眼。
panoWidgetView.loadImageFromBitmap(BitmapFactory.decodeStream(istr), panoOptions);

//展示全景视频
videoWidgetView = (VrVideoView) findViewById(R.id.video_view);
    videoWidgetView.setEventListener(new ActivityEventListener());
//VrVideoEventListener同时对视频加载和操作的回调
private class ActivityEventListener extends VrVideoEventListener  {
    /**
     * Called by video widget on the UI thread when it's done loading the video.
     */
    @Override
    public void onLoadSuccess() {
      Log.i(TAG, "Sucessfully loaded video " + videoWidgetView.getDuration());
      loadVideoStatus = LOAD_VIDEO_STATUS_SUCCESS;
      seekBar.setMax((int) videoWidgetView.getDuration());
      updateStatusText();
    }

    /**
     * Called by video widget on the UI thread on any asynchronous error.
     */
    @Override
    public void onLoadError(String errorMessage) {
      // An error here is normally due to being unable to decode the video format.
      loadVideoStatus = LOAD_VIDEO_STATUS_ERROR;
      Toast.makeText(
          SimpleVrVideoActivity.this, "Error loading video: " + errorMessage, Toast.LENGTH_LONG)
          .show();
      Log.e(TAG, "Error loading video: " + errorMessage);
    }

    @Override
    public void onClick() {
      togglePause();
    }

    /**
     * Update the UI every frame.
     */
    @Override
    public void onNewFrame() {
      updateStatusText();
      seekBar.setProgress((int) videoWidgetView.getCurrentPosition());
    }

    /**
     * Make the video play in a loop. This method could also be used to move to the next video in
     * a playlist.
     */
    @Override
    public void onCompletion() {
      videoWidgetView.seekTo(0);
    }
  }
//支持两种加载方式,从asset文件夹中或从一个uri中读取视频数据
//VrVideoView.Options同样是用来配置视频格式的
videoWidgetView.loadVideoFromAsset("congo.mp4", options);
或
videoWidgetView.loadVideo(fileInformation[0].first, fileInformation[0].second)

//除此外还有一些控制渲染、播放的方法:
videoWidgetView.pauseRendering();
videoWidgetView.resumeRendering();
videoWidgetView.shutdown();
videoWidgetView.playVideo();
videoWidgetView.pauseVideo();

//shutdown()一定要在onDestroy()时调用,用来释放占用内存。

附:VRDemo

时间: 2024-09-20 22:59:32

Google VR技术大揭秘的相关文章

【高德地图API】汇润做爱地图技术大揭秘

原文:[高德地图API]汇润做爱地图技术大揭秘 昨日收到了高德地图微信公众号的消息推送,说有[一大波免费情趣用品正在袭来],点进去看了一眼,说一个电商公司(估计是卖情趣用品的)用高德云图制作了一张可以标记做爱地点与详情的地图.这不就是中国版的I just made love麽? 滑到屏幕底下,看了看阅读量,哇塞,居然有4万3!!!说明实在是有很多人关注做爱地图啊.本着研究地图的心情(绝对不是为了什么价值300的智能情趣用品!),我也就点击了[阅读原文]-- 好吧,为了证明我真的不是为了奖品,我会

打开天窗说“亮话”,手淘这些年的技术大揭秘

中国云计算产业最具影响力的盛会之一--2016杭州云栖大会(https://yunqi.aliyun.com/)将在云栖小镇召开.连续举办七届的云栖大会一直是业界了解阿里云计算生态发展和应用趋势.体验前沿技术和产品的最佳平台,来自海内外的上万名开发者.创业者聚集于此,分享着他们对云计算的思考与实践经验.7年来,从产品发布到行业解决方案展示,从关注技术到技术与服务并重,从单一的客户到生态全景的展现,大会的核心内容一直在"进化",而2016年杭州云栖大会,则以"飞天・进化&quo

漆远:蚂蚁金服 AI 技术大揭秘, 开放“模型服务平台”

在本次大会上,蚂蚁金服副总裁兼首席数据科学家漆远博士发表了主题为<金融智能的发展与应用>的演讲.漆远表示,蚂蚁金服今年的两个关键词,一个是"开放",一个是"AI". 在此次演讲中,漆远从风控系统.智能助理.定损宝等产品案例出发,全面介绍了蚂蚁金服产品背后的 AI 技术. 现场,蚂蚁金服的"模型服务平台"首次公开亮相,主打"模型所见即所得".漆远表示,数据是资产,模型本身也是资产.未来,蚂蚁金服也会将这个平台作为其中

视频内容谁来保护?阿里云视频加密技术大揭秘,打造云上视频安全体系

视频行业的从业者--尤其是在线教育.财经分析等重视内容版权的播放平台都知道,视频安全是一个非常重要的基础需求.用户通过一次付费行为,就可以拿到付费视频的播放URL,将播放URL进行二次分发,这种行为叫做盗链:用户直接将视频下载到本地,然后再进行二次上传分发,这种行为叫做盗播,这两种行为都会给内容版权方造成十分严重的经济损失,面对日渐增多的盗链和盗播情况,我们应该怎么样去保护内容呢? 阿里云最新推出的 视频加密解决方案 对视频版权的保护可以从视频处理的各个环节来分别实现.阿里云通过转码.播放.分发

阿里云年会人机大战-技术大揭秘

引言 在上一篇文章中人工智能PK金牌速记员之实战录,我们讲述了阿里云年会人机大战背后的故事.技术Geek们可能就好奇了?现场的实时转录系统是怎么回事? 其中核心的语音识别系统到底是什么,工作原理是什么? 阿里云iDST的语音识别系统准确率为什么可以做到这么高,有什么独得之秘?本文将会将这些问题的答案一一揭晓. 人机大战之现场   阿里云年会现场,图中左边屏幕显示的是语音识别,右边屏幕显示的是人工速记 上图是视频的截图,展示的就是阿里云年会人机大战的现场情形, 阿里云的掌门人孙权在台上演讲,自动语

Li-Fi无线技术大揭秘 有光就能上网!

Li-Fi(Light Fidelity)是一种新型无线网络连接技术,由Harold Hass于2011年发明.其中,"L"代表Light,便是光线,所以该技术是基于LED灯而实现无线数据传播.在MWC 2016世界移动通信大会上,Harold Hass创建的PureLi-Fi公司带来了实际产品的演示,让人们可以近距离体验Li-Fi的先进理念,下面一起来了解一下. 基于光线的无线信号 PureLi-Fi公司在展会现场带来了一款Li-Fi兼容的USB适配器,可以看到,相比WIFI外置网卡

云计算、人工智能等关键技术大揭秘

"云计算"――这个概念是指,你可以根据需要来租用应用程序,然后通过互联网来访问它们,而不是购买应用程序,然后将应用程序安装到计算机上.就是这样,这就是"云计算".你可能已听说过"软件即服务"这个术语(简称"SaaS").这实际上就是一回事.它是指通过订阅服务来获取的一种集中托管的软件.对投资者来说,这个领域已上了轨道,像客户关系管理(CRM)SaaS提供商Salesforce.com这些公司的10年回报率超过了780%.不过对

邮件群发推广技术大揭秘

中介交易 http://www.aliyun.com/zixun/aggregation/6858.html">SEO诊断 淘宝客 云主机 技术大厅 相信很多站长都是懒的,相信很多站长都用过邮件群发来推广过网站,也相信大部分站长都认为邮件群发如果真的发出去且进了收件箱效果是很明显的.那么邮件怎么发出去?怎么进收件箱?收邮件的服务器如何判断你的是垃圾邮件?本人根据自己一个多月研究邮件群发的经验来谈谈这个问题. 先来说一下邮件发送的两种方式.一种是DNS特快专递,一种是通过SMTP服务器,也可

Google副总裁泄玄机:Google搜索技术揭秘

Google副总裁泄玄机:Google搜索技术揭秘- -                      Google将其成功部分地归功于公司所发明的独有运算机制,令其搜索引擎可以在极短时间内对数以百万计的网络用户的搜索请求提供答案. 上周三,Google副总裁Urs Hoelzle在Eclipse会议上的一番发言,令与会者有机会了解Google的搜索技术是如何产生以及该技术现在是如何运作的. Hoelzle对与会者说,要发明Google的技术,开发者必须抛弃过去大型数据库所使用技术的思维定势.由于一