美文网首页
ExoPlayer的简单封装和使用

ExoPlayer的简单封装和使用

作者: leo567 | 来源:发表于2018-10-22 10:22 被阅读471次

ExoPlayer介绍:

https://google.github.io/ExoPlayer/supported-formats.html

https://codelabs.developers.google.com/codelabs/exoplayer-intro/#0

https://blog.csdn.net/hejjunlin/article/details/54693696

截图

1.jpg 2.jpg

对PlayerView的封装

import android.annotation.SuppressLint;
import android.content.Context;
import android.media.session.PlaybackState;
import android.net.Uri;
import android.os.Handler;
import android.util.AttributeSet;
import android.view.View;
import com.google.android.exoplayer2.ExoPlayer;
import com.google.android.exoplayer2.ExoPlayerFactory;
import com.google.android.exoplayer2.Player;
import com.google.android.exoplayer2.source.ExtractorMediaSource;
import com.google.android.exoplayer2.source.MediaSource;
import com.google.android.exoplayer2.ui.PlayerView;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DefaultDataSourceFactory;
import com.google.android.exoplayer2.util.Util;
import static com.google.android.exoplayer2.Player.REPEAT_MODE_ALL;
import static com.google.android.exoplayer2.ui.AspectRatioFrameLayout.RESIZE_MODE_FILL;

/**
 * @author: fanrunqi
 * @date: 2018/10/19 16:20
 */
public class TheExoPlayer extends PlayerView {

    private ExoPlayer player;
    private boolean isPlay;
    private OnStateListener onStateListener;
    private boolean isLoopProgress = true;
    private boolean isPause;
    private Player.EventListener eventListener;

    public TheExoPlayer(Context context) {
        this(context, null);
    }

    public TheExoPlayer(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public TheExoPlayer(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }

    private void init() {
        setResizeMode(RESIZE_MODE_FILL);
        setUseController(false);

        player = ExoPlayerFactory.newSimpleInstance(getContext());
        setPlayer(player);
        player.addListener(eventListener=new Player.EventListener() {
            @Override
            public void onLoadingChanged(boolean isLoading) {
                if (onStateListener != null) {
                    onStateListener.onLoadingChanged(isLoading);
                }
            }
            @Override
            public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
                if (playbackState == PlaybackState.STATE_PLAYING) {
                    if (onStateListener != null) {
                        onStateListener.onPlayPrepare();
                        handler.postDelayed(task, 1000);
                    }
                }
            }
        });
    }

    public void initialization(String applicationName, String videoUrl) {
        DataSource.Factory dataSourceFactory = new DefaultDataSourceFactory(getContext(),
                Util.getUserAgent(getContext(), applicationName));
        MediaSource videoSource = new ExtractorMediaSource.Factory(dataSourceFactory)
                .createMediaSource(Uri.parse(videoUrl));
        player.prepare(videoSource);
        player.setRepeatMode(REPEAT_MODE_ALL);
    }

    @Override
    public void onResume() {
        super.onResume();
        hideSystemUi();
        if(isPause){
            isPause=false;
            play();
        }
    }

    public void onPause() {
        if (isPlay) {
            isPause=true;
            player.setPlayWhenReady(false);
            isPlay = false;
        }
    }

    public void onDestroy() {
        isLoopProgress = false;
        if(null!=eventListener){
            player.removeListener(eventListener);
        }
        if (player != null) {
            player.release();
            player = null;
        }
    }

    public void play() {
        if (!isPlay) {
            player.setPlayWhenReady(true);
            isPlay = true;
        }
    }

    public void pause() {
        if (isPlay) {
            player.setPlayWhenReady(false);
            isPlay = false;
        }
    }

    public void seekTo(int progress) {
        if (player != null) {
            player.seekTo(progress * 1000);
        }
    }

    public boolean isPlaying() {
        return isPlay;
    }

    public String getCurrentTime() {
        return secToTime((int) (player.getCurrentPosition() / 1000));
    }

    public String getVideoTotalTime() {
        return secToTime(getVideoTotalSeconds());
    }

    public int getBufferedProgress() {
        return (int) (player.getBufferedPosition() / 1000);
    }

    public int getCurrentProgress() {
        return (int) (player.getCurrentPosition() / 1000);
    }

    public int getVideoTotalSeconds() {
        return (int) (player.getContentDuration() / 1000);
    }

    public String secToTime(int time) {
        int day;
        int hour;
        int minute;
        int second;
        if (time <= 0) {
            return "00:00";
        } else {
            minute = time / 60;
            if (minute < 60) {
                second = time % 60;
                return unitFormat(minute) + ":" + unitFormat(second) + "";
            }

            hour = minute / 60;
            if (hour < 24) {
                minute = minute % 60;
                second = time - hour * 3600 - minute * 60;
                return unitFormat(hour) + ":" + unitFormat(minute) + ":" + unitFormat(second) + ":";
            }

            day = hour / 24;
            hour = hour % 24;
            minute = minute - day * 24 * 60 - hour * 60;
            return unitFormat(day) + "天" + unitFormat(hour) + "小时" + unitFormat(minute) + "分钟";
        }
    }

    private String unitFormat(int i) {
        String retStr;
        if (i >= 0 && i < 10)
            retStr = "0" + Integer.toString(i);
        else
            retStr = "" + i;
        return retStr;
    }

    private Handler handler = new Handler();
    private Runnable task = new Runnable() {
        public void run() {
            if (player != null) {
                onStateListener.onProgressChanged(getCurrentProgress());
            }
            if (isLoopProgress) {
                handler.postDelayed(this, 1000);
            }
        }
    };

    @SuppressLint("InlinedApi")
    private void hideSystemUi() {
        setSystemUiVisibility(View.SYSTEM_UI_FLAG_LOW_PROFILE
                | View.SYSTEM_UI_FLAG_FULLSCREEN
                | View.SYSTEM_UI_FLAG_LAYOUT_STABLE
                | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
                | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
                | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);
    }

    public void setOnStateListener(OnStateListener listener) {
        onStateListener = listener;
    }

    public interface OnStateListener {
        void onLoadingChanged(boolean isLoading);

        void onPlayPrepare();

        void onProgressChanged(int progress);
    }
}

对TheExoPlayer的使用

import android.content.Context;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.SeekBar;
import android.widget.TextView;
import cn.leo.androidvideoplayer.R;

/**
 * @author: fanrunqi
 * @date: 2018/10/19 19:30
 */
public class TheExoPlayerUse extends RelativeLayout {
    TheExoPlayer playerView;
    TextView begin,end;
    SeekBar seekBar;
    ImageView play_pause;

    public TheExoPlayerUse(Context context) {
        this(context, null);
        init();
    }

    public TheExoPlayerUse(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
        init();
    }

    public TheExoPlayerUse(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
       init();
    }

    private void init() {
        LayoutInflater from = LayoutInflater.from(getContext());
        View view = from.inflate(R.layout.e_video_view, null);
        RelativeLayout.LayoutParams rlp = new RelativeLayout.LayoutParams(
                RelativeLayout.LayoutParams.MATCH_PARENT,
                RelativeLayout.LayoutParams.MATCH_PARENT);
        view.setLayoutParams(rlp);

        playerView = view.findViewById(R.id.video_view);
        begin = view.findViewById(R.id.tv_begin);
        end = view.findViewById(R.id.tv_end);
        seekBar = view.findViewById(R.id.seekBar);
        play_pause = view.findViewById(R.id.play_pause);

        playerView.setOnStateListener(new TheExoPlayer.OnStateListener() {
            @Override
            public void onLoadingChanged(boolean isLoading) {
                seekBar.setSecondaryProgress(playerView.getBufferedProgress());
            }

            @Override
            public void onPlayPrepare() {
                initPlayVideo();
            }

            @Override
            public void onProgressChanged(int progress) {
                begin.setText(playerView.getCurrentTime());
                seekBar.setProgress(progress);
            }
        });

        addView(view);
    }

    public void load(String applicationName, String videoUrl) {
        playerView.initialization(applicationName,videoUrl);
    }

    private void initPlayVideo() {
        play_pause.setOnClickListener(v -> {
            if(playerView.isPlaying()){
                playerView.pause();
                play_pause.setBackgroundResource(R.drawable.play);
            }else {
                playerView.play();
                play_pause.setBackground(null);
            }
        });

        end.setText(playerView.getVideoTotalTime());
        seekBar.setMax(playerView.getVideoTotalSeconds());
        seekBar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
            @Override
            public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) { }
            @Override
            public void onStartTrackingTouch(SeekBar seekBar) { }
            @Override
            public void onStopTrackingTouch(SeekBar seekBar) {
                playerView.play();
                playerView.seekTo(seekBar.getProgress());
                play_pause.setBackground(null);
            }
        });
    }

    public void onResume() {
        playerView.onResume();
    }

    public void onPause() {
        playerView.onPause();
    }

    public void onDestroy() {
        playerView.onDestroy();
    }
}

布局:

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

    <cn.leo.androidvideoplayer.lib.TheExoPlayer
        android:id="@+id/video_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        />

    <ImageView
        android:background="@drawable/play"
        android:id="@+id/play_pause"
        android:layout_width="100dp"
        android:layout_height="100dp"
        android:layout_marginStart="8dp"
        android:layout_marginTop="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="8dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/tv_begin"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginStart="16dp"
        android:layout_marginBottom="16dp"
        android:text="00:00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintStart_toStartOf="parent" />

    <SeekBar
        android:id="@+id/seekBar"
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginStart="8dp"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="16dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toStartOf="@+id/tv_end"
        app:layout_constraintStart_toEndOf="@+id/tv_begin" />


    <TextView
        android:id="@+id/tv_end"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_marginEnd="8dp"
        android:layout_marginBottom="16dp"
        android:text="05:00"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent" />
</android.support.constraint.ConstraintLayout>

主界面


import android.content.Intent;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import cn.leo.androidvideoplayer.lib.TheExoPlayerUse;

public class MainActivity extends AppCompatActivity {
    TheExoPlayerUse theExoPlayerUse;
    String url = "https://media.w3.org/2010/05/sintel/trailer.mp4";

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

        findViewById(R.id.button).setOnClickListener(v ->
                startActivity(new Intent(MainActivity.this, SecondActivity.class)));

        theExoPlayerUse = findViewById(R.id.eVideoView);
        theExoPlayerUse.load("AndroidVideoPlayer", url);
    }

    @Override
    protected void onResume() {
        super.onResume();
        theExoPlayerUse.onResume();
    }

    @Override
    protected void onPause() {
        super.onPause();
        theExoPlayerUse.onPause();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        theExoPlayerUse.onDestroy();
    }
}

demo下载:https://download.csdn.net/download/amazing7/10736089

相关文章

网友评论

      本文标题:ExoPlayer的简单封装和使用

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