笔记——android实现VR视频显示和优化
2017-03-09 14:26
525 查看
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.onP
e785
ause();
}
//当我们获取焦点,回调
@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代码:
网站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.onP
e785
ause();
}
//当我们获取焦点,回调
@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; } } }
相关文章推荐
- Android应用中使用ListView实现数据列表显示(传智播客视频笔记)
- Android应用中使用ListView实现数据列表显示(传智播客视频笔记)
- Android应用中使用GridView实现数据网格显示(传智播客视频笔记)
- Android 学习笔记之SurfaceView的使用+如何实现视频播放...
- 安卓学习笔记---Android实现页面悬浮显示
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 基于avd7181c解决视频输入效果差的问题<四>---android显示相关实现调试手记
- Android个人学习笔记之ListView知识应用-仿IOS百度云条目点击显示菜单模块实现
- [置顶] Android开发实战使用(VR技术实现360°全景视频播放功能)
- 通过Android实现VR视频的播放
- Android视频播放项目总结之 适配器绑定视频信息列表显示到界面(适配器简单优化)
- android WebView实现播放网络视频以及全屏显示
- Androidx学习笔记(35)---新闻客户端之ListView显示新闻内容&ViewHolder优化
- 视频学习笔记:Android ffmpeg解码多路h264视频并显示
- 【凯子哥带你做高仿】“煎蛋”Android版的高仿及优化(二)——大图显示模式、评论“盖楼”效果实现详解
- android 笔记11 得到布局,状态栏显示隐藏,代码优化
- Android笔记(六):RecyclerView实现上/下滑隐藏/显示顶部搜索栏(item可点击)
- Android VR Player(全景视频播放器) [7]:视频列表的实现-网络视频
- 【Android开发VR实战】二.播放360°全景视频(自用笔记)
- android开发笔记之ListView的优化+分类显示