VideoView 视频播放界面被拉伸
1、项目需要开发视频播放,前期要求简单,所以直接拿videoview用了
运行app就发现问题。不同分辨率下不同size的视频资源会被拉伸,而且未居中
先看效果:

2、查看源码获悉两个方法
public void setOnPreparedListener(MediaPlayer.OnPreparedListener l)
{
mOnPreparedListener = l;
}
//FixMe 这个方法api最低为17,详细代码见最后一个步骤
public void setOnInfoListener(OnInfoListener l)
{
mOnInfoListener = l;
}
这两个方法都可以获取到mediaplayer对象
3、好了,现在进行吐槽式的调整了
已知mediaplayer的方法
public void setOnVideoSizeChangedListener(OnVideoSizeChangedListener listener){ mOnVideoSizeChangedListener = listener;}
不论是在视频初始加载资源时还是在视频状态通知时。
info借口回调中可以写
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START || what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
//FixMe 写这里
}
}
代码如下
videoView.setOnPreparedListener(mp -> {
mp.setOnVideoSizeChangedListener((mp1, width, height) -> {
//FixMe 获取视频资源的宽度
int mVideoWidth = mp1.getVideoWidth();
//FixMe 获取视频资源的高度
int mVideoHeight = mp1.getVideoHeight();
//FixMe 获取屏幕的宽度
DisplayMetrics display = IneedApplication.newInstanse().getResources().getDisplayMetrics();
//FixMe 在资源尺寸可以播放观看时处理
if (mVideoHeight > 0 && mVideoWidth > 0) {
//FixMe 拉伸比例
float scale = (float) mVideoWidth / (float) mVideoHeight;
//FixMe 视频资源拉伸至屏幕宽度,横屏竖屏需结合传感器等特殊处理
mVideoWidth = display.widthPixels;
//FixMe 拉伸VideoView高度
mVideoHeight = (int) (mVideoWidth / scale);//FixMe 设置surfaceview画布大小
videoView.getHolder().setFixedSize(mVideoWidth, mVideoHeight);
//FixMe 重绘VideoView大小,这个方法是在重写VideoView时对外抛出方法
videoView.setMeasure(mVideoWidth,mVideoHeight);
//FixMe 请求调整
videoView.requestLayout(); }});
mp.start();
}
4、VideoView 中
public void setMeasure(int width, int height) {
this.width = width;
this.height = height;
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec)
{
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
// 默认高度,为了自动获取到focus
int width = MeasureSpec.getSize(widthMeasureSpec);
int height = width;
// 这个之前是默认的拉伸图像
if (this.width > 0 && this.height > 0)
{
width = this.width;
height = this.height;
}
setMeasuredDimension(width, height);
}
5、最后
<RelativeLayout
android:id="@+id/widget_empty"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerInParent="true">
<RatioVideoView
android:id="@+id/widget_video_test"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerInParent="true"
android:visibility="visible" />
</RelativeLayout>
需要其他地方为黑色的,最外层加个黑色背景
6、//视频控制
if (videoView != null) {
if(Build.VERSION.SDK_INT >= 17)
videoView.setOnInfoListener((mp, what, extra) -> {
if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START || what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START)
{
if (listener != null) {
// 控制loding状态
listener.onPlayStart(true);
}
}
return true;
});
}
ViewVisiable.setVisiable(videoView, true);
videoView.setOnClickListener(v -> {
playStyle(videoView);
});
try {
// videoView.setOnErrorListener(null);
videoView.setMediaController(new MediaController(view.getContext()));
} catch (Exception e) {
} finally {
videoView.setVideoURI(Uri.parse(S.WEBFILE + "/" + entitys.audioUrl));
}
videoView.setOnPreparedListener(mp -> {
mp.setOnVideoSizeChangedListener((mp1, width, height) -> {
int mVideoWidth = mp1.getVideoWidth();
int mVideoHeight = mp1.getVideoHeight();
DisplayMetrics display = IneedApplication.newInstanse().getResources().getDisplayMetrics();
if (mVideoHeight > 0 && mVideoWidth > 0) {
float scale = (float) mVideoWidth / (float) mVideoHeight;
mVideoWidth = display.widthPixels;
mVideoHeight = (int) (mVideoWidth / scale);
videoView.getHolder().setFixedSize(mVideoWidth, mVideoHeight);
videoView.setMeasure(mVideoWidth,mVideoHeight); videoView.requestLayout();
}
});
mp.start();
if (listener != null) {
//发送通知开始播放,开始loding菊花
listener.onStartMusic(S.WEBFILE + "/" + entitys.audioUrl, videoView); }
if (Build.VERSION.SDK_INT < 17) {
mp.setOnInfoListener((mp1, what, extra) -> { if (what == MediaPlayer.MEDIA_INFO_BUFFERING_START || what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) {
if (listener != null) {
// 控制loding状态,true可以播放,隐藏菊花
listener.onPlayStart(true);
} }
return true;
});
}
if (danmakuView != null && ImplDanmaKu != null) {
ImplDanmaKu.onPrepared(danmakuView);
}
ViewVisiable.setVisiable(widget_god_say_body_music_play, false);
ViewVisiable.setVisiable(widget_god_say_body_imguri, false);
ViewVisiable.setVisiable(widget_scrollTextView_Demo, false);
});
videoView.setOnCompletionListener(mp -> {
videoView.stopPlayback();
if (listener != null) {
listener.onPlayStop();
}
isShowDanmaKu = false;
// danmakuView.callOnClick();
ViewVisiable.setVisiable(widget_god_say_body_imguri, true);
ViewVisiable.setVisiable(widget_god_say_body_music_play, true);
ViewVisiable.setVisiable(widget_scrollTextView_Demo, true)
;//FixMe not wrong and view is null.
});
videoView.requestFocus();
// videoView.setOnClickListener(v -> playStyle(videoView));
}else{
view.postDelayed(() -> startAudioShow(entitys, widget_god_say_body_music_play, danmakuView), 200l);//ToDo 自动播放音频
}