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的创建
效果图是这样子的:
这里需要我们自己去写一个时间监控的进度条,没有发现他是否带,或许可能是我没有找到吧。反正我自己写了一个。
接下来我们创建MainActivity
这样我们基本就完成了得图SDK的嵌套了。
其中遇到几个问题,这里一一说明下。
1.Android中加载视频之后,陀螺仪的属性设置为true之后,发现观看视频的时候并没有实现手机的360度旋转观看。后来发现需要我们再程序加载完成之后,再设置其属性就可以,可能是小弟年轻,到现在也没弄明白怎么回事。所以我就将开启功能的代码,写到了播放按钮的点击事件里面。
2.当我们进入到Activity中的时候,默认是自动播放视频的。但是我们还没有调用播放按钮的点击事件,那么陀螺仪就不能打开。这个时候需要我们设置当前视频加载完成之后,不要播放。
当前视频加载完成之后,默认是暂停状态。进入到界面之后,我们点击播放按钮,然后进行视频的播放,这里同时设置陀螺仪的属性为ture。
3.在程序运行过程中,报了android:getSlotFromBufferLocked: unknown buffer: 0xf3d544c0 错误,这个是因为Android6.0系统本身的问题,我们不需要去处理。如果非要处理的话,可以更换一个虚拟机。就不会报这个错误了。
得图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的使用大致就是这些。如果有什么错误请及时指出。谢谢!
相关文章推荐
- 集成Vuforia 5.0.5与Google Cardboard实现AR+VR的效果
- Android Studio 实现真机截图和短视频录制
- 笔记——android实现VR视频显示和优化
- 在Google Daydream上用VR观看Youtobe视频吧!
- Android Studio使用Gradle实现自动打包,签名,自定义apk文件名,多渠道打包,集成系统签名证书【附效果图附源码】
- 无限互联iOS项目视频教程 新浪微博2.8.实现主题Label_在线视频观看
- 做视频直播时如何实现对观看直播的用户做登记?
- android studio 免费实现聊天视频功能
- Tesseract OCR集成Android Studio实现OCR识别
- [置顶] Android开发实战使用(VR技术实现360°全景视频播放功能)
- android studio中观看json&http视频疑问
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-9系统,3行代码即可集成.
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-9系统,3行代码即可集成.
- Android开发VR实战之播放360度全景视频
- PlayStation VR将支持360度全景视频
- Android studio相关设置及实现存在于工程目录中的视频播放
- 仿照微信的效果,实现了一个支持多选、选原图和视频的图片选择器,适配了iOS6-9系统,3行代码即可集成.
- 基于vlc的unity3d vr视频播放器开发,360度全景视频
- 通过Android实现VR视频的播放
- VR的图片和视频的实现流程