123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454 |
- package com.yc.kernel.impl.exo;
- import android.app.Application;
- import android.content.Context;
- import android.content.res.AssetFileDescriptor;
- import android.os.Handler;
- import android.view.Surface;
- import android.view.SurfaceHolder;
- import com.google.android.exoplayer2.DefaultLoadControl;
- import com.google.android.exoplayer2.DefaultRenderersFactory;
- import com.google.android.exoplayer2.ExoPlaybackException;
- import com.google.android.exoplayer2.LoadControl;
- import com.google.android.exoplayer2.PlaybackParameters;
- import com.google.android.exoplayer2.Player;
- import com.google.android.exoplayer2.RenderersFactory;
- import com.google.android.exoplayer2.SimpleExoPlayer;
- import com.google.android.exoplayer2.analytics.AnalyticsCollector;
- import com.google.android.exoplayer2.source.MediaSource;
- import com.google.android.exoplayer2.source.MediaSourceEventListener;
- import com.google.android.exoplayer2.trackselection.DefaultTrackSelector;
- import com.google.android.exoplayer2.trackselection.MappingTrackSelector;
- import com.google.android.exoplayer2.trackselection.TrackSelector;
- import com.google.android.exoplayer2.upstream.DefaultBandwidthMeter;
- import com.google.android.exoplayer2.util.Clock;
- import com.google.android.exoplayer2.util.EventLogger;
- import com.google.android.exoplayer2.util.Util;
- import com.google.android.exoplayer2.video.VideoListener;
- import com.yc.kernel.inter.AbstractVideoPlayer;
- import com.yc.kernel.utils.PlayerConstant;
- import com.yc.kernel.utils.VideoLogUtils;
- import java.util.Map;
- import static com.google.android.exoplayer2.ExoPlaybackException.TYPE_SOURCE;
- /**
- * <pre>
- * @author yangchong
- * blog : https://github.com/yangchong211
- * time : 2018/11/9
- * desc : exo视频播放器实现类
- * revise:
- * </pre>
- */
- public class ExoMediaPlayer extends AbstractVideoPlayer implements VideoListener, Player.EventListener {
- protected Context mAppContext;
- protected SimpleExoPlayer mInternalPlayer;
- protected MediaSource mMediaSource;
- protected ExoMediaSourceHelper mMediaSourceHelper;
- private PlaybackParameters mSpeedPlaybackParameters;
- private int mLastReportedPlaybackState = Player.STATE_IDLE;
- private boolean mLastReportedPlayWhenReady = false;
- private boolean mIsPreparing;
- private boolean mIsBuffering;
- private LoadControl mLoadControl;
- private RenderersFactory mRenderersFactory;
- private TrackSelector mTrackSelector;
- public ExoMediaPlayer(Context context) {
- if (context instanceof Application){
- mAppContext = context;
- } else {
- mAppContext = context.getApplicationContext();
- }
- mMediaSourceHelper = ExoMediaSourceHelper.getInstance(context);
- }
- @Override
- public void initPlayer() {
- //创建exo播放器
- mInternalPlayer = new SimpleExoPlayer.Builder(
- mAppContext,
- mRenderersFactory == null ? mRenderersFactory = new DefaultRenderersFactory(mAppContext) : mRenderersFactory,
- mTrackSelector == null ? mTrackSelector = new DefaultTrackSelector(mAppContext) : mTrackSelector,
- mLoadControl == null ? mLoadControl = new DefaultLoadControl() : mLoadControl,
- DefaultBandwidthMeter.getSingletonInstance(mAppContext),
- Util.getLooper(),
- new AnalyticsCollector(Clock.DEFAULT),
- /* useLazyPreparation= */ true,
- Clock.DEFAULT)
- .build();
- setOptions();
- //播放器日志
- if (VideoLogUtils.isIsLog() && mTrackSelector instanceof MappingTrackSelector) {
- mInternalPlayer.addAnalyticsListener(new EventLogger((MappingTrackSelector) mTrackSelector, "ExoPlayer"));
- }
- initListener();
- }
- /**
- * exo视频播放器监听listener
- */
- private void initListener() {
- mInternalPlayer.addListener(this);
- mInternalPlayer.addVideoListener(this);
- }
- public void setTrackSelector(TrackSelector trackSelector) {
- mTrackSelector = trackSelector;
- }
- public void setRenderersFactory(RenderersFactory renderersFactory) {
- mRenderersFactory = renderersFactory;
- }
- public void setLoadControl(LoadControl loadControl) {
- mLoadControl = loadControl;
- }
- /**
- * 设置播放地址
- *
- * @param path 播放地址
- * @param headers 播放地址请求头
- */
- @Override
- public void setDataSource(String path, Map<String, String> headers) {
- // 设置dataSource
- if(path==null || path.length()==0){
- if (mPlayerEventListener!=null){
- mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_URL_NULL, 0);
- }
- return;
- }
- mMediaSource = mMediaSourceHelper.getMediaSource(path, headers);
- }
- @Override
- public void setDataSource(AssetFileDescriptor fd) {
- //no support
- }
- /**
- * 准备开始播放(异步)
- */
- @Override
- public void prepareAsync() {
- if (mInternalPlayer == null){
- return;
- }
- if (mMediaSource == null){
- return;
- }
- if (mSpeedPlaybackParameters != null) {
- mInternalPlayer.setPlaybackParameters(mSpeedPlaybackParameters);
- }
- mIsPreparing = true;
- mMediaSource.addEventListener(new Handler(), mMediaSourceEventListener);
- //准备播放
- mInternalPlayer.prepare(mMediaSource);
- }
- /**
- * 播放
- */
- @Override
- public void start() {
- if (mInternalPlayer == null){
- return;
- }
- mInternalPlayer.setPlayWhenReady(true);
- }
- /**
- * 暂停
- */
- @Override
- public void pause() {
- if (mInternalPlayer == null){
- return;
- }
- mInternalPlayer.setPlayWhenReady(false);
- }
- /**
- * 停止
- */
- @Override
- public void stop() {
- if (mInternalPlayer == null){
- return;
- }
- mInternalPlayer.stop();
- }
- private MediaSourceEventListener mMediaSourceEventListener = new MediaSourceEventListener() {
- @Override
- public void onReadingStarted(int windowIndex, MediaSource.MediaPeriodId mediaPeriodId) {
- if (mPlayerEventListener != null && mIsPreparing) {
- mPlayerEventListener.onPrepared();
- }
- }
- };
- /**
- * 重置播放器
- */
- @Override
- public void reset() {
- if (mInternalPlayer != null) {
- mInternalPlayer.stop(true);
- mInternalPlayer.setVideoSurface(null);
- mIsPreparing = false;
- mIsBuffering = false;
- mLastReportedPlaybackState = Player.STATE_IDLE;
- mLastReportedPlayWhenReady = false;
- }
- }
- /**
- * 是否正在播放
- */
- @Override
- public boolean isPlaying() {
- if (mInternalPlayer == null){
- return false;
- }
- int state = mInternalPlayer.getPlaybackState();
- switch (state) {
- case Player.STATE_BUFFERING:
- case Player.STATE_READY:
- return mInternalPlayer.getPlayWhenReady();
- case Player.STATE_IDLE:
- case Player.STATE_ENDED:
- default:
- return false;
- }
- }
- /**
- * 调整进度
- */
- @Override
- public void seekTo(long time) {
- if (mInternalPlayer == null){
- return;
- }
- mInternalPlayer.seekTo(time);
- }
- /**
- * 释放播放器
- */
- @Override
- public void release() {
- if (mInternalPlayer != null) {
- mInternalPlayer.removeListener(this);
- mInternalPlayer.removeVideoListener(this);
- final SimpleExoPlayer player = mInternalPlayer;
- mInternalPlayer = null;
- new Thread() {
- @Override
- public void run() {
- //异步释放,防止卡顿
- player.release();
- }
- }.start();
- }
- mIsPreparing = false;
- mIsBuffering = false;
- mLastReportedPlaybackState = Player.STATE_IDLE;
- mLastReportedPlayWhenReady = false;
- mSpeedPlaybackParameters = null;
- }
- /**
- * 获取当前播放的位置
- */
- @Override
- public long getCurrentPosition() {
- if (mInternalPlayer == null){
- return 0;
- }
- return mInternalPlayer.getCurrentPosition();
- }
- /**
- * 获取视频总时长
- */
- @Override
- public long getDuration() {
- if (mInternalPlayer == null){
- return 0;
- }
- return mInternalPlayer.getDuration();
- }
- /**
- * 获取缓冲百分比
- */
- @Override
- public int getBufferedPercentage() {
- return mInternalPlayer == null ? 0 : mInternalPlayer.getBufferedPercentage();
- }
- /**
- * 设置渲染视频的View,主要用于SurfaceView
- */
- @Override
- public void setSurface(Surface surface) {
- if (surface!=null){
- try {
- if (mInternalPlayer != null) {
- mInternalPlayer.setVideoSurface(surface);
- }
- } catch (Exception e) {
- mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,e.getMessage());
- }
- }
- }
- @Override
- public void setDisplay(SurfaceHolder holder) {
- if (holder == null){
- setSurface(null);
- } else{
- setSurface(holder.getSurface());
- }
- }
- /**
- * 设置音量
- */
- @Override
- public void setVolume(float leftVolume, float rightVolume) {
- if (mInternalPlayer != null){
- mInternalPlayer.setVolume((leftVolume + rightVolume) / 2);
- }
- }
- /**
- * 设置是否循环播放
- */
- @Override
- public void setLooping(boolean isLooping) {
- if (mInternalPlayer != null){
- mInternalPlayer.setRepeatMode(isLooping ? Player.REPEAT_MODE_ALL : Player.REPEAT_MODE_OFF);
- }
- }
- @Override
- public void setOptions() {
- //准备好就开始播放
- mInternalPlayer.setPlayWhenReady(true);
- }
- /**
- * 设置播放速度
- */
- @Override
- public void setSpeed(float speed) {
- PlaybackParameters playbackParameters = new PlaybackParameters(speed);
- mSpeedPlaybackParameters = playbackParameters;
- if (mInternalPlayer != null) {
- mInternalPlayer.setPlaybackParameters(playbackParameters);
- }
- }
- /**
- * 获取播放速度
- */
- @Override
- public float getSpeed() {
- if (mSpeedPlaybackParameters != null) {
- return mSpeedPlaybackParameters.speed;
- }
- return 1f;
- }
- /**
- * 获取当前缓冲的网速
- */
- @Override
- public long getTcpSpeed() {
- // no support
- return 0;
- }
- @Override
- public void onPlayerStateChanged(boolean playWhenReady, int playbackState) {
- if (mPlayerEventListener == null){
- return;
- }
- if (mIsPreparing){
- return;
- }
- if (mLastReportedPlayWhenReady != playWhenReady || mLastReportedPlaybackState != playbackState) {
- switch (playbackState) {
- //最开始调用的状态
- case Player.STATE_IDLE:
- break;
- //开始缓充
- case Player.STATE_BUFFERING:
- mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_BUFFERING_START, getBufferedPercentage());
- mIsBuffering = true;
- break;
- //开始播放
- case Player.STATE_READY:
- if (mIsBuffering) {
- mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_BUFFERING_END, getBufferedPercentage());
- mIsBuffering = false;
- }
- break;
- //播放器已经播放完了媒体
- case Player.STATE_ENDED:
- mPlayerEventListener.onCompletion();
- break;
- default:
- break;
- }
- mLastReportedPlaybackState = playbackState;
- mLastReportedPlayWhenReady = playWhenReady;
- }
- }
- @Override
- public void onPlayerError(ExoPlaybackException error) {
- if (mPlayerEventListener != null) {
- int type = error.type;
- if (type == TYPE_SOURCE){
- //错误的链接
- mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_SOURCE,error.getMessage());
- } else if (type == ExoPlaybackException.TYPE_RENDERER
- || type == ExoPlaybackException.TYPE_UNEXPECTED
- || type == ExoPlaybackException.TYPE_REMOTE
- || type == ExoPlaybackException.TYPE_OUT_OF_MEMORY){
- mPlayerEventListener.onError(PlayerConstant.ErrorType.TYPE_UNEXPECTED,error.getMessage());
- }
- }
- }
- @Override
- public void onVideoSizeChanged(int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) {
- if (mPlayerEventListener != null) {
- mPlayerEventListener.onVideoSizeChanged(width, height);
- if (unappliedRotationDegrees > 0) {
- mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_VIDEO_ROTATION_CHANGED, unappliedRotationDegrees);
- }
- }
- }
- @Override
- public void onRenderedFirstFrame() {
- if (mPlayerEventListener != null && mIsPreparing) {
- mPlayerEventListener.onInfo(PlayerConstant.MEDIA_INFO_VIDEO_RENDERING_START, 0);
- mIsPreparing = false;
- }
- }
- }
|