VideoView plus controlador personalizado para reproducir video

Creo que aquellos que hacen desarrollo de Android generalmente han reproducido videos web. Todos generalmente usan VideoView para reproducir videos web, y también hay un controlador para controlar la pausa o el avance rápido del video. Pero el estilo de Controller no se puede cambiar para que sea particularmente feo. No puedo cumplir con la experiencia de IU de gama alta.

Complete un controlador de reproducción personalizado y una sencilla función de cambio de pantalla horizontal y vertical. Probablemente registre el proceso:

1. Personalice MyVideoView para resolver el problema que puede no cubrir toda la pantalla y causar bordes en blanco.

public class MyVideoView extends VideoView {
    public MyVideoView(Context context, AttributeSet attrs) {
        super(context, attrs);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        int width = getDefaultSize(0,widthMeasureSpec);
        int height = getDefaultSize(0,heightMeasureSpec);
        setMeasuredDimension(width,height);
    }
}

2. Coloque VideoView y Controller en un archivo xml en un diseño.

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <RelativeLayout
        android:id="@+id/rl_content"
        android:layout_width="match_parent"
        android:layout_height="200dp">
        <!-- 播放视频的VideoView -->
        <com.teach.myapplication.MyVideoView
            android:id="@+id/videoView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
        <!-- 控制器 -->
        <RelativeLayout
            android:id="@+id/rl"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true">
            <!-- 自定义样式后的SeekBar进度条 -->
            <SeekBar
                android:id="@+id/sb"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_above="@+id/ll"
                android:maxHeight="4dp"
                android:minHeight="4dp"
                android:paddingLeft="16dp"
                android:paddingRight="16dp"
                android:progressDrawable="@drawable/seekbar_shape"
                android:thumb="@mipmap/icon_seekbar_button"
                android:thumbOffset="20dp" />

            <LinearLayout
                android:paddingBottom="3dp"
                android:id="@+id/ll"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentBottom="true"
                android:layout_marginLeft="16dp"
                android:orientation="horizontal">
                <!-- 当前播放位置 -->
                <TextView
                    android:id="@+id/tv_process_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="00:00"
                    android:textColor="#0E83F8"
                    android:textSize="13sp" />

                <TextView
                    android:id="@+id/tv"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="/"
                    android:textColor="#FFFFFF"
                    android:textSize="13sp" />
                <!-- 视频总时长 -->
                <TextView
                    android:id="@+id/tv_all_date"
                    android:layout_width="wrap_content"
                    android:layout_height="wrap_content"
                    android:text="00:00"
                    android:textColor="#FFFFFF"
                    android:textSize="13sp" />
            </LinearLayout>
            <!-- 全屏按钮 -->
            <ImageView
                android:paddingBottom="3dp"
                android:id="@+id/iv_full_screen"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_alignParentRight="true"
                android:layout_alignParentBottom="true"
                android:layout_marginRight="16dp"
                android:src="@mipmap/icon_quanping" />
            <!-- 播放暂停按钮 -->
            <ImageView
                android:id="@+id/iv_play_or_pause"
                android:layout_width="wrap_content"
                android:layout_height="wrap_content"
                android:layout_above="@+id/sb"
                android:layout_centerHorizontal="true"
                android:src="@mipmap/icon_dianbo_play" />
        </RelativeLayout>

    </RelativeLayout>
</RelativeLayout>

3. MediaView personalizado

/**
 * 自定义的视频播放器
 */
public class MediaView extends FrameLayout implements SeekBar.OnSeekBarChangeListener, View.OnClickListener, MediaPlayer.OnPreparedListener, View.OnTouchListener {
    /**
     * 视频播放VideoView
     */
    private MyVideoView videoView;
    /**
     * 进度SeekBar
     */
    private SeekBar sb;
    /**
     * 播放总时长 和当前播放时长
     */
    private TextView tv_process_date, tv_all_date;
    /**
     * 全屏播放按钮
     */
    private ImageView iv_full_screen;
    /**
     * 播放或者暂停按钮
     */
    private ImageView iv_play_or_pause;
    /**
     * 播放控制器
     */
    private RelativeLayout rl, rl_content;
    /**
     * 是否正在播放视频
     */
    private boolean playing;
    /**
     * 当前播放至的进度
     */
    private int progress;
    /**
     * 时间定时器
     */
    private Timer timer;
    private TimerTask task;
    private Handler handler;
    /**
     * 是否展示控制器
     */
    private boolean showIng;
    private Context context;
    private boolean isFullScreen;
    private int mHeight;

    public MediaView(@NonNull Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        this.context = context;
        View view = LayoutInflater.from(context).inflate(R.layout.my_mediacontroller_layout, this, true);
        videoView = view.findViewById(R.id.videoView);
        sb = view.findViewById(R.id.sb);
        sb.setOnSeekBarChangeListener(this);
        tv_process_date = view.findViewById(R.id.tv_process_date);
        tv_all_date = view.findViewById(R.id.tv_all_date);
        iv_full_screen = view.findViewById(R.id.iv_full_screen);
        iv_full_screen.setOnClickListener(this);
        iv_play_or_pause = view.findViewById(R.id.iv_play_or_pause);
        iv_play_or_pause.setOnClickListener(this);
        rl = view.findViewById(R.id.rl);
        rl_content = view.findViewById(R.id.rl_content);
        videoView.setOnTouchListener(this);
        handler = new Handler() {
            @Override
            public void handleMessage(Message msg) {
                if (msg.what == 1) {
                    //do something
                    sb.setProgress(videoView.getCurrentPosition());
                    tv_process_date.setText(DateFormatUtils.getDateFormat(videoView.getCurrentPosition()));
                } else if (msg.what == 2) {
                    rl.setVisibility(View.GONE);
                    showIng = false;
                }
                super.handleMessage(msg);
            }
        };
    }

    /**
     * 播放器准备
     *
     * @param url
     */
    public void start(String url) {
        videoView.setVideoPath(url);
        videoView.setOnPreparedListener(this);
    }

    /**
     * 播放
     */
    public void play() {
        videoView.seekTo(videoView.getCurrentPosition());
        playing = true;
        videoView.start();
        Log.e("lee", "播放的时候" + DateFormatUtils.getDateFormat(videoView.getCurrentPosition()));
        Log.e("lee", "播放的时候" + videoView.getCurrentPosition());
        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 1;
                handler.sendMessage(message);
            }
        };
        timer.schedule(task, 0, 1000);
        handler.postDelayed(new Runnable() {
            @Override
            public void run() {
                Message message = new Message();
                message.what = 2;
                handler.sendMessage(message);
            }
        }, 5000);
        iv_play_or_pause.setImageResource(R.mipmap.icon_dianbo_pause);
    }

    /**
     * 暂停
     */
    public void pause() {
        videoView.pause();
        Log.e("lee", "暂停的时候" + DateFormatUtils.getDateFormat(videoView.getCurrentPosition()));
        Log.e("lee", "暂停的时候" + videoView.getCurrentPosition());
        timer.cancel();
    }

    /**
     * seekbar监听器
     */
    @Override
    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
        tv_process_date.setText(DateFormatUtils.getDateFormat(progress));
    }

    @Override
    public void onStartTrackingTouch(SeekBar seekBar) {
        videoView.pause();
    }

    @Override
    public void onStopTrackingTouch(SeekBar seekBar) {
        videoView.seekTo(seekBar.getProgress());
        videoView.start();
        playing = true;
        iv_play_or_pause.setImageResource(R.mipmap.icon_dianbo_pause);
    }

    /**
     * 点击事件
     *
     * @param v
     */
    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.iv_play_or_pause://播放暂停按钮
                if (playing) {//正在播放 (点击暂停)
                    iv_play_or_pause.setImageResource(R.mipmap.icon_dianbo_play);
                    pause();
                    playing = false;
                } else {//正在暂停 (点击播放)
                    iv_play_or_pause.setImageResource(R.mipmap.icon_dianbo_pause);
                    play();
                    playing = true;
                }
                break;
            case R.id.iv_full_screen:
                if (!isFullScreen) {//竖屏状态(切换成横屏)
                    //首先获得原来的高度
                    mHeight = rl_content.getHeight();
                    //重新制定高度
                    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) rl_content.getLayoutParams();
                    params.height = ViewGroup.LayoutParams.MATCH_PARENT;
                    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
                    ((MainActivity) context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);//显示顶部状态栏
                    ((MainActivity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);
                    ((MainActivity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
                    rl_content.setLayoutParams(params);
                    isFullScreen = true;
                } else {//横屏状态(切换成竖屏)
                    RelativeLayout.LayoutParams params = (RelativeLayout.LayoutParams) rl_content.getLayoutParams();
                    params.height = mHeight;
                    params.width = ViewGroup.LayoutParams.MATCH_PARENT;
                    ((MainActivity) context).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏不 显示顶部状态栏
                    ((MainActivity) context).getWindow().addFlags(WindowManager.LayoutParams.FLAG_FORCE_NOT_FULLSCREEN);
                    ((MainActivity) context).setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
                    rl_content.setLayoutParams(params);
                    isFullScreen = false;
                }
                break;
            default:

                break;
        }
    }

    /**
     * 视频加载成功
     *
     * @param mp
     */
    @Override
    public void onPrepared(MediaPlayer mp) {
        sb.setMax(videoView.getDuration());
        tv_process_date.setText(DateFormatUtils.getDateFormat(videoView.getCurrentPosition()));
        tv_all_date.setText(DateFormatUtils.getDateFormat(videoView.getDuration()));
        //播放
        play();

        /**
         * 视频播放完成监听
         */
        mp.setOnCompletionListener(new MediaPlayer.OnCompletionListener() {
            @Override
            public void onCompletion(MediaPlayer mp) {
                videoView.seekTo(0);
                sb.setProgress(0);
                playing = false;
                rl.setVisibility(View.VISIBLE);
                showIng = true;
                iv_play_or_pause.setImageResource(R.mipmap.icon_dianbo_play);
            }
        });
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("lee", "ACTION_DOWN");
                rl.setVisibility(View.VISIBLE);
                showIng = true;
                if (showIng) {
                    handler.removeMessages(2);
                }
                break;
            case MotionEvent.ACTION_MOVE:
                Log.e("lee", "ACTION_MOVE");
                if (showIng) {
                    handler.removeMessages(2);
                }
                break;
            case MotionEvent.ACTION_UP:
                Log.e("lee", "ACTION_DOWN");
                handler.postDelayed(new Runnable() {
                    @Override
                    public void run() {
                        Message message = new Message();
                        message.what = 2;
                        handler.sendMessage(message);
                    }
                }, 5000);
                break;
            default:
                break;
        }
        return true;
    }
}

4. Llamada externa

Código en actividad

 mediaView = findViewById(R.id.view);
 mediaView.start("http://vfx.mtime.cn/Video/2019/06/26/mp4/190626111517361726.mp4");

código xml

    <com.teach.myapplication.MediaView
        android:id="@+id/view"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

Tenga en cuenta que la actividad debe agregarse en el archivo de manifiesto

android:screenOrientation="portrait"
android:configChanges="orientation|screenSize|keyboardHidden"

5. El estilo de seekbar seekbar_shape.xml

<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
    <item android:id="@android:id/background">
        <shape>
            <corners android:radius="2dp" />
            <solid android:color="#33FFFFFF" />
        </shape>
    </item>

    <item android:id="@android:id/secondaryProgress">
        <clip>
            <shape>
                <corners android:radius="2dp" />
                <solid android:color="#77FFFFFF" />
            </shape>
        </clip>
    </item>

    <item android:id="@android:id/progress">
        <clip>
            <shape>
                <corners android:radius="2dp" />
                <solid android:color="#0E83F8" />
            </shape>
        </clip>
    </item>
</layer-list>

Lo anterior ha completado el controlador de reproducción personalizado simple y simplemente puede cambiar la función de reproducción entre pantallas horizontales y verticales, y los íconos de pausa y reproducción no se cargarán, solo reemplácelos con su propio nombre.

Supongo que te gusta

Origin blog.csdn.net/qq77485042/article/details/105840471
Recomendado
Clasificación