笔记——android实现VR视频显示和优化

    xiaoxiao2021-03-25  125

    1.谷歌官网提供的VR资源下载 网站 https://github.com/googlevr/gvr-android-sdk/此网站是国外的网站,需要翻墙。 2.因为使用VR的资源很小号内存,所以我们为了避免OOM的问题,在清单文件中添加 android:largeHeap="true",提高警报线。 清单文件代码: <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:largeHeap="true" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> </activity> </application> 3..由于低版本要用高版本的东西,在Gradle文件中添加 compile 'com.google.android.exoplayer:exoplayer:r1.5.10' compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7' 4.导入三个库文件common,commonwidget,videowidget 目录为gvr-android-sdk-master\libraries下的三个文件 再添加到moudle中,Ctrl+Alt+Shift+S,选择你的moudle,点击右上角加号,导入需要的三个库文件; 5.编译构造版本太低,2.0后的studio没办法导入此model. 会爆出这个异常,解决的办法是进入文件里,修改build.gradle文件 6.在布局文件中添加VR控件和进度条控件: 代码: <com.google.vr.sdk.widgets.video.VrVideoView android:id="@+id/vr_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"/> 7.初始化VrPanoramaView控件 8.在src文件夹下的main文件夹下创建一个资产文件assets,存放VR动画; 9.由于VR资源数据量大,获取需要时间,故把加载图片放到子线程中进行,主线程来显示图片,可以使用一个异步线程AsyncTask或EventBus技术完成; 创建一个子线程,继承自AsyncTask<String,Void,Void>,并创建复写方法,将从本地文件中把资源和显示效果加载到内存中。 代码如下: private class vrLoadTask extends AsyncTask<String,Void,Void>{ @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<String, Void, Void> { //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; } } }
    转载请注明原文地址: https://ju.6miu.com/read-11327.html

    最新回复(0)