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

Android studio 集成得图实现视频360度观看(VR)

2016-08-12 09:46 309 查看
今天项目中需要用到得图进行视频的360度全方位观看,因此将项目中集成了一下得图的SDK

开发工具:Android studio

运行环境:Windows7

首先我们需要在得图的官网进行SDK的下载,官网地址是http://www.detu.com。下载最新的SDK就可以,下载完成之后解压当前压缩包。


我们根据需要将所有的jar包导入进我们自己的项目中的libs文件夹下。因为得图使用universal-image-loader类库来管理图片,因此首先要在Application中初始化ImageLoader,若在您的项目中已使用到了该类库,只需保证 DisplayImageOptions 中bitmapConfig为Bitmap.Config.ARGB_8888类型,imageScaleType为ImageScaleType.NONE,并且开启了内存和磁盘缓存。 没有配置过的可以按以下方式配置:



如果项目中已经使用到ImageLoder,请注意jar的导入,不要重复。

Android studio中jar包的导入方法如下图:



这时我们可以查看build.gradle中是否有重复的jar导入



接下来我们需要去配置基本信息



然后我们就可以在代码中进行布局的创建和Activity的创建

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<com.player.renderer.PanoPlayerSurfaceView
android:id="@+id/video"
android:layout_width="match_parent"
android:layout_height="match_parent" />

<LinearLayout
android:id="@+id/videolay"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_alignParentBottom="true"
android:gravity="center"
android:orientation="horizontal" >

<Button
android:id="@+id/btn_play"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:minHeight="40dp"
android:text="播放" />

<TextView
android:id="@+id/lable1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="00:00:00" />

<SeekBar
android:id="@+id/sb_progress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.8" />

<TextView
android:id="@+id/lable2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="00:00:00" />
</LinearLayout>
</RelativeLayout>


效果图是这样子的:



这里需要我们自己去写一个时间监控的进度条,没有发现他是否带,或许可能是我没有找到吧。反正我自己写了一个。

接下来我们创建MainActivity

package com.starts.liuzhourailwaycourt_android;

import android.app.Activity;
import android.media.Image;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.SeekBar;
import android.widget.TextView;

import com.nostra13.universalimageloader.core.ImageLoader;
import com.player.data.panoramas.PanoramaData;
import com.player.panoplayer.IPanoPlayerListener;
import com.player.panoplayer.IPanoPlayerVideoPluginListener;
import com.player.panoplayer.PanoPlayer;
import com.player.panoplayer.PanoPlayerUrl;
import com.player.panoplayer.Plugin;
import com.player.panoplayer.plugin.VideoPlugin;
import com.player.renderer.PanoPlayerSurfaceView;

import tv.danmaku.ijk.media.player.IjkMediaPlayer;

/**
* Created by Administrator on 2016/8/11.
*/
public class Video extends Activity implements IPanoPlayerListener, IPanoPlayerVideoPluginListener {
private PanoPlayerSurfaceView panoPlayerSurfaceView;
private PanoPlayer panoPlayer_render;
private Handler handler = new Handler();
//视频播放状态
private PanoPlayer.PanoVideoPluginStatus playerStatus = PanoPlayer.PanoVideoPluginStatus.VIDEO_STATUS_STOP;
private VideoPlugin videoplugin;
private boolean isGyroEnable = false;
private boolean isSeekBarDragging;
private Button buttonPlay;
private SeekBar sb_progress;
private TextView maxtimelable;
private TextView curtimelable;
private boolean isplaylive = false;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.video);

buttonPlay = (Button) findViewById(R.id.btn_play);
sb_progress = (SeekBar) findViewById(R.id.sb_progress);
maxtimelable = (TextView) findViewById(R.id.lable2);
curtimelable = (TextView) findViewById(R.id.lable1);
//获取播放器
panoPlayerSurfaceView = (PanoPlayerSurfaceView) findViewById(R.id.video);
//创建渲染器并和播放器进行绑定
panoPlayer_render = new PanoPlayer(panoPlayerSurfaceView, Video.this);
panoPlayer_render.setListener(this);
panoPlayer_render.setVideoPluginListener(this);
panoPlayerSurfaceView.setRenderer(panoPlayer_render);
PanoPlayerUrl panoPlayerUrl = new PanoPlayerUrl();
panoPlayerUrl.SetVideoUrlImage("http://v3.cztv.com/cztv/vod/2016/03/15/f71522061dc84e10bc012c5243585e0f/h264_1500k_mp4.mp4",null );
panoPlayer_render.Play(panoPlayerUrl);
//        playLive();
buttonPlay.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (panoPlayer_render != null) {
System.out.println("isGyroEnable == " + isGyroEnable);
panoPlayer_render.setGyroEnable(true);
}
Log.e("", "click btn_play");
switch (playerStatus) {
case VIDEO_STATUS_PAUSE:
videoplugin.start();
Log.e("", "click btn_play to start");
break;
case VIDEO_STATUS_STOP:
videoplugin.start();
Log.e("", "click btn_play to start");
break;
case VIDEO_STATUS_PLAYING:
videoplugin.pause();
Log.e("", "click btn_play to pause");
break;
default:
break;
}
}
});

sb_progress.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {

@Override
public void onStopTrackingTouch(SeekBar sb) {
isSeekBarDragging = false;
videoplugin.seekTo(sb.getProgress());
}

@Override
public void onStartTrackingTouch(SeekBar arg0) {
isSeekBarDragging = true;
}

@Override
public void onProgressChanged(SeekBar arg0, int progress,
boolean fromUser) {
}
});

}

//    public void playLive() {
//        isplaylive=true;
//        PanoPlayerUrl panoplayerurl = new PanoPlayerUrl();
//
//        //播放 方式一:  setXmlContent(String content);  content 必须是如下格式的XML 文本 才可以播放
//
//
//        //播放方式二:  setXmlUrl(String url); url 地址 必须返回的是 如上格式 的XML 文本才可以播放
//
//        //panoplayerurl.setXmlUrl("http://www.detu.com/live/xinlan/live-test.xml");
//
//        String PanoPlayer_Template = "<DetuVr> "
//                + "<settings init=\"pano1\" initmode=\"flat\" enablevr=\"false\"  title=\"\"/>"
//                + "<scenes>"
//                + "<scene name=\"pano1\"  title=\"\"    thumburl=\"\"   >"
//                + "<image type=\"video\" url=\"%s\" rx=\"0\" ry=\"0\" rz=\"0\"/>"
//                + "<view hlookat=\"0\" vlookat=\"0\" fov=\"100\" vrfov=\"95\" vrz=\"0.5\" righteye=\"0.1\" fovmax=\"130\" defovmax=\"95\" gyroEnable=\"false\"/>"
//                + "</scene>"
//                + "</scenes>"
//                + "</DetuVr>";
//        String xmlstring = String.format(PanoPlayer_Template, "http://v3.cztv.com/cztv/vod/2016/03/15/f71522061dc84e10bc012c5243585e0f/h264_1500k_mp4.mp4");
//
//        panoplayerurl.setXmlContent(xmlstring);
//
//        panoPlayer_render.Play(panoplayerurl);
//        panoPlayer_render.setGyroEnable(true);
//    }

@Override
public void PanoPlayOnLoading() {
Log.d("PanoPlay", "PluginVideoOnStatus to PanoPlayOnLoading");
}

@Override
public void PanoPlayOnLoaded() {
Log.d("PanoPlay", "PluginVideoOnStatus to PanoPlayOnLoaded");
Plugin plugin = panoPlayer_render.getCurPlugin();
if (plugin instanceof VideoPlugin && !isplaylive) {
videoplugin = (VideoPlugin) plugin;
videoplugin.pause();
findViewById(R.id.videolay).setVisibility(View.VISIBLE);
}
}

@Override
public void PanoPlayOnEnter(PanoramaData panoramaData) {
Log.d("PanoPlay", "PluginVideoOnStatus to PanoPlayOnEnter");
}

@Override
public void PanoPlayOnLeave(PanoramaData panoramaData) {
Log.d("PanoPlay", "PluginVideoOnStatus to PanoPlayOnLeave");
}

@Override
public void PanoPlayOnError(PanoPlayer.PanoPlayerErrorCode panoPlayerErrorCode) {
Log.d("PanoPlay", "PluginVideoOnStatus to PanoPlayOnError");
}

@Override
public void PluginVideoOnStatusChanged(PanoPlayer.PanoVideoPluginStatus panoVideoPluginStatus) {
playerStatus = panoVideoPluginStatus;
switch (panoVideoPluginStatus) {
case VIDEO_STATUS_PAUSE:
buttonPlay.post(new Runnable() {
public void run() {
buttonPlay.setText("播放");
}
});
Log.d("PanoPlay", "PluginVideoOnStatusChanged to pause");
break;
case VIDEO_STATUS_STOP:
buttonPlay.post(new Runnable() {
public void run() {
buttonPlay.setText("停止");
}
});
Log.d("PanoPlay", "PluginVideoOnStatusChanged to stop");
sb_progress.setProgress(0);
break;
case VIDEO_STATUS_PLAYING:
buttonPlay.post(new Runnable() {
public void run() {
buttonPlay.setText("暂停");
}
});
Log.d("PanoPlay", "PluginVideoOnStatusChanged to play");
break;
case VIDEO_STATUS_FINISH:
Log.d("PanoPlay", "PluginVideoOnStatusChanged to FINISH");
break;
case VIDEO_STATUS_BUFFER_EMPTY:
Log.d("PanoPlay", "PluginVideoOnStatusChanged to BUFFER_EMPTY");
break;
default:
Log.d("PanoPlay", "PluginVideoOnStatusChanged to UNPREPARED;");
break;
}
}

@Override
public void PluginVideoOnProgressChanged(final int curTime, int bufTime, final int maxTime) {

if (!isSeekBarDragging) {
sb_progress.setMax(maxTime);
sb_progress.setSecondaryProgress(bufTime);
sb_progress.setProgress(curTime);
handler.post(new Runnable() {
@Override
public void run() {
maxtimelable.setText(formatDuring(maxTime));
curtimelable.setText(formatDuring(curTime));
}
});
}
}
public String formatDuring(long mss) {
long days = mss / (1000 * 60 * 60 * 24);
long hours = (mss % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60) + days
* 24;
long minutes = (mss % (1000 * 60 * 60)) / (1000 * 60);
long seconds = (mss % (1000 * 60)) / 1000;

String HH = (hours > 0) ? String.valueOf(hours) : "00";
String mm = (minutes > 0) ? String.valueOf(minutes) : "00";
String ss = (seconds > 0) ? String.valueOf(seconds) : "00";

HH = (HH.length() == 1) ? ("0" + HH) : (HH);
mm = (mm.length() == 1) ? ("0" + mm) : (mm);
ss = (ss.length() == 1) ? ("0" + ss) : (ss);
return HH + " : " + mm + " : " + ss;
}
@Override
public void PluginVideoOnSeekFinished() {
Log.d("PanoPlay", "PluginVideoOnSeekFinished");
}

@Override
public void PluginVideOnPlayerError(PanoPlayer.PanoPlayerErrorStatus panoPlayerErrorStatus, String errorstr) {
Log.d("PanoPlay", "PluginVideOnPlayerError" + errorstr);
}

@Override
public void PluginVideoOnInit() {
Plugin plugin = panoPlayer_render.getCurPlugin();
if (plugin != null && plugin instanceof VideoPlugin) {
videoplugin = (VideoPlugin) plugin;
videoplugin.setLogLevel(IjkMediaPlayer.IJK_LOG_DEFAULT);
}
}
}


这样我们基本就完成了得图SDK的嵌套了。

其中遇到几个问题,这里一一说明下。

1.Android中加载视频之后,陀螺仪的属性设置为true之后,发现观看视频的时候并没有实现手机的360度旋转观看。后来发现需要我们再程序加载完成之后,再设置其属性就可以,可能是小弟年轻,到现在也没弄明白怎么回事。所以我就将开启功能的代码,写到了播放按钮的点击事件里面。



2.当我们进入到Activity中的时候,默认是自动播放视频的。但是我们还没有调用播放按钮的点击事件,那么陀螺仪就不能打开。这个时候需要我们设置当前视频加载完成之后,不要播放。



当前视频加载完成之后,默认是暂停状态。进入到界面之后,我们点击播放按钮,然后进行视频的播放,这里同时设置陀螺仪的属性为ture。

3.在程序运行过程中,报了android:getSlotFromBufferLocked: unknown buffer: 0xf3d544c0 错误,这个是因为Android6.0系统本身的问题,我们不需要去处理。如果非要处理的话,可以更换一个虚拟机。就不会报这个错误了。

得图SDK的使用大致就是这些。如果有什么错误请及时指出。谢谢!
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息