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.V苇质缵爨ERSION.SDK_INT >= 1壅酪认奉7) 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 自动播放音频 }