使用VR组件时,项目需要最低SDK版本为19。


在main下新建文件夹为assets,用于存放资源文件

android用什么开发vr 安卓vr开发_android



一、配置VR开发环境步骤:

1.使用VR是非常消耗内存的,所以为了避免OOM的问题,需在清单文件中application下添加的属性(把警报权限提高,从192提高到512MB)。(Heap:堆)


android:largeHeap="true"


android用什么开发vr 安卓vr开发_VR视频_02


2.在build.gradle里添加最新的依赖文件,下面的三个是后面


依赖module产生的。


gradle文件参照sample下的demo来修改


android用什么开发vr 安卓vr开发_VR视频_03




具体配置环境类似上一篇文章




具体实现代码如下:


MainActivity.java


package com.zhiyuan3g.vrvideo;

import android.os.AsyncTask;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.vr.sdk.widgets.video.VrVideoEventListener;
import com.google.vr.sdk.widgets.video.VrVideoView;

import java.io.IOException;

public class MainActivity extends AppCompatActivity {

    private VrVideoView mVideoView;
    private SeekBar mSeekBar;
    private TextView mTv_show;
    private VideoLoadTask mVideoLoadTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mVideoView = (VrVideoView) findViewById(R.id.video);
        mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
        mTv_show = (TextView) findViewById(R.id.tv_show);

        //隐藏VR效果左下角信息显示按钮
        mVideoView.setInfoButtonEnabled(false);
        //切换VR的模式,  参数:FULLSCREEN_STEREO 设备模式(横屏立体)
        mVideoView.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);
        //对VR视频进行事件监听
        mVideoView.setEventListener(new MyEventListener());

        //播放VR效果,只需要执行异步任务即可
        mVideoLoadTask = new VideoLoadTask();
        mVideoLoadTask.execute("congo_2048.mp4");

    }

    //由于VR资源数据量很大,获取需要时间,故加载视频放在子线程中执行,主线程来显示,可以使用异步任务AsyncTask或
    //EventBus技术完成(AsyncTask是开启子线程来实现的)
    //自定义一个类继承AsyncTask,只使用我们需要的方法,完成子线程加载资源,主线程显示
    private class VideoLoadTask extends AsyncTask<String,Void,Void> {

        //该方法在子线程运行,从本地文件中把资源加载到内存中
        @Override
        protected Void doInBackground(String... params) {
            //创建VrVideoView对应的options对象,决定VR是普通的效果,还是立体的效果
            VrVideoView.Options options = new VrVideoView.Options();
            //设置为立体效果
            options.inputType = VrVideoView.Options.TYPE_STEREO_OVER_UNDER;
            //设置加载视频的格式
            //FORMAT_DEFAULT:默认模式(SD或assets)
            //FORMAT_HLS:流媒体数据格式(直播)
            options.inputFormat=VrVideoView.Options.FORMAT_DEFAULT;
            try {
                //重点提示:视频加载的方法不仅做了把视频读取到内存中的操作(耗时操作),还做了更新UI的操作,所以它会有一个矛盾,
                // 调用该方法是在主线程还是在子线程(一般我们放在子线程去调用该方法)
                //使用VR控件对象,从资产目录加载视频数据,显示效果,参数:1.String对象(就是我们的资源文件)
                // 2.VrVideoView.Options对象,决定显示的效果
                //此处报错是因为loadVideoFromAsset方法不仅做了耗时操作,也做了更新UI,而其又在AsyncTask中
                //即子线程中,是不推荐更新UI的,所以系统会报错,不过这个错可以忽略。
                mVideoView.loadVideoFromAsset(params[0],options);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

    }


    //因为VR很占用内存,所以当界面进入OnPause状态,暂停VR视图显示,进入onResume状态,继续VR视图显示
    //进入onDestroy状态,杀死VR


    //当失去焦点时,回调

    @Override
    protected void onPause() {
        super.onPause();
        //暂停渲染显示
        mVideoView.pauseRendering();
    }

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

    }

    //
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //关闭渲染视图
        mVideoView.shutdown();
        //在退出Activity时,如果异步任务没有取消,则取消
        if (mVideoLoadTask != null) {
            if (!mVideoLoadTask.isCancelled()) {
                mVideoLoadTask.cancel(true);
            }
        }
    }


    //对VR运行0状态监听类,自定义一个类继承VrVideoEventListener,复习需要的方法
    private class MyEventListener extends VrVideoEventListener {

        //当VR视频加载成功时回调
        @Override
        public void onLoadSuccess() {
            super.onLoadSuccess();
            //获取视频长度
            long max = mVideoView.getDuration();
            //设置seekBar的进度最大值
            mSeekBar.setMax((int) max);

        }

        //当VR视频加载失败时回调
        @Override
        public void onLoadError(String errorMessage) {
            super.onLoadError(errorMessage);
             Toast.makeText(getApplicationContext(), "播放失败", Toast.LENGTH_SHORT).show();
        }

        //当视频开始播放,每次进入下一帧的时候,回调这个方法(就是播放时,会不停的回调该方法)
        @Override
        public void onNewFrame() {
            super.onNewFrame();
            //获取当前视频的播放时间位置
            int currentPosition = (int) mVideoView.getCurrentPosition();
            //设置seekbar的进度条
            mSeekBar.setProgress(currentPosition);
            //显示播放的进度数字
            mTv_show.setText("播放进度:"+String.format("",currentPosition/1000.f)+String.format("%.2f",mVideoView.getDuration()/1000f));
        }

        //当视频播放结束后的回调
        @Override
        public void onCompletion() {
            super.onCompletion();
            //让视频播放结束后,视频回到零点
            mVideoView.seekTo(0);

            //视频停止
            mVideoView.pauseVideo();
            //设置进度条也设置零点
            mSeekBar.setProgress(0);

            //播放完成后,重新设置标签,标签为true, 
            isPaused=true;
        }

        //设置一个视频暂停的标签,true代表暂停,false代表播放·
        private boolean isPaused=false;


        //重写点击视图的方法,是视频被点击时,播放或者暂停
        @Override
        public void onClick() {
            super.onClick();
             Toast.makeText(getApplicationContext(), "点击", Toast.LENGTH_SHORT).show();
            //根据标签判读当前视频的状态,标签false,是播放状态,点击则暂停;标签true,是暂停状态,点击则播放
            if (isPaused) {
                mVideoView.playVideo();
            } else {
                mVideoView.pauseVideo();
            }
            //对标签操作一次后,进去取反
            isPaused =!isPaused;
        }
    }
}


activity_main.xml


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <com.google.vr.sdk.widgets.video.VrVideoView
        android:id="@+id/video"
        android:layout_width="match_parent"
        android:layout_height="250dp"></com.google.vr.sdk.widgets.video.VrVideoView>

    <android.support.v7.widget.AppCompatSeekBar
        android:id="@+id/seek_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"/>

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</LinearLayout>



效果图:(手机没有陀螺仪,是无法显示旋转显示)



android用什么开发vr 安卓vr开发_VR视频_04




完整Demo代码下载:http://pan.baidu.com/s/1qYNMsIo