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

今天项目中需要用到得图进行视频的360度全方位观看,因此将项目中集成了一下得图的SDK
开发工具:Android studio
运行环境:Windows7
首先我们需要在得图的官网进行SDK的下载,官网地址是http://www.detu.com。下载最新的SDK就可以,下载完成之后解压当前压缩包。这是解压之后项目中libs文件夹下的图片
我们根据需要将所有的jar包导入进我们自己的项目中的libs文件夹下。因为得图使用universal-image-loader类库来管理图片,因此首先要在Application中初始化ImageLoader,若在您的项目中已使用到了该类库,只需保证 DisplayImageOptions 中bitmapConfig为Bitmap.Config.ARGB_8888类型,imageScaleType为ImageScaleType.NONE,并且开启了内存和磁盘缓存。 没有配置过的可以按以下方式配置:
其中红色的地方比较重要,需要我们注意
如果项目中已经使用到ImageLoder,请注意jar的导入,不要重复。
Android studio中jar包的导入方法如下图:
将jar包导入到libs文件夹下,右键点击
这时我们可以查看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的使用大致就是这些。如果有什么错误请及时指出。谢谢!

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值