需求:
开发过程中,有个功能像是全屏循环播放视频,音频用户可选择取消,后台音视频分别给了不同的url。
效果:(用的在线MP4转gif工具,好模糊呀)
实现过程:
因为之间用的GSYVideoPlayer,想着用它实现,写好之后发现找不到隐藏SeekBar啥的方法,换(如果有人知道可以告诉一下,谢谢啦),然后准备播放和关闭音乐用控制系统静音控制,也没实现得了。因为音视频是给的不同的url,用的原生VideoView+MediaPlayer所以实现起来还算不麻烦的,就是有时脑壳短路。
1.全屏播放视频(自定义)
/**
* 视频播放,主要是因为手机的大小很多,不能保证原生的VideoView能实现全屏
*/
public class FullVideoView extends VideoView {
public FullVideoView(Context context) {
super(context);
}
public FullVideoView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public FullVideoView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
//我们重新计算高度
int width = getDefaultSize(0, widthMeasureSpec);
int height = getDefaultSize(0, heightMeasureSpec);
setMeasuredDimension(width, height);
}
@Override
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l) {
super.setOnPreparedListener(l);
}
@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {
return super.onKeyDown(keyCode, event);
}
}
2.布局(直接把自定义FullVideoView占满全屏就好,ImageView控制音乐)
<?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"
>
<com.dingding.ddmentality.other.view.FullVideoView
android:id="@+id/videoView_videoTip"
android:layout_width="match_parent"
android:layout_height="match_parent" />
<ImageView
android:id="@+id/ivReturn_videoTip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_fanhui_b"
android:layout_marginLeft="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:padding="@dimen/dp_10"
/>
<ImageView
android:id="@+id/ivMusic_videoTip"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@mipmap/ic_yinyue"
android:layout_alignParentRight="true"
android:layout_marginRight="@dimen/dp_20"
android:layout_marginTop="@dimen/dp_20"
android:padding="@dimen/dp_10"
/>
</RelativeLayout>
3.代码实现(原谅我还是用的mvc,实现页面逻辑多,我只留下了跟音视频相关的方法了)
/**
* shen
* 视频倾诉视频引导页 setLayout() addAction() initData()都是BaseActivity在onCreat中的抽象方法。
*/
public class TipVideoActivity extends BaseActivity{
private ImageView ivMusicVideoTip;
private FullVideoView fullVideoView;
private Intent intent;
//请求接口返回的信息
private JudgeStateRsp judgeStateRsp;
//播放音频
private MediaPlayer mMediaPlayer;
//控制进入页面是否播放音乐,为true播放,为false下面playMusic()方法先不要播放音乐
private boolean isMusicStart = true;
//用于判断是否第一次播放完视频
private boolean isFrist;
@Override
protected void setLayout() {
setContentView(R.layout.activity_video_tip);
}
@Override
protected void addAction() {
isFrist = true;
fullVideoView = (FullVideoView) findViewById(R.id.videoView_videoTip);
ivMusicVideoTip = (ImageView) findViewById(R.id.ivMusic_videoTip);
intent = new Intent();
initClickListener();
}
/**
* 点击事件
*/
private void initClickListener() {
throttleFirst(ivMusicVideoTip).subscribe(v -> {
setMusicIcon();
});
}
//点击音按钮
private void setMusicIcon() {
//这里控制音乐播放与暂停
if(isMusicStart){
ivMusicVideoTip.setImageResource(R.mipmap.ic_yinyue_2);
mMediaPlayer.pause();
isMusicStart = false;
}else {
ivMusicVideoTip.setImageResource(R.mipmap.ic_yinyue);
mMediaPlayer.start();
isMusicStart = true;
}
}
private void playMusic(String url) {
// 创建音乐播放
mMediaPlayer = new MediaPlayer();
mMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);// 设置媒体流类型
new Thread(() -> {
try {
mMediaPlayer.reset();
mMediaPlayer.setDataSource(url); // 设置数据源
mMediaPlayer.prepare(); // prepare自动播放
mMediaPlayer.start();
} catch (Exception e) {
e.printStackTrace();
}
}).start();
}
@Override
protected void initData() {
getJudgeMessage();
}
@Override
protected void onStop() {
super.onStop();
if (mMediaPlayer != null) {
mMediaPlayer.stop();
mMediaPlayer.release();
mMediaPlayer = null;
}
}
/**
* 调接口(这里要调后台接口获取音视频url)
*/
private void getJudgeMessage() {
JudgeStateReq req = new JudgeStateReq();
req.setType("1");//判断用户状态
RetrofitClient.getInstance().getApiService().getJudgeState(req)
.compose(resp_filter_without_tips()).subscribe(
rsp -> {
if (rsp.isSuccess()) {
judgeStateRsp = rsp;
//成功后开始播放
initVideoView();
if(mMediaPlayer == null){
playMusic(rsp.getMusicUrl());
}
}
}, err -> {
hideProgress();
showToast(err.getMessage());
}
);
}
private void initVideoView() {
fullVideoView.setVideoPath(judgeStateRsp.getVideoUrl());
//播放
fullVideoView.start();
//实现循环播放
fullVideoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mediaPlayer) {
//判断是否为第一次播放结束,做自己的操作
if(isFrist){
isFrist = !isFrist;
}
//结束后重新开始播放
fullVideoView.start();
}
});
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ButterKnife.bind(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
fullVideoView.stopPlayback();
}
}
问题:
可能是我视频挺长的获取了url后要几秒钟才能开始播放视频。
总结:
这个功能看起来很麻烦,但是实现起来还是挺好实现的,重点是刚开始思路不对,思路对了什么都好说了。