视频播放器

这里写图片描述

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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:orientation="vertical">

    <SurfaceView
        android:id="@+id/sv"
        android:layout_width="match_parent"
        android:layout_height="300dp" />

    <SeekBar
        android:id="@+id/seekbar"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <TextView
        android:id="@+id/time"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="right"
        android:text="00:00/00:00"/>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

        <Button
            android:id="@+id/play"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="播放"/>

        <Button
            android:id="@+id/pause"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="暂停"/>

        <Button
            android:id="@+id/stop"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="停止"/>

        <Button
            android:id="@+id/replay"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="重播"/>

    </LinearLayout>

</LinearLayout>

MainActivity.class

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    /**SurfaceView内部采用双缓存机制,它会缓存视频中的流数据,将数据进行渲染之后推送到屏幕上做显示。
       简单来讲,他就是一个显示视频的屏幕。*/
    private SurfaceView sv;
    private SurfaceHolder holder;
    private SeekBar seekbar;
    private MediaPlayer player;
    private TextView time;
    private Button play;
    private Button pause;
    private Button stop;
    private Button replay;
    private int duration;
    private boolean isUpdateBar;
    // 获取视频路径
    String path = Environment.getExternalStorageDirectory() + "/Movies/Uptown Funk.mp4";

    // 播放器的几个状态,我们可以通过状态码来判断
    public static final int PLAYING = 1; // 播放状态
    public static final int PAUSING = 2; // 暂停状态
    public static final int STOPPING = 3; // 停止状态
    private int CURRENT = 0; // 当前状态

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        sv = findViewById(R.id.sv);
        seekbar = findViewById(R.id.seekbar);
        play = findViewById(R.id.play);
        pause = findViewById(R.id.pause);
        stop = findViewById(R.id.stop);
        replay = findViewById(R.id.replay);
        time = findViewById(R.id.time);

        play.setOnClickListener(this);
        pause.setOnClickListener(this);
        stop.setOnClickListener(this);
        replay.setOnClickListener(this);

        holder = sv.getHolder();
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); // 设置缓冲

        seekbar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int i, boolean b) {

            }

            @Override
            public void onStartTrackingTouch(SeekBar seekBar) {
                //开始拖动seekbar的时候停止更新seekbar
                stopSeekBar();

            }

            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                //停止拖动seekbar的时候定位到相应的位置,并且开始更新seekbar
                if(player != null) {
                   if(CURRENT == PLAYING) {
                       player.seekTo(seekBar.getProgress());
                       updateSeekBar();
                   }
                }

            }
        });

    }

    @Override
    public void onClick(View view) {
        switch (view.getId()){
            case R.id.play:
                try {

                    if (player != null) {
                        if (CURRENT == PLAYING) { //当前是播放状态
                            return;
                        } else if (CURRENT == PAUSING) { // 当前是暂停状态
                            player.seekTo(seekbar.getProgress());
                            player.start();
                            CURRENT = PLAYING;
                            updateSeekBar();
                            return;
                        }
                    }

                    if (CURRENT == 0 || CURRENT == STOPPING) { //如果是最开始的状态或者是停止状态
                        // 创建一个播放器对象
                        player = new MediaPlayer();
                        // 设置路径
                        player.setDataSource(path);
                        // 准备
                        player.prepare();
                        // 获取视频最大的时长(毫秒为单位)
                        duration = player.getDuration();
                        // 设置seekBar的最大值
                        seekbar.setMax(duration);
                        // 格式化最大时间
                        String lastTime = formatTime(duration);
                        time.setText("00:00/" + lastTime);
                        player.seekTo(seekbar.getProgress());
                        // 视频开始播放
                        player.start();
                        // 更新seekBar
                        updateSeekBar();
                        // 设置输出画面
                        player.setDisplay(holder);
                        CURRENT = PLAYING;
                    }
                } catch(IOException e){
                    e.printStackTrace();
                }

                break;
            case R.id.pause: // 暂停
                if(player != null && CURRENT == PLAYING) {
                    player.pause();
                    stopSeekBar();
                    CURRENT = PAUSING;
                }
                break;
            case R.id.stop: // 停止播放
                if(player != null) {
                    if(CURRENT == PLAYING || CURRENT == PAUSING) {
                        stopSeekBar();
                        seekbar.setProgress(0);
                        time.setText("00:00/"+formatTime(duration));
                        player.stop(); // 播放器处于停止状态 所有设置都清零
                        player.release(); // 释放资源
                        CURRENT = STOPPING;
                    }
                }
                break;
            case R.id.replay: // 重播
                if(player != null) {
                    try{
                        player.reset(); // 播放器空闲状态 要想播放必须重新设置路径还要进入准备状态
                        player.setDataSource(path);
                        player.prepare(); // 准备状态
                        player.start();
                        CURRENT = PLAYING;
                    }catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                break;
                default:
                    break;
        }
    }

    //更新进度条
    private void updateSeekBar(){
        isUpdateBar = true;
        new Thread(new Runnable() {
            @Override
            public void run() {
                while(isUpdateBar) {
                    // 每秒更新一次
                    SystemClock.sleep(1000);
                    if(player != null && CURRENT == PLAYING){
                        seekbar.setProgress(player.getCurrentPosition());
                        // 在主线程中更新UI
                        runOnUiThread(new Runnable() {
                            @Override
                            public void run() {
                                String current = formatTime(player.getCurrentPosition()); // 播放进度
                                String durationString = formatTime(duration); // 最大时间
                                time.setText(current + "/" + durationString);
                            }
                        });
                    }
                }
            }
        }).start();
    }

    private String formatTime(int duration) {
        int second = duration / 1000; // 先转换成总秒数 270s
        int minute = second / 60; // 在转换成总分钟 4
        second = second - minute * 60; // 转换成秒位置上的秒数 30s
        StringBuilder sb = new StringBuilder();
        sb.append(minute > 10 ? minute + "" : "0" + minute); // 04
        sb.append(":");
        sb.append(second > 10 ? second + "" : "0" + second);// 04:30
        return  sb.toString();
    }

    private void stopSeekBar(){
        isUpdateBar = false;
    }
}

媒体控制器
这里写图片描述

MainActivity.class

public class MainActivity extends AppCompatActivity {
    /**videoView播放器*/
    private VideoView mVideoView;
    /**媒体控制器*/
    private MediaController mController;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // 设置窗口格式为半透明
        getWindow().setFormat(PixelFormat.TRANSLUCENT);
        setContentView(R.layout.activity_main);
        // 绑定videoView控件
        mVideoView = findViewById(R.id.video_view);
        // 创建MediaController对象
        mController = new MediaController(this);
        // 准备播放文件
        File video = new File(Environment.getExternalStorageDirectory()+"/Movies/小城大事-张学友.mp4");
        // 如果文件存在
        if(video.exists()) {
            mVideoView.setVideoPath(video.getPath());
            // 设置VideoView与Controller建立关联
            mVideoView.setMediaController(mController);
            // 设置controller和videoView建立关联
            mController.setMediaPlayer(mVideoView);
            //让VideoView获取焦点
            mVideoView.requestFocus();
        }
    }
}

猜你喜欢

转载自blog.csdn.net/qq_39981500/article/details/78892243