google vr 入门之制作简易的VR播放器及去除界面控制按钮(1)

PlayerActivity

public class PlayerActivity extends Activity implements View.OnClickListener {

private VrVideoView mVideoView;

private String mUrl;

private TextView mVideoDuration;

private SeekBar mSeekBar;

private View mVideoPorgressContainer;

private String mTotalDuration;//视频总时长, 00:08格式

private ImageView mPlayView;

private boolean isPlaying;

private View mVideoVr;

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_player);

Intent intent = getIntent();

mUrl = intent.getStringExtra(“url”);//上一个Activity传递过来的url播放地址

initView();

initData();

initListener();

}

@Override

protected void onNewIntent(Intent intent) {

setIntent(intent);

//TODO handleIntent

}

private void initView() {

mVideoView = (VrVideoView) findViewById(R.id.video_view);

mPlayView = (ImageView) findViewById(R.id.play);

mVideoDuration = (TextView) findViewById(R.id.video_duration);

mSeekBar = (SeekBar) findViewById(R.id.video_progress);

mVideoPorgressContainer = findViewById(R.id.video_progress_container);

mVideoVr = findViewById(R.id.video_vr);

mVideoView.setInfoButtonEnabled(false);//设置左侧信息原圈不可见

mVideoView.setFullscreenButtonEnabled(false);//设置全屏按钮不可见

mVideoView.setStereoModeButtonEnabled(false);//设置立体眼镜模式按钮不可见

}

private void initData() {

Uri uri;

if (“”.equals(mUrl)) {

uri = Uri.parse(“http://resource.vr-store.cn/appfile/6cc160ba38394af0a251d4275ea66c29.mp4”);//坝上的云

} else {

uri = Uri.parse(mUrl);

}

VrVideoView.Options option = new VrVideoView.Options();

try {

mVideoView.loadVideo(uri, option);

} catch (IOException e) {

e.printStackTrace();

}

}

private void initListener() {

mPlayView.setOnClickListener(this);

mVideoVr.setOnClickListener(this);

mSeekBar.setOnSeekBarChangeListener(new SeekBarListener());

mVideoView.setEventListener(new VrVideoEventListener() {

@Override

public void onClick() {

//处理控制面板的显示和隐藏

int visibility = mVideoPorgressContainer.getVisibility();

mVideoPorgressContainer.setVisibility(visibility == View.VISIBLE ? View.GONE : View.VISIBLE);

}

/**

  • Make the video mPlayView in a loop. This method could also be used to move to the next video in

  • a playlist.

*/

@Override

public void onCompletion() {

//播放完成后的操作

//mVideoView.seekTo(0);//循环播放效果

}

@Override

public void onNewFrame() {

updateVideoProgress();

}

@Override

public void onLoadSuccess() {

long duration = mVideoView.getDuration();//视频总时长,毫秒

mTotalDuration = RegularExpress.parseDuration(duration);

mSeekBar.setMax((int) duration);

}

@Override

public void onLoadError(String errorMessage) {

super.onLoadError(errorMessage);

Toast.makeText(PlayerActivity.this, “加载视频失败”, Toast.LENGTH_SHORT).show();

}

@Override

public void onDisplayModeChanged(int newDisplayMode) {

super.onDisplayModeChanged(newDisplayMode);

}

});

}

/**

  • 更新播放进度

*/

private void updateVideoProgress() {

long currentPosition = mVideoView.getCurrentPosition();

String currentPos = RegularExpress.parseDuration(currentPosition);

mSeekBar.setProgress((int) (currentPosition));//更新播放进度

StringBuilder sb = new StringBuilder();

sb.append(currentPos);

sb.append(" / ");

sb.append(mTotalDuration);

mVideoDuration.setText(sb);

}

@Override

public void onClick(View view) {

switch (view.getId()) {

case R.id.play:

performClickPlay();

break;

case R.id.video_vr:

performClickVideoVr();

break;

default:

break;

}

}

private void performClickVideoVr() {

mVideoView.setDisplayMode(3);//enterStereoMode,眼镜模式

}

/**

  • 播放暂停切换

*/

private void performClickPlay() {

if (isPlaying) {

mVideoView.pauseVideo();

mPlayView.setImageResource(R.mipmap.play);

isPlaying = false;

} else {

mVideoView.playVideo();

mPlayView.setImageResource(R.mipmap.stop);

isPlaying = true;

}

}

@Override

protected void onPause() {

super.onPause();

// Prevent the view from rendering continuously when in the background.

mVideoView.pauseRendering();

// If the video is playing when onPause() is called, the default behavior will be to pause

// the video and keep it paused when onResume() is called.

isPlaying = false;

}

@Override

protected void onResume() {

super.onResume();

// Resume the 3D rendering.

mVideoView.resumeRendering();

}

@Override

protected void onDestroy() {

//https://developers.google.com/vr/android/reference/com/google/vr/sdk/widgets/common/VrWidgetView#shutdown()

mVideoView.shutdown();

super.onDestroy();

}

/**

  • 播放器进度条监听

*/

private class SeekBarListener implements SeekBar.OnSeekBarChangeListener {

@Override

public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {

if (fromUser) {

mVideoView.seekTo(progress);

}

}

@Override

public void onStartTrackingTouch(SeekBar seekBar) {

}

@Override

public void onStopTrackingTouch(SeekBar seekBar) {

//手指离开进度条,三秒钟后隐藏控制面板

}

}

}

由于代码逻辑都比较简单,也都有注释,这里不再做过多的阐述。

下面介绍一下如何去除VR模式下界面上google自带的退出按钮和设置按钮。

集成过google vr或者玩过google vr sdk中提供的sample工程的童鞋都见过下面的两个按钮,在VR模式下,这两个按钮分别在页面的左上角和右上角。

去除方式多种多样,这里介绍比较简单实用的一种

在自己项目res/values/style.xml文件中添加如下样式:

那么中间的竖线如何去掉呢?

在自己项目的res/values/values.xml文件中添加如下代码:

0mm

0dip

112dip

效果如下:

为什么我们写一个style属性就能去掉返回和设置按钮呢?

查找源码发现com.google.vr:sdk-base1.10.0中layout文件夹下面有几个布局文件

back_button.xml

<?xml version="1.0" encoding="utf-8"?>

<ImageButton xmlns:android=“http://schemas.android.com/apk/res/android”

style=“@style/UiButton”

android:src=“@drawable/quantum_ic_close_white_24”

android:layout_alignParentRight=“true”

android:layout_alignParentTop=“true”/>

settings_button.xml

<?xml version="1.0" encoding="utf-8"?>

<ImageButton xmlns:android=“http://schemas.android.com/apk/res/android”

style=“@style/UiButton”

android:src=“@drawable/quantum_ic_settings_white_24”

android:contentDescription=“@string/settings_button_content_description”

android:layout_alignParentRight=“true”

android:layout_alignParentBottom=“true”/>

这两个布局分别是返回键和设置按钮的布局文件,它们都共用同一个style样式:UiButton

ui_layer_with_portrait_support.xml

<?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”>

<RelativeLayout

android:id=“@+id/ui_alignment_marker”

android:layout_height=“@dimen/alignment_marker_thickness”

android:layout_width=“@dimen/alignment_marker_height”

android:layout_centerVertical=“true”

android:layout_alignParentLeft=“true”

android:background=“@color/alignment_marker_color”>

这个布局文件是VR模式下GVR控制面板的布局(一个返回按钮、一个设置按钮、中间竖线)

中间竖线的宽高分别是alignment_marker_height和alignment_marker_thickness,这就是我们在values.xml文件中把它们俩都写为0的原因。

自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。

深知大多数Go语言工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!

因此收集整理了一份《2024年Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
img
img
img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
img

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

Go语言全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。**
[外链图片转存中…(img-xuspI7dG-1712874273284)]
[外链图片转存中…(img-lrxYQxsy-1712874273285)]
[外链图片转存中…(img-UpEoBBlQ-1712874273285)]
[外链图片转存中…(img-Vt461SP6-1712874273286)]
[外链图片转存中…(img-0cCQIC92-1712874273286)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Golang知识点,真正体系化!

由于文件比较大,这里只是将部分目录大纲截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且后续会持续更新

如果你觉得这些内容对你有帮助,可以添加V获取:vip1024b (备注Go)
[外链图片转存中…(img-aGzE5p95-1712874273287)]

一个人可以走的很快,但一群人才能走的更远。不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎扫码加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

  • 23
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值