Google VR全景圖片與視頻功能開發(fā)詳解

1. VR開發(fā)概述

時下關(guān)于“谷歌袁串、Android與VR”的各種言論紛飛刨沦。VR群里有人在爭論Android VR是不是一體機鸠真,是不是類似Android Wear悯仙、為VR打造的全新平臺,是不是改良后的Android N吠卷。

隨著vr設(shè)備的流行開來锡垄,各大招聘平臺上也發(fā)布了不少關(guān)于andorid vr開發(fā)相關(guān)的Android工程師崗位,從這點來說掌握vr在項目中的實際應(yīng)用要點祭隔,有助于大家為自己的開發(fā)經(jīng)驗上增加前沿技術(shù)的積累货岭。

經(jīng)過研發(fā)市面上的主流vr app 的功能,抽取并整合項目中的vr開發(fā)知識點疾渴,希望大家掌握后千贯,在企業(yè)相關(guān)vr app游刃有余。

1.1 下載google vr sdk 并搭建開發(fā)環(huán)境

  • 帶大家去github上搜索并下載google vr sdk
  • 介紹sdk的組成部分與應(yīng)用范圍
  • 搭建一個基本android vr app的開發(fā)環(huán)境

1.2 CardBorad應(yīng)用核心功能

  • 帶大家查找本地vr 全景圖片資源
  • 介紹vr全景圖與普通圖片的不同點
  • 使用rv列表進行展示
  • 使用VrPanoramaView控件進行本地全景圖片的展示

1.3 UtoVR應(yīng)用核心功能

  • 帶大家通過網(wǎng)絡(luò)請求獲取vr視頻的json數(shù)據(jù)
  • 使用 Gson解析得到j(luò)avaBean數(shù)據(jù)
  • 使用VrVideoView控件進行網(wǎng)絡(luò)全景視圖的展示

以上這些功能是現(xiàn)流行的在線vr視頻搞坝,vr圖片相關(guān)app的核心功能搔谴。例如.vr管家應(yīng)用,3d播播桩撮,discovery VR 敦第,看房 vr等等熱門應(yīng)用峰弹。

1.4 知識點

  • http網(wǎng)絡(luò)請求技術(shù)
  • Gson解析技術(shù)與gsonformat插件
  • RecyclerView與cardView
  • Glider流行圖片加載框架
  • VrPanoramaView
  • VrVideoView

1.5 好玩好用的VR

成本其實很便宜!教你用手機體驗VR魅力

  • 17塊錢芜果!把手機改造為VR眼鏡
  • 好玩好用的VR APP推薦

2. 全景圖片顯示

2.1 搭建vr全景圖片的開發(fā)環(huán)境

VR開發(fā)需要gvr-android-sdk鞠呈,GitHub下載地址

gvr-android-sdk

VR開發(fā)Google官方技術(shù)文檔

VR開發(fā)技術(shù)文檔

2.1.1 導(dǎo)入全景圖相關(guān)的三個開發(fā)庫

common,commonwidget师幕,panowidget
PS:最新的SDK已經(jīng)沒有這三個文件夾了粟按,使用下一步的依賴庫即可

2.1.2 依賴該庫

compile 'com.google.vr:sdk-panowidget:1.30.0'
//compile project(':common')
//compile project(':commonwidget')
//compile project(':panowidget')
//google的一套序列化數(shù)據(jù)結(jié)構(gòu)開發(fā)庫
//compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'

2.1.3 準備全景圖片測試資源

放在assets目錄 例:assets/a.jpg(全景圖與普通圖片的不同 大诬滩,立體)

2.1.4 功能清單配置

android:largeHeap="true" 全景圖片比較耗資源

<application
    android:largeHeap="true">
</application>

2.2 布局全景控件顯示加載后的全景圖片

<com.google.vr.sdk.widgets.pano.VrPanoramaView
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:id="@+id/vr_pv" />
public class MainActivity extends AppCompatActivity {

    private VrPanoramaView vrPanoramaView;
    private ImageTask imageTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //全景圖片的瀏覽功能
        //步驟一霹粥。下載github上google開源 vr-sdk
        //1.1.導(dǎo)入到我們的工作空間 common,commonwidget  panowidget
        //1.2.依賴到我們的項目中
        //1.3.依賴sdk中找不到的api
        //1.4.準備一些測試素材 放置在assets目錄下面 例:assets/a.jpg
        //1.5.開啟內(nèi)存設(shè)置  android:largeHeap="true"盡可能使應(yīng)用使用最大內(nèi)存

2.2.1 布局查找控件

//步驟二。布局全景控件顯示加載后的全景圖片
//2.1.布局查找控件
vrPanoramaView = (VrPanoramaView) findViewById(R.id.vr_pv);

2.2.2 設(shè)置初始化參數(shù)

//2.2.設(shè)置初始化參數(shù)
vrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_STEREO);
//刪除不需要連接疼鸟,信息圖標
vrPanoramaView.setInfoButtonEnabled(false);
//隱藏全屏按鈕
vrPanoramaView.setFullscreenButtonEnabled(false);

2.2.3 創(chuàng)建異步任務(wù)加載圖片

Bitmap是圖片在內(nèi)存中的表示對象后控,全景圖也可加載成bitmap

    //2.3.創(chuàng)建異步任務(wù)加載圖片 Bitmap是圖片在內(nèi)存中的表示對象,全景圖也可加載成bitmap
    imageTask = new ImageTask();
    imageTask.execute();

}
private class ImageTask extends AsyncTask<Void, Void, Bitmap> {
    @Override
    protected Bitmap doInBackground(Void... params) {
        //2.4.從資產(chǎn)目錄打開一個流
        try {
            InputStream inputStream = getAssets().open("a.jpg");
            //2.5.使用BitmapFactory轉(zhuǎn)換成Bitmap
            Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
            return bitmap;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    //2.6任務(wù)執(zhí)行完后,可獲取Bitmap圖片
    @Override
    protected void onPostExecute(Bitmap bitmap) {
        super.onPostExecute(bitmap);
        if (bitmap != null) {
            //loadImageFromBitmap加載bitmap到顯示控件 參1.bitmap 參2 顯示參數(shù)的封裝
            VrPanoramaView.Options options = new VrPanoramaView.Options();
            //加載立體圖片空镜,上部分顯示在左眼浩淘,下部分顯示在右眼
            options.inputType = VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER;
            if (listener == null) {
                listener = new VrPanoramaEventListener() {
                    @Override
                    public void onLoadError(String errorMessage) {
                        super.onLoadError(errorMessage);
                        //處理加載失敗的情況
                        Toast.makeText(MainActivity.this, "錯誤消息:" + errorMessage, Toast.LENGTH_SHORT).show();
                    }

                    @Override
                    public void onLoadSuccess() {
                        super.onLoadSuccess();
                        //成功的情況提示下現(xiàn)在要進行全景圖片的展示
                        Toast.makeText(MainActivity.this, "進入vr:", Toast.LENGTH_SHORT).show();
                    }
                };
                // 增加加載出錯的業(yè)務(wù)邏輯處理
                vrPanoramaView.setEventListener(listener);
            }
            //2.7.讓控件加載bitmap對象
            vrPanoramaView.loadImageFromBitmap(bitmap, options);
            //2.8.如果loadImageFromBitmap加載失敗需要提示用戶相關(guān)信息則需要添加事件監(jiān)聽器listener
        }
    }
}
private VrPanoramaEventListener listener;

2.3 VrPanoramaView控件退到后臺,回到屏幕吴攒,銷毀處理細節(jié)

    //步驟三张抄。VrPanoramaView控件退到后臺,回到屏幕洼怔,銷毀處理細節(jié)
    //3.1.退到后臺.暫停顯示
    @Override
    protected void onPause() {
        super.onPause();
        if (vrPanoramaView != null) {
            vrPanoramaView.pauseRendering();
        }
    }
    //3.2.回到屏幕,恢復(fù)顯示
    @Override
    protected void onResume() {
        super.onResume();
        if (vrPanoramaView != null) {
            vrPanoramaView.resumeRendering();
        }
    }
    //3.3.退出界面停止顯示
    @Override
    protected void onDestroy() {
        if (vrPanoramaView != null) {
            vrPanoramaView.shutdown();
        }
        if (imageTask != null && !imageTask.isCancelled()) {//銷毀任務(wù)
            imageTask.cancel(true);
            imageTask = null;
        }
        super.onDestroy();
    }
}
package com.itheima.demovrimagevideo2;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.Toast;

import com.google.vr.sdk.widgets.common.VrWidgetView;
import com.google.vr.sdk.widgets.pano.VrPanoramaEventListener;
import com.google.vr.sdk.widgets.pano.VrPanoramaView;

import java.io.IOException;
import java.io.InputStream;

public class MainActivity extends AppCompatActivity {

    private VrPanoramaView vrPanoramaView;
    private ImageTask imageTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //全景圖片的瀏覽功能
        //步驟一署惯。下載github上google開源 vr-sdk
        //1.1.導(dǎo)入到我們的工作空間 common,commonwidget  panowidget
        //1.2.依賴到我們的項目中
        //1.3.依賴sdk中找不到的api
        //1.4.準備一些測試素材 放置在assets目錄下面 例:assets/a.jpg
        //1.5.開啟內(nèi)存設(shè)置  android:largeHeap="true"盡可能使應(yīng)用使用最大內(nèi)存
        //步驟二。將全景圖片加載到內(nèi)存中镣隶,再顯示在控件
        //2.1.布局全景圖片顯示控件
        vrPanoramaView = (VrPanoramaView) findViewById(R.id.vr_pano);
        //刪除不需要連接
        vrPanoramaView.setInfoButtonEnabled(false);
        //隱藏全屏按鈕
        vrPanoramaView.setFullscreenButtonEnabled(false);
        //2.2.所有的圖片在內(nèi)存表示成Bitmap
        imageTask = new ImageTask();
        imageTask.execute();
        //vrPanoramaView.loadImageFromBitmap(bitmap);
    }

    //2.3.AsyncTask異步加載
    private class ImageTask extends AsyncTask<Void, Void, Bitmap> {
        @Override
        protected Bitmap doInBackground(Void... params) {
            try {
                InputStream inputStream = getAssets().open("a.jpg");
                //2.4.使用BitmapFactory 可以sd ,byte[] inputstream-->Bitmap
                Bitmap bitmap = BitmapFactory.decodeStream(inputStream);
                return bitmap;
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        @Override
        protected void onPostExecute(Bitmap bitmap) {
            super.onPostExecute(bitmap);
            if (bitmap != null) {
                //loadImageFromBitmap加載bitmap到顯示控件 參1.bitmap 參2 顯示參數(shù)的封裝
                VrPanoramaView.Options option = new VrPanoramaView.Options();
                //立體圖片:上半張顯示在左眼极谊,下半張顯示在右眼
                option.inputType = VrPanoramaView.Options.TYPE_STEREO_OVER_UNDER;
                VrPanoramaEventListener listener=new VrPanoramaEventListener(){
                    @Override
                    public void onLoadSuccess() {
                        super.onLoadSuccess();
                        //成功的情況提示下現(xiàn)在要進行全景圖片的展示
                        Toast.makeText(MainActivity.this, "進入vr圖片", Toast.LENGTH_SHORT).show();
                    }
                    @Override
                    public void onLoadError(String errorMessage) {
                        super.onLoadError(errorMessage);
                        //處理加載失敗的情況
                        Toast.makeText(MainActivity.this, "E:"+errorMessage, Toast.LENGTH_SHORT).show();
                    }
                };
                //2.5.增加加載出錯的業(yè)務(wù)邏輯處理
                vrPanoramaView.setEventListener(listener);
                //2.6.全屏展示
                vrPanoramaView.setDisplayMode(VrWidgetView.DisplayMode.FULLSCREEN_MONO);
                //2.4.加載bitmap到控件上顯示
                vrPanoramaView.loadImageFromBitmap(bitmap, option);
            }
        }
    }
    //步驟三。優(yōu)化程序細節(jié) 安岂,頁面退到后臺,暫停顯示 轻猖,頁面顯示在屏幕 恢復(fù)顯示。銷毀頁面,釋放全景圖片

    //3.1 頁面退到后臺,暫停顯示
    @Override
    protected void onPause() {
        super.onPause();
        if(vrPanoramaView!=null)
        {
            vrPanoramaView.pauseRendering();
        }
    }
    //3.2 頁面顯示在屏幕 恢復(fù)顯示
    @Override
    protected void onResume() {
        super.onResume();
        if(vrPanoramaView!=null)
        {
            vrPanoramaView.resumeRendering();
        }
    }
    //3.3.銷毀頁面,釋放全景圖片
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vrPanoramaView != null) {
            vrPanoramaView.shutdown();
        }
        if (imageTask != null && !imageTask.isCancelled()) {
            imageTask.cancel(true);
            imageTask = null;
        }
    }
}

3. 全景視頻顯示開發(fā)

3.1 vr視頻環(huán)境搭建

  • 導(dǎo)入需要的三個庫 common,comonwidget.videowiget
  • 依賴這三個庫
  • 準備顯示使用到全景視頻 assets目錄下面 例:assets/b.mp4
  • 配置大內(nèi)存選項 android:largeHeap="true" 可以使用最大內(nèi)存

3.1.1 導(dǎo)入vr sdk 中的相關(guān)庫

common域那,commonwidget咙边,videowidget
PS:最新的SDK已經(jīng)沒有這三個文件夾了,使用下一步的依賴庫即可

3.1.2 依賴以上三個庫

compile 'com.google.vr:sdk-videowidget:1.30.0'
//compile project(':common')
//compile project(':commonwidget')
//compile project(':videowidget')
// 出現(xiàn)類未定義錯誤的缺少庫
//compile 'com.google.android.exoplayer:exoplayer:r1.5.10'
//compile 'com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7'

3.1.3 打開內(nèi)存設(shè)置 android:largeHeap="true"

<application
        android:largeHeap="true">
</application>

3.1.4 準備測試使用的全景視頻

放置在assets目錄 例:assets/congo_2048.mp4

3.2 布局視頻控件次员,并加載視頻內(nèi)容

public class MainActivity extends AppCompatActivity {

    private VrVideoView vrVideoView;
    private VideoTask videoTask;
    private SeekBar seekBar;
    private TextView text;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //步驟一样眠。搭建vr全景視頻的開發(fā)環(huán)境
        //1.1.導(dǎo)入需要的三個庫 common,comonwidget.videowiget
        //1.2.依賴這三個庫
        //1.3.準備顯示使用到全景視頻 assets目錄下面 例:assets/b.mp4
        //1.4.配置大內(nèi)存選項   android:largeHeap="true" 可以使用最大內(nèi)存
        //步驟二。布局視頻控件翠肘,并加載視頻內(nèi)容
        //2.1布局控件
        //2.2查找控件
        vrVideoView = (VrVideoView) findViewById(R.id.vr_vv);
        //2.3加載視頻數(shù)據(jù)
        videoTask = new VideoTask();
        videoTask.execute("congo_2048.mp4");
    }
    // 創(chuàng)建異步任務(wù)防止占用主線程
    private class VideoTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... params) {
           // 把文件名取出來進行加載  視頻資源來自asssets
            VrVideoView.Options options = new VrVideoView.Options();
            //2.4.輸入模式
            //立體模式
            options.inputType = VrVideoView.Options.TYPE_STEREO_OVER_UNDER;
            //2.5.設(shè)置視頻來源
            //處理視頻加載的格式(sd卡或者assets)
            //options.inputFormat = VrVideoView.Options.FORMAT_DEFAULT;
            //FORMAT_DEFAULT 視頻資源來自assetss/sd
            //FORMAT_HLS 視頻來自網(wǎng)絡(luò)流媒 直播
            //處理視頻加載的格式 流媒體直播格式
            options.inputFormat=VrVideoView.Options.FORMAT_HLS;
            try {
                //2.8 如果資源有問題檐束,不能正常播放需要處理下界面提示
                if (listener == null) {
                    listener = new VrVideoEventListener() {
                        @Override
                        public void onLoadSuccess() {
                            super.onLoadSuccess();
                            //獲取當前總時長
                            long max=vrVideoView.getDuration();
                            seekBar.setMax((int) max);
                            seekBar.setProgress(0);
                            Toast.makeText(MainActivity.this, "準備播放vr", Toast.LENGTH_SHORT).show();

                        }
                        @Override
                        public void onNewFrame() {
                            super.onNewFrame();
                            //獲取當前播放位置
                            long currentPosition = vrVideoView.getCurrentPosition();
                            //設(shè)置當前進度
                            seekBar.setProgress((int) currentPosition);
                            //時間值
                            String total=String.format("%.2f",vrVideoView.getDuration()/1000f);
                            String curr=String.format("%.2f",vrVideoView.getCurrentPosition()/1000f);
                            text.setText("播放進度"+curr+":"+total);
                        }
                        private boolean isPause=true;
                        @Override
                        public void onCompletion() {
                            super.onCompletion();
                            seekBar.setProgress(0);
                            vrVideoView.seekTo(0);//重回0位置
                            vrVideoView.pauseVideo();//暫停播放
                            isPause=true;//保存暫停狀態(tài)
                        }

                        @Override
                        public void onClick() {
                            super.onClick();
                            if (isPause) {//播放
                                vrVideoView.playVideo();
                                isPause=false;
                            } else {
                                vrVideoView.pauseVideo();
                                isPause=true;
                            }
                        }

                        @Override
                        public void onLoadError(String errorMessage) {
                            super.onLoadError(errorMessage);
                            Toast.makeText(MainActivity.this, "加載失敗", Toast.LENGTH_SHORT).show();
                        }
                    };
                    vrVideoView.setEventListener(listener);
                }
                //2.7加載視頻資源
                //vrVideoView.loadVideoFromAsset(params[0], options);
                String url="http://youkesvideo.oss-cn-hangzhou.aliyuncs.com/movie2/2016/10/11/%E6%B9%84%E5%85%AC%E6%B2%B3%E8%A1%8C%E5%8A%A8.Operation.Mekong.2016.TC720P.X264.AAC.Mandarin.CHS.Mp4Ba.mp4";
                vrVideoView.loadVideo(Uri.parse(url),options);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }
    }

    private VrVideoEventListener listener;

3.3 處理頁面退到后臺,回到屏幕,頁面銷毀

    //步驟三束倍。處理頁面退到后臺被丧,回到屏幕,頁面銷毀盟戏。

    //3.1.頁面退到后臺暫停視頻
    @Override
    protected void onPause() {
        super.onPause();
        if (vrVideoView != null) {
            vrVideoView.pauseRendering();
        }
    }

    //3.2.頁面回到屏幕繼續(xù)播放
    @Override
    protected void onResume() {
        super.onResume();
        if (vrVideoView != null) {
            vrVideoView.resumeRendering();
        }
    }

    //3.3.頁面銷毀
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vrVideoView != null) {
            vrVideoView.shutdown();
        }
        if (videoTask != null && !videoTask.isCancelled()) {
            videoTask.cancel(false);
            videoTask = null;
        }
    }
}

3.4 添加進度條相關(guān)事件

3.4.1布局查找出控件

<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:orientation="vertical">
    <SeekBar
        android:id="@+id/seek_bar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <TextView
        android:id="@+id/text"
        android:background="#AEAEAE"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:gravity="center"
        android:textColor="#FFFFFF"
        android:textSize="22sp"
        android:text="00:00" />
</LinearLayout>
seekBar = (SeekBar) findViewById(R.id.seek_bar);
text = (TextView) findViewById(R.id.text);

3.4.2.加載成功設(shè)置最大值

在VrVideoEventListener中的onLoadSuccess處理

3.4.3.在播放過程中不斷更新

進度值 onNewFrame 每播放一個畫面就調(diào)用該方法一次

3.4.4.同步理新文本時間值

在VrVideoEventListener中的onNewFrame處理

3.4.5.播放完成重新播放

在VrVideoEventListener中的onCompletion處理

package com.itheima.appvideo;

import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.SeekBar;
import android.widget.TextView;
import android.widget.Toast;

import com.google.vr.sdk.widgets.common.VrWidgetView;
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 vrVideoView;
    private VideoTask task;
    private SeekBar seekBar;
    private TextView timeText;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        //步驟一。搭建vr全景視頻的開發(fā)環(huán)境
        //1.1.導(dǎo)入需要的三個庫 common,comonwidget.videowiget
        //1.2.依賴這三個庫
        //1.3.準備顯示使用到全景視頻 assets目錄下面 例:assets/b.mp4
        //1.4.配置大內(nèi)存選項   android:largeHeap="true" 可以使用最大內(nèi)存
        //步驟二甥桂。加載視頻到內(nèi)存中柿究,再使用控件顯示
        //2.1 布局全景視頻控件
        vrVideoView = (VrVideoView) findViewById(R.id.vr_video_view);
        //2.2加載全景視頻
        task = new VideoTask();
        task.execute("b.mp4");
        seekBar = (SeekBar) findViewById(R.id.seekbar);
        timeText = (TextView) findViewById(R.id.time);
    }

    //2.2.1創(chuàng)建異步任務(wù)防止占用主線程
    private class VideoTask extends AsyncTask<String, Void, Void> {
        @Override
        protected Void doInBackground(String... params) {
            //2.2.2.把文件名取出來進行加載  視頻資源來自asssets
            VrVideoView.Options options = new VrVideoView.Options();
            //立體的視頻資源:上半畫面顯示在左眼,下半畫面顯示右眼
            options.inputType = VrVideoView.Options.TYPE_STEREO_OVER_UNDER;
            //FORMAT_DEFAULT 視頻資源來自assetss/sd
            //FORMAT_HLS 視頻來自網(wǎng)絡(luò)流媒 直播
            options.inputFormat = VrVideoView.Options.FORMAT_DEFAULT;
            try {
                //步驟四.編寫進度顯示 業(yè)務(wù)邏輯
                VrVideoEventListener listener = new VrVideoEventListener() {
                    //4.1.加載成功
                    @Override
                    public void onLoadSuccess() {
                        super.onLoadSuccess();
                        Toast.makeText(MainActivity.this, "準備放3d視頻", Toast.LENGTH_SHORT).show();
                        upProgress();
                    }

                    //4.2加載失敗的提示
                    @Override
                    public void onLoadError(String errorMessage) {
                        super.onLoadError(errorMessage);
                        Toast.makeText(MainActivity.this, "視頻加載失敗" + errorMessage, Toast.LENGTH_SHORT).show();
                    }

                    //4.3.顯示播放時長與播放進度
                    //4.3.1.布局顯示控件SeekBar 與TextView
                    //4.3.2.查找出來
                    //4.3.3.在onLoadSuccess里面獲取視頻時長 視頻播放位置
                    //4.3.4.在onNewFrame  不斷獲取最新的進度值來更新界面
                    @Override//播放了一個畫面,onNewFrame就被調(diào)用次
                    public void onNewFrame() {
                        super.onNewFrame();
                        upProgress();
                    }

                    private boolean isPause = false;

                    //4.4.處理播放完成
                    @Override
                    public void onCompletion() {
                        super.onCompletion();
                        vrVideoView.seekTo(0);
                        vrVideoView.pauseVideo();
                        isPause = true;
                        upProgress();
                    }

                    //4.5.點擊業(yè)務(wù)
                    @Override
                    public void onClick() {
                        super.onClick();
                        if (isPause) {
                            isPause = false;
                            vrVideoView.playVideo();
                        } else {
                            isPause = true;
                            vrVideoView.pauseVideo();
                        }
                    }
                };
                vrVideoView.setEventListener(listener);
                vrVideoView.loadVideoFromAsset(params[0], options);//參1文件名 參2 設(shè)置參數(shù)
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

        private void upProgress() {
            long max = vrVideoView.getDuration();
            long currPosition = vrVideoView.getCurrentPosition();
            seekBar.setMax((int) max);
            seekBar.setProgress((int) currPosition);
            timeText.setText(String.format("%.2f", currPosition / 1000f) + "/" + String.format("%.2f", max / 1000f));
        }
    }
    //步驟三黄选。程序優(yōu)化 頁面退到后臺蝇摸,暫停  頁面回到屏幕繼續(xù)播放  頁面銷毀 關(guān)閉

    //3.1. 頁面退到后臺,暫停
    @Override
    protected void onPause() {
        super.onPause();
        if (vrVideoView != null) {
            vrVideoView.pauseRendering();
        }
    }

    //3.2 頁面回到屏幕繼續(xù)播放
    @Override
    protected void onResume() {
        super.onResume();
        if (vrVideoView != null) {
            vrVideoView.resumeRendering();
        }
    }

    //3.3. 頁面銷毀 關(guān)閉銷毀
    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (vrVideoView != null) {
            vrVideoView.shutdown();
        }
        if (task != null && !task.isCancelled()) {
            task.cancel(true);
            task = null;
        }
    }
}

GitHub:https://github.com/JackChen1999/GoogleVR

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末办陷,一起剝皮案震驚了整個濱河市貌夕,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌民镜,老刑警劉巖啡专,帶你破解...
    沈念sama閱讀 216,744評論 6 502
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異制圈,居然都是意外死亡们童,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,505評論 3 392
  • 文/潘曉璐 我一進店門鲸鹦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來慧库,“玉大人,你說我怎么就攤上這事馋嗜∑氚澹” “怎么了?”我有些...
    開封第一講書人閱讀 163,105評論 0 353
  • 文/不壞的土叔 我叫張陵嵌戈,是天一觀的道長覆积。 經(jīng)常有香客問我,道長熟呛,這世上最難降的妖魔是什么宽档? 我笑而不...
    開封第一講書人閱讀 58,242評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮庵朝,結(jié)果婚禮上吗冤,老公的妹妹穿的比我還像新娘。我一直安慰自己九府,他們只是感情好椎瘟,可當我...
    茶點故事閱讀 67,269評論 6 389
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著侄旬,像睡著了一般肺蔚。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上儡羔,一...
    開封第一講書人閱讀 51,215評論 1 299
  • 那天宣羊,我揣著相機與錄音璧诵,去河邊找鬼。 笑死仇冯,一個胖子當著我的面吹牛之宿,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播苛坚,決...
    沈念sama閱讀 40,096評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼比被,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了泼舱?” 一聲冷哼從身側(cè)響起等缀,我...
    開封第一講書人閱讀 38,939評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎柠掂,沒想到半個月后项滑,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體依沮,經(jīng)...
    沈念sama閱讀 45,354評論 1 311
  • 正文 獨居荒郊野嶺守林人離奇死亡涯贞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,573評論 2 333
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了危喉。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片宋渔。...
    茶點故事閱讀 39,745評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖辜限,靈堂內(nèi)的尸體忽然破棺而出皇拣,到底是詐尸還是另有隱情,我是刑警寧澤薄嫡,帶...
    沈念sama閱讀 35,448評論 5 344
  • 正文 年R本政府宣布氧急,位于F島的核電站,受9級特大地震影響毫深,放射性物質(zhì)發(fā)生泄漏吩坝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,048評論 3 327
  • 文/蒙蒙 一哑蔫、第九天 我趴在偏房一處隱蔽的房頂上張望钉寝。 院中可真熱鬧,春花似錦闸迷、人聲如沸嵌纲。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,683評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽今阳。三九已至邓嘹,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間险胰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,838評論 1 269
  • 我被黑心中介騙來泰國打工起便, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人榆综。 一個月前我還...
    沈念sama閱讀 47,776評論 2 369
  • 正文 我出身青樓妙痹,卻偏偏與公主長得像,于是被迫代替她去往敵國和親鼻疮。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 44,652評論 2 354

推薦閱讀更多精彩內(nèi)容