Android播放视频--VideoView

CustomVideoView
--这个自定义view类并不是很重要,就比原生的VideoView多了一步重新计算高度。

import android.content.Context; import android.media.MediaPlayer; import android.util.AttributeSet; import android.view.KeyEvent; import android.widget.VideoView; /** * 视频播放,主要是因为手机的大小很多,不能保证原生的VideoView能实现全屏 * Created by lgl on 16/2/18. */ public class CustomVideoView extends VideoView {public CustomVideoView(Context context) { super(context); }public CustomVideoView(Context context, AttributeSet attrs) { super(context, attrs); }public CustomVideoView(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); } }

感谢:
Android高级控件(四)——VideoView 实现引导页播放视频欢迎效果,超级简单却十分的炫酷
接下来,是我真正在项目中的运用:
MainPageVideoView
package com.zuji.entrance.widget; import android.content.Context; import android.graphics.Color; import android.media.MediaPlayer; import android.net.Uri; import android.support.constraint.ConstraintLayout; import android.util.AttributeSet; import android.view.LayoutInflater; import android.view.View; import android.widget.ImageView; import android.widget.VideoView; import com.zuji.library.R; /** * Created by fangyc on 2018/7/6. */public class MainPageVideoView extends ConstraintLayout { VideoView videoView; ImageView img_player_icon; //ImageView img_cover; public MainPageVideoView(Context context) { this(context, null); }public MainPageVideoView(Context context, AttributeSet attrs) { this(context, attrs, 0); }public MainPageVideoView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); View rootView = LayoutInflater.from(context).inflate(R.layout.zuji_main_page_video_widget, this); initViews(rootView); initEvents(); }private void initViews(View rootView) { videoView = rootView.findViewById(R.id.video_content); videoView.setZOrderMediaOverlay(true); //img_cover = rootView.findViewById(R.id.img_video_cover); img_player_icon = rootView.findViewById(R.id.img_video_player_icon); }private void initEvents() { //解决黑屏 // 这段代码的关键是MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START这个变量, // Android SDK中给出的注释是:这个状态表示展现了用于渲染的第一帧视频, // 也就是这个时候才真正将视频帧展示到了屏幕上。 videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) videoView.setBackgroundColor(Color.TRANSPARENT); return true; } }); } }); //循环播放 videoView.setOnCompletionListener(new MediaPlayer.OnCompletionListener() { @Override public void onCompletion(MediaPlayer mediaPlayer) { stopPlay(); } }); //点击播放 img_player_icon.setOnClickListener(new OnClickListener() { @Override public void onClick(View v) { startPlay(); } }); }public void startPlay() { //videoView.setVisibility(View.VISIBLE); img_player_icon.setVisibility(View.GONE); //设置播放加载路径 videoView.setVideoURI(Uri.parse("android.resource://" + videoView.getContext().getPackageName() + "/" + R.raw.track_guide_video_zh)); //播放 videoView.start(); }public void stopPlay() { img_player_icon.setVisibility(View.VISIBLE); //暂停 videoView.pause(); } }

zuji_main_page_video_widget.xml

直接调用

解决播放黑屏:
要解决这个问题,需要等到视频真正开始渲染后再去掉VideoView 的背景。最终的解决办法是在onPrepared回调中,加添加一个setOnInfoListener的监听,在这个监听中将VideoView的背景清除。具体修改如下:
videoView.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.setOnInfoListener(new MediaPlayer.OnInfoListener() { @Override public boolean onInfo(MediaPlayer mp, int what, int extra) { if (what == MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START) videoView.setBackgroundColor(Color.TRANSPARENT); return true; } });

这段代码的关键是MediaPlayer.MEDIA_INFO_VIDEO_RENDERING_START这个变量,Android SDK中给出的注释是:这个状态表示展现了用于渲染的第一帧视频,也就是这个时候才真正将视频帧展示到了屏幕上。
然而,这个变量是在4.1版本才引入的,4.1之前的版本依然不支持。4.1之前的版本,只能暂时通过方法三来优化。
【Android播放视频--VideoView】感谢:
Android VideoView播放本地视频短暂黑屏的解决方法

    推荐阅读