您的位置:首页 > 移动开发 > Android开发

笔记——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代码:
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;
}
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
相关文章推荐