美文网首页
Android播放视频--VideoView

Android播放视频--VideoView

作者: 颤抖的闪电 | 来源:发表于2018-07-09 10:47 被阅读0次

    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

    <?xml version="1.0" encoding="utf-8"?>
    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <VideoView
            android:id="@+id/video_content"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:background="@drawable/zuji_last_video_bg"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />
    
        <!--<ImageView
            android:id="@+id/img_video_cover"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            android:src="@drawable/zuji_last_video_bg"
            app:layout_constraintBottom_toBottomOf="@+id/video_content"
            app:layout_constraintEnd_toEndOf="@+id/video_content"
            app:layout_constraintStart_toStartOf="@+id/video_content"
            app:layout_constraintTop_toTopOf="@+id/video_content" />-->
    
        <ImageView
            android:id="@+id/img_video_player_icon"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:src="@drawable/zuji_guide_player_icon"
            app:layout_constraintBottom_toBottomOf="@+id/video_content"
            app:layout_constraintEnd_toEndOf="@+id/video_content"
            app:layout_constraintStart_toStartOf="@+id/video_content"
            app:layout_constraintTop_toTopOf="@+id/video_content" />
    </android.support.constraint.ConstraintLayout>
    

    直接调用

    <android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
        xmlns:app="http://schemas.android.com/apk/res-auto"
        xmlns:tools="http://schemas.android.com/tools"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:background="@android:color/transparent">
    
        <com.zuji.entrance.widget.MainPageVideoView
            android:id="@+id/video_main_page"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            app:layout_constraintBottom_toBottomOf="parent"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent"
            app:layout_constraintVertical_bias="0.0" />
    </android.support.constraint.ConstraintLayout>
    

    解决播放黑屏:
    要解决这个问题,需要等到视频真正开始渲染后再去掉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

          本文链接:https://www.haomeiwen.com/subject/evcbuftx.html