使用VR组件时,项目需要最低SDK版本为19。
在main下新建文件夹为assets,用于存放资源文件
一、配置VR开发环境步骤:
1.使用VR是非常消耗内存的,所以为了避免OOM的问题,需在清单文件中application下添加的属性(把警报权限提高,从192提高到512MB)。(Heap:堆)
android:largeHeap="true"
2.在build.gradle里添加最新的依赖文件,下面的三个是后面
依赖module产生的。
gradle文件参照sample下的demo来修改
具体配置环境类似上一篇文章
具体实现代码如下:
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>
效果图:(手机没有陀螺仪,是无法显示旋转显示)
完整Demo代码下载:http://pan.baidu.com/s/1qYNMsIo