1. 程式人生 > >Android中VR視訊的Demo

Android中VR視訊的Demo

使用VR元件時,專案需要最低SDK版本為19。

在main下新建資料夾為assets,用於存放資原始檔


一、配置VR開發環境步驟:
1.使用VR是非常消耗記憶體的,所以為了避免OOM的問題,需在清單檔案中application下新增的屬性(把警報許可權提高,從192提高到512MB)。(Heap:堆)
android:largeHeap="true"

2.在build.gradle裡新增最新的依賴檔案,下面的三個是後面
依賴module產生的。
gradle檔案參照sample下的demo來修改



具體配置環境類似上一篇文章:http://blog.csdn.net/lixiang_y/article/details/60874691


具體實現程式碼如下:

MainActivity.java

package com.zhiyuan3g.vrvideo;

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

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 mVideoView;
    private SeekBar mSeekBar;
    private TextView mTv_show;
    private VideoLoadTask mVideoLoadTask;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mVideoView = (VrVideoView) findViewById(R.id.video);
        mSeekBar = (SeekBar) findViewById(R.id.seek_bar);
        mTv_show = (TextView) findViewById(R.id.tv_show);

        //隱藏VR效果左下角資訊顯示按鈕
        mVideoView.setInfoButtonEnabled(false);
        //切換VR的模式,  引數:FULLSCREEN_STEREO 裝置模式(橫屏立體)
        mVideoView.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);
        //對VR視訊進行事件監聽
        mVideoView.setEventListener(new MyEventListener());

        //播放VR效果,只需要執行非同步任務即可
        mVideoLoadTask = new VideoLoadTask();
        mVideoLoadTask.execute("congo_2048.mp4");

    }

    //由於VR資源資料量很大,獲取需要時間,故載入視訊放在子執行緒中執行,主執行緒來顯示,可以使用非同步任務AsyncTask或
    //EventBus技術完成(AsyncTask是開啟子執行緒來實現的)
    //自定義一個類繼承AsyncTask,只使用我們需要的方法,完成子執行緒載入資源,主執行緒顯示
    private class VideoLoadTask extends AsyncTask<String,Void,Void> {

        //該方法在子執行緒執行,從本地檔案中把資源載入到記憶體中
        @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 {
                //重點提示:視訊載入的方法不僅做了把視訊讀取到記憶體中的操作(耗時操作),還做了更新UI的操作,所以它會有一個矛盾,
                // 呼叫該方法是在主執行緒還是在子執行緒(一般我們放在子執行緒去呼叫該方法)
                //使用VR控制元件物件,從資產目錄載入視訊資料,顯示效果,引數:1.String物件(就是我們的資原始檔)
                // 2.VrVideoView.Options物件,決定顯示的效果
                //此處報錯是因為loadVideoFromAsset方法不僅做了耗時操作,也做了更新UI,而其又在AsyncTask中
                //即子執行緒中,是不推薦更新UI的,所以系統會報錯,不過這個錯可以忽略。
                mVideoView.loadVideoFromAsset(params[0],options);
            } catch (IOException e) {
                e.printStackTrace();
            }
            return null;
        }

    }


    //因為VR很佔用記憶體,所以當介面進入OnPause狀態,暫停VR檢視顯示,進入onResume狀態,繼續VR檢視顯示
    //進入onDestroy狀態,殺死VR


    //當失去焦點時,回撥

    @Override
    protected void onPause() {
        super.onPause();
        //暫停渲染顯示
        mVideoView.pauseRendering();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mVideoView.resumeRendering();

    }

    //
    @Override
    protected void onDestroy() {
        super.onDestroy();
        //關閉渲染檢視
        mVideoView.shutdown();
        //在退出Activity時,如果非同步任務沒有取消,則取消
        if (mVideoLoadTask != null) {
            if (!mVideoLoadTask.isCancelled()) {
                mVideoLoadTask.cancel(true);
            }
        }
    }


    //對VR執行0狀態監聽類,自定義一個類繼承VrVideoEventListener,複習需要的方法
    private class MyEventListener extends VrVideoEventListener {

        //當VR視訊載入成功時回撥
        @Override
        public void onLoadSuccess() {
            super.onLoadSuccess();
            //獲取視訊長度
            long max = mVideoView.getDuration();
            //設定seekBar的進度最大值
            mSeekBar.setMax((int) max);

        }

        //當VR視訊載入失敗時回撥
        @Override
        public void onLoadError(String errorMessage) {
            super.onLoadError(errorMessage);
             Toast.makeText(getApplicationContext(), "播放失敗", Toast.LENGTH_SHORT).show();
        }

        //當視訊開始播放,每次進入下一幀的時候,回撥這個方法(就是播放時,會不停的回撥該方法)
        @Override
        public void onNewFrame() {
            super.onNewFrame();
            //獲取當前視訊的播放時間位置
            int currentPosition = (int) mVideoView.getCurrentPosition();
            //設定seekbar的進度條
            mSeekBar.setProgress(currentPosition);
            //顯示播放的進度數字
            mTv_show.setText("播放進度:"+String.format("",currentPosition/1000.f)+String.format("%.2f",mVideoView.getDuration()/1000f));
        }

        //當視訊播放結束後的回撥
        @Override
        public void onCompletion() {
            super.onCompletion();
            //讓視訊播放結束後,視訊回到零點
            mVideoView.seekTo(0);

            //視訊停止
            mVideoView.pauseVideo();
            //設定進度條也設定零點
            mSeekBar.setProgress(0);

            //播放完成後,重新設定標籤,標籤為true, 
            isPaused=true;
        }

        //設定一個視訊暫停的標籤,true代表暫停,false代表播放·
        private boolean isPaused=false;


        //重寫點選檢視的方法,是視訊被點選時,播放或者暫停
        @Override
        public void onClick() {
            super.onClick();
             Toast.makeText(getApplicationContext(), "點選", Toast.LENGTH_SHORT).show();
            //根據標籤判讀當前視訊的狀態,標籤false,是播放狀態,點選則暫停;標籤true,是暫停狀態,點選則播放
            if (isPaused) {
                mVideoView.playVideo();
            } else {
                mVideoView.pauseVideo();
            }
            //對標籤操作一次後,進去取反
            isPaused =!isPaused;
        }
    }
}

activity_main.xml

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
              xmlns:tools="http://schemas.android.com/tools"
              android:layout_width="match_parent"
              android:layout_height="match_parent"
              android:orientation="vertical"
              tools:context=".MainActivity">

    <com.google.vr.sdk.widgets.video.VrVideoView
        android:id="@+id/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"/>

    <TextView
        android:id="@+id/tv_show"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>


</LinearLayout>

效果圖:(手機沒有陀螺儀,是無法顯示旋轉顯示)