通過Android實現VR視訊的播放
實現VR視訊的播放和前面寫過的VR全景圖的展示差不多,改變的也只是庫檔案的不同,資源目錄下的資源不同而已。下面就來說一下步驟。
先展示一下效果圖
完成步驟:
1.以匯入Moudle的方式匯入庫檔案。(videowidget,common,commonwidget)資源獲取連結:https://github.com/googlevr/gvr-android-sdk/
2.在main下新建資產目錄asstes,放入視訊資源
3.在清單檔案application中提高警報許可權android:largeHeap=”true”
4.在Moudlede的 build.grable檔案裡dependencies中新增
compile ‘com.google.android.exoplayer:exoplayer:r1.5.10’
compile ‘com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7’
5.關聯匯入的依賴庫
6完成xml中的佈局,video.VrVideoView,AppCompatSeekBar,TextView
7.使用非同步任務AsyncTask,(或EventBus技術)載入視訊
8.利用執行緒進行VR優化。
9.設定VR的監聽效果
具體方法:
1.以匯入Moudle的方式匯入庫檔案
2.新增資產目錄。在main新建asstes目錄,將VR資源放入
3在清單檔案下的application新增 android:largeHeap=”true”的屬下節點
4.在Module的build.gradle檔案裡dependencie中加入
compile ‘com.google.android.exoplayer:exoplayer:r1.5.10’
compile ‘com.google.protobuf.nano:protobuf-javanano:3.0.0-alpha-7’
獲取方式:在你下載的VR資原始檔路徑下(xxxx\gvr-android-sdk-master\samples\sdk-simplevideowidget)build.gradle檔案中拷取。
5.關聯你的庫檔案:ctrl+alt+shift+s在開啟的對話方塊中,選擇你原本的專案Moudle,選擇Dependencise,點選右上角”+”,選擇第三個Module dependency,在開啟的對話方塊中,選擇之前匯入的庫檔案。
6.xml中的程式碼:
<?xml version="1.0" encoding="utf-8"?>
<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="com.zhiyuan3g.vrvideo.MainActivity">
<com.google.vr.sdk.widgets.video.VrVideoView
android:layout_width="match_parent"
android:layout_height="250dp"
android:id="@+id/vr_video">
</com.google.vr.sdk.widgets.video.VrVideoView>
<android.support.v7.widget.AppCompatSeekBar
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:id="@+id/seek_bar"/>
<TextView
android:id="@+id/tv_progress"
android:textSize="20dp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>
</LinearLayout>
7、8,9步中所有的程式碼都在這了
MainActivity中的程式碼:
這裡寫程式碼片import android.os.AsyncTask;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
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 vr_video;
private SeekBar seek_bar;// 進度條
private TextView tv_progress;
private VideoLoadTask mVideoLoadTask;// 非同步任務
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// A初始化控制元件
vr_video = (VrVideoView) findViewById(R.id.vr_video);
seek_bar = (SeekBar) findViewById(R.id.seek_bar);
tv_progress = (TextView) findViewById(R.id.tv_progress);
// 隱藏VR效果左下角資訊按鈕顯示
vr_video.setInfoButtonEnabled(false);
// 切換VR模式 引數:VrVideoView.DisplayMode.FULLSCREEN_STEREO:裝置模式(手機橫著放試試)
// VrVideoView.DisplayMode..FULLSCREEN_MONO手機模式
vr_video.setDisplayMode(VrVideoView.DisplayMode.FULLSCREEN_STEREO);
// 對VR視訊進行事件監聽
vr_video.setEventListener(new MyEventListener() );
// 播放VR效果,只需要執行非同步任務即可
mVideoLoadTask = new VideoLoadTask();
mVideoLoadTask.execute("congo_2048.mp4");
}
// 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。params物件,2.VrVideoView.Options物件,決定顯示的效果
vr_video.loadVideoFromAsset(params[0],options);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
// C因為VR很佔用記憶體,所以當介面進入OnPause狀態,暫停VR檢視顯示,
// 進入OnResume狀態,繼續VR檢視顯示,進入OnDestroy狀態,殺死VR
// 當我們失去焦點,回撥
@Override
protected void onPause() {
super.onPause();
// 暫停渲染和顯示
vr_video.pauseRendering();
}
// 當獲取焦點時,回撥
@Override
protected void onResume() {
super.onResume();
vr_video.resumeRendering();
}
// 當Activity銷燬時,回撥
@Override
protected void onDestroy() {
super.onDestroy();
vr_video.shutdown();
// 在退出Activity時,如果非同步任務沒有取消,則取消
if (mVideoLoadTask!=null){
if (!mVideoLoadTask.isCancelled()){
mVideoLoadTask.cancel(true);
}
}
}
// 對VR執行狀態監聽類,自定義一個類,繼承VrVideoEventListener,複寫裡面需要的方法
private class MyEventListener extends VrVideoEventListener{
// 當VR視訊載入成功的時候回撥 什麼是回撥:當你的程式到達符合某個條件時,
// 自動呼叫某段程式碼或執行某個方法
@Override
public void onLoadSuccess() {
super.onLoadSuccess();
// 獲取視訊長度
long max = vr_video.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) vr_video.getCurrentPosition();
// 設定seekVar的進度條
seek_bar.setProgress(currentPosition);
// 顯示播放的進度數字
tv_progress.setText("播放進度:"+String.format("%.2f",currentPosition/1000.f)+String.format("%.2f",vr_video.getDuration()/1000f));
}
// 當視訊播放結束後的回到方法
@Override
public void onCompletion() {
super.onCompletion();
// 讓視訊回到0點
vr_video.seekTo(0);
// 讓視訊停止
vr_video.pauseVideo();
// 同時讓進度條回到0點
seek_bar.setProgress(0);
// 播放完成後,重新設定標籤true,暫停播放
isPaused = true;
}
// 設定一個視訊播放狀態的標籤
private boolean isPaused = false;
// 重寫點選檢視的方法,使視訊被點選時播放或者暫停
@Override
public void onClick() {
super.onClick();
Log.d("jzs","點選");
// 根據標籤判斷當前視訊的狀態,標籤false,播放則暫停,標籤true,暫停播放
// true代表視訊正處於暫停狀態
if (isPaused){
// 視訊播放
vr_video.playVideo();
}else{// false代表視訊正在播放的狀態
vr_video.pauseVideo();
}
// 對標籤操做一次後,進行取反
isPaused = !isPaused;
}
}
}
共勉!!!!!