android:id="@+id/seek_bar"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
7.初始化VrPanoramaView控件
8.在src文件夹下的main文件夹下创建一个资产文件assets,存放VR动画;
9.由于VR资源数据量大,获取需要时间,故把加载图片放到子线程中进行,主线程来显示图片,可以使用一个异步线程AsyncTask或EventBus技术完成;
创建一个子线程,继承自AsyncTask,并创建复写方法,将从本地文件中把资源和显示效果加载到内存中。
代码如下:
private class vrLoadTask extends AsyncTask{
@Override
protected Void doInBackground(String... params) {
//创建 VrVideoView.Options,决定显示的效果
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 {
//提示:视频加载的方法还做了把视频读取到内存中的操作,所以它会有一个矛盾,调用该方法是在主线程还是在子线程(一般我们放在子线程去调用该方法);
//使用VR对象,从资产目录加载视频数据,显示效果,参数1:params对象,2.VrVideoView.Options对象,决定显示的效果。
mVr_video.loadVideoFromAsset(params[0],options);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
10.在OnCreat方法中使用自定义的AsyncTask,播放VR效果
11.优化VR,因为VR很占用内存,所以当界面进入onPause状态,暂停VR视图显示,进入onResume状态,继续VR视图显示,进入onDestroy状态,杀死VR,关闭异步任务。当销毁Activity时判断ImagerLoaderTask是否为空,让不为空的时候再判断activity异步任务是否取消。
创建onPause,onResume和onDestroy等方法;(回调:当触动某个方法是自动调用;)
//因为VR很占用内存,所以当界面进入onPanuse状态,暂停VR视图显示,进入OnResume状态,继续VR视图显示,进入OnDestroy状态,杀死VR视图
//当我们失去焦点,回调
@Override
protected void onPause() {
//暂停渲染和显示
mVr_video.pauseRendering();
super.onPause();
}
//当我们获取焦点,回调
@Override
protected void onResume() {
//继续渲染和显示
mVr_video.resumeRendering();
super.onResume();
}
//当我们销毁焦点,回调
@Override
protected void onDestroy() {
//关闭渲染和显示
mVr_video.shutdown();
if(mVrLoadTask!=null){
if(!mVrLoadTask.isCancelled()){
mVrLoadTask.cancel(true);
}
}
super.onDestroy();
}
12.VR的优化,实现隐藏左下角的信息按钮,和对视频添加播放,暂停和进度条。
(1)//隐藏VR效果左下角信息按钮显示
vrVideoView.setInfoButtonEnabled(false);
(2) //切换VR模式 参数:VrVideoView.DisplayMode.FULLSCREEN_STEREO设备模式(手机横放) VrVideoView.DisplayMode.FULLSCREEN_MONO手机模式
vrVideoView.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);
(3)//对VR视频进行事件监听
vrVideoView.setEventListener(new MyEventListener());
(4)对VR运行状态监听类,自定义一个类继承VrVideoEventListener,复写里面需要的方法
①//当VR视频加载成功的时候回调
@Override
public void onLoadSuccess() {
super.onLoadSuccess();
//获取视频长度;
long max = vrVideoView.getDuration();
//设置seekbar的进度最大值
seek_bar.setMax((int) max);
}
②
//当VR视频加载失败的时候回调
@Override
public void onLoadError(String errorMessage) {
super.onLoadError(errorMessage);
Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
}
③
//当视频开始播放,每次进入下一帧的时候,回调这个方法
@Override
public void onNewFrame() {
super.onNewFrame();
//获取当前视频的播放时间位置
int currentPosition = (int) vrVideoView.getCurrentPosition();
//设置seekbar的进度条
seek_bar.setProgress(currentPosition);
//显示播放的进度数字
tv_text.setText("播放进度:" + String.format("%.2f", currentPosition / 1000.f) +"/"+ String.format("%.2f", vrVideoView.getDuration() / 1000f));
}
④
//当视频播放结束后的回调
@Override
public void onCompletion() {
super.onCompletion();
//让视频回到0点
vrVideoView.seekTo(0);
//让视频停止播放
vrVideoView.pauseVideo();
//让进度条也设置到0点
seek_bar.setProgress(0);
//播放完成后,重新设置标签,标签为true,暂停播放
isPaused = true;
}
⑤
//设置一个视频播放状态的标签
private boolean isPaused = false;
⑥
//重写点击视图的方法,使视频被点击时,播放或暂停
@Override
public void onClick() {
super.onClick();
//根据标签,判断当前视频的状态,标签false,播放则暂停,标签true,暂停则播放
if (isPaused) {
vrVideoView.playVideo();
} else {
vrVideoView.pauseVideo();
}
//对标签操作一次后要进行取反。
isPaused = !isPaused;
}
MainActivity代码:
public class MainActivity extends AppCompatActivity {
private VrVideoView vrVideoView;
private SeekBar seek_bar;
private TextView tv_text;
private VideoLoadTask mVideoLoadTask;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//A.进行控件初始化
vrVideoView = (VrVideoView) findViewById(R.id.vr_video);
seek_bar = (SeekBar) findViewById(R.id.seek_bar);
tv_text = (TextView) findViewById(R.id.tv_text);
//B.播放VR的效果,只需要执行异步任务。
mVideoLoadTask = new VideoLoadTask();
mVideoLoadTask.execute("congo_2048.mp4");
//D. VR的优化,实现隐藏左下角的信息按钮,和对视频添加播放,暂停和进度条。
//隐藏VR效果左下角信息按钮显示
vrVideoView.setInfoButtonEnabled(false);
//切换VR模式 参数:VrVideoView.DisplayMode.FULLSCREEN_STEREO设备模式(手机横放) VrVideoView.DisplayMode.FULLSCREEN_MONO手机模式
vrVideoView.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);
//对VR视频进行事件监听
vrVideoView.setEventListener(new MyEventListener());
}
//B.由于VR资源数据量大,获取需要时间,故把加载视频放到子线程中进行,主线程显示,可以使用异步任务AsyncTask或EventBus技术完成。
//自定义一个类继承自AsyncTask,只使用我们需要的方法,完成在子线程加载图片的资源,在主线程完成。
private class VideoLoadTask extends AsyncTask {
//B.该方法在子线程中进行,从本地文件中把资源加载到内存中。
@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 {
//提示:视频加载的方法还做了把视频读取到内存中的操作,所以会产生一个矛盾,调用该方法是在主线程还是在子线程(一般我们放在子线程去调用该方法)
//使用VR控件对象从资产目录加载视频数据,显示效果, 参数:1.String对象 2.VrVideoView.options对象,决定显示的效果
vrVideoView.loadVideoFromAsset(params[0], options);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
//C.因为VR很占用内存,所以当界面进入onPause状态,暂停VR视图显示,进入onResume状态,继续VR视图显示,进入onDestory状态,杀死VR,关闭异步状态。
//当我们失去焦点回调
@Override
protected void onPause() {
super.onPause();
//暂停渲染和显示
vrVideoView.pauseRendering();
}
//当获取焦点时回调
@Override
protected void onResume() {
super.onResume();
//继续渲染和显示
vrVideoView.resumeRendering();
}
//当销毁焦点时回调
@Override
protected void onDestroy() {
super.onDestroy();
//关闭渲染和显示
vrVideoView.shutdown();
//在退出Activity时,如果异步任务没有取消,则取消
if (mVideoLoadTask != null) {
if (!mVideoLoadTask.isCancelled()) {
mVideoLoadTask.cancel(true);
}
}
}
//D.对VR运行状态监听类,自定义一个类继承VrVideoEventListener,复写里面需要的方法
private class MyEventListener extends VrVideoEventListener {
//当VR视频加载成功的时候回调
@Override
public void onLoadSuccess() {
super.onLoadSuccess();
//获取视频长度;
long max = vrVideoView.getDuration();
//设置seekbar的进度最大值
seek_bar.setMax((int) max);
}
//当VR视频加载失败的时候回调
@Override
public void onLoadError(String errorMessage) {
super.onLoadError(errorMessage);
Toast.makeText(MainActivity.this, "加载失败", Toast.LENGTH_SHORT).show();
}
//当视频开始播放,每次进入下一帧的时候,回调这个方法
@Override
public void onNewFrame() {
super.onNewFrame();
//获取当前视频的播放时间位置
int currentPosition = (int) vrVideoView.getCurrentPosition();
//设置seekbar的进度条
seek_bar.setProgress(currentPosition);
//显示播放的进度数字
tv_text.setText("播放进度:" + String.format("%.2f", currentPosition / 1000.f) +"/"+ String.format("%.2f", vrVideoView.getDuration() / 1000f));
}
//当视频播放结束后的回调
@Override
public void onCompletion() {
super.onCompletion();
//让视频回到0点
vrVideoView.seekTo(0);
//让视频停止播放
vrVideoView.pauseVideo();
//让进度条也设置到0点
seek_bar.setProgress(0);
//播放完成后,重新设置标签,标签为true,暂停播放
isPaused = true;
}
//设置一个视频播放状态的标签
private boolean isPaused = false;
//重写点击视图的方法,使视频被点击时,播放或暂停
@Override
public void onClick() {
super.onClick();
//根据标签,判断当前视频的状态,标签false,播放则暂停,标签true,暂停则播放
if (isPaused) {
vrVideoView.playVideo();
} else {
vrVideoView.pauseVideo();
}
//对标签操作一次后要进行取反。
isPaused = !isPaused;
}
}
}