前言:
又是客户反馈,说他的 某为 手机录制的视频播放不了。
我叼,我用的是Intent拉起系统播放器还能播不了?
在让客户录视频演示了一波后,还真TM播不了。可以看到拉起系统播放器后闪退了。我叼,什么操作?
我又试了试某米,某O,某V,都没问题啊。
得,这下傻眼了。
初步怀疑,是播放器的问题。至于到底是不是系统播放器的问题,这里先不深入探究了,你系统爱闪退就闪退吧,反正我不用了。我直接内置个播放页面就好了。
先看一下最终效果。
可以看到,有返回值,进度条。文件名,基本播放,暂停。快进等已近可以基本满足。
<!--布局中的控件-->
<VideoView
android:id="@+id/vv_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true" />
基本使用步骤
获取控件
VideoView vvMain;
vvMain = findViewById(R.id.vv_main);
//设置播放目标uri
vvMain.setVideoURI(Uri);
//播放模块控制器,如暂停,快进等。
vvMain.setMediaController(new MediaController(this));
视频文件加载成功的回调
vvMain.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
@Override
public void onPrepared(MediaPlayer mp) {
//这里 我是在加载成功后 开始播放视频
vvMain.start();
}
});
视频播放完毕的回调
vvMain.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer mp) {
//这里我是在播放完成后 关闭页面 当然你可以做自己的处理
finish();
}
});
发生异常的回调,包括加载异常,播放异常等。
vvMain.setOnErrorListener(new MediaPlayer.OnErrorListener() {
@Override
public boolean onError(MediaPlayer mp, int what, int extra) {
//如果加载失败,或者VideoView发送任何错误,会回调到此方法。
//这里我选择 拉起系统播放器。你也可以给出相应提示或者相关处理。
Intent mIntent = new Intent(Intent.ACTION_VIEW);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
mIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
} else {
mIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
mIntent.setDataAndType(uri, "video/*");
startActivity(mIntent);
finish();
return false;
}
}
自定义MediaController
由于默认的MediaController是在显示进度条3秒后会自动隐藏,和我的需求不符。所以选择自定义MediaController来实现点一下显示,再点一下隐藏的操作。
class MyMediaController extends MediaController {
public MyMediaController(Context context) {
super(context);
}
@Override
public void show(int timeout) {
//这里 填入0 表示 一直显示
//否则默认为3秒后会自动隐藏
super.show(0);
}
@Override
public void show() {
super.show();
}
@Override
public void hide() {
super.hide();
}
}
至此,一个基本可用的本地播放器已经实现。
关于Uri的转换和7.0以上FileProvider的使用,请参考这篇博客。