Android中VR視訊的Demo
阿新 • • 發佈:2019-01-05
使用VR元件時,專案需要最低SDK版本為19。
在main下新建資料夾為assets,用於存放資原始檔
一、配置VR開發環境步驟:
1.使用VR是非常消耗記憶體的,所以為了避免OOM的問題,需在清單檔案中application下新增的屬性(把警報許可權提高,從192提高到512MB)。(Heap:堆)
2.在build.gradle裡新增最新的依賴檔案,下面的三個是後面
依賴module產生的。
gradle檔案參照sample下的demo來修改
具體配置環境類似上一篇文章:http://blog.csdn.net/lixiang_y/article/details/60874691
具體實現程式碼如下:
效果圖:(手機沒有陀螺儀,是無法顯示旋轉顯示)
在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>
效果圖:(手機沒有陀螺儀,是無法顯示旋轉顯示)