From 2fab53ca99a503f502fcbc7e2ed8d6108b101650 Mon Sep 17 00:00:00 2001 From: guoshuyu Date: Mon, 21 May 2018 10:25:44 +0800 Subject: [PATCH] fix demo exo --- .../exo/GSYExo2MediaPlayer.java | 707 +----------------- .../ijk/media/exo2/IjkExo2MediaPlayer.java | 44 +- 2 files changed, 31 insertions(+), 720 deletions(-) diff --git a/app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2MediaPlayer.java b/app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2MediaPlayer.java index f5eef09..422f087 100644 --- a/app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2MediaPlayer.java +++ b/app/src/main/java/com/example/gsyvideoplayer/exo/GSYExo2MediaPlayer.java @@ -56,6 +56,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; +import tv.danmaku.ijk.media.exo2.IjkExo2MediaPlayer; import tv.danmaku.ijk.media.exo2.demo.EventLogger; import tv.danmaku.ijk.media.player.AbstractMediaPlayer; import tv.danmaku.ijk.media.player.IMediaPlayer; @@ -65,66 +66,16 @@ import tv.danmaku.ijk.media.player.misc.IjkTrackInfo; /** * 自定义exo player,实现不同于库的exo 无缝切换效果 */ -public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.EventListener, AnalyticsListener { +public class GSYExo2MediaPlayer extends IjkExo2MediaPlayer { private static final String TAG = "GSYExo2MediaPlayer"; - private Context mAppContext; - private SimpleExoPlayer mInternalPlayer; - private EventLogger mEventLogger; - private DefaultRenderersFactory renderersFactory; - private MediaSource mMediaSource; - private DefaultTrackSelector mTrackSelector; - private Surface mSurface; - private Map mHeaders = new HashMap<>(); - private List uris = new ArrayList<>(); - private PlaybackParameters mSpeedPlaybackParameters; - private Cache mCache; - private int mVideoWidth; - private int mVideoHeight; - private int lastReportedPlaybackState; - private boolean lastReportedPlayWhenReady; - private boolean mIsPrepareing = true; - private boolean mIsBuffering = false; - private boolean isLooping = false; - - private int audioSessionId = C.AUDIO_SESSION_ID_UNSET; + private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; + private final Timeline.Window window = new Timeline.Window(); public GSYExo2MediaPlayer(Context context) { - mAppContext = context.getApplicationContext(); - lastReportedPlaybackState = Player.STATE_IDLE; - } - - - private int getVideoRendererIndex() { - if (mInternalPlayer != null) { - for (int i = 0; i < mInternalPlayer.getRendererCount(); i++) { - if (mInternalPlayer.getRendererType(i) == C.TRACK_TYPE_VIDEO) { - return i; - } - } - } - return 0; - } - - @Override - public void setDisplay(SurfaceHolder sh) { - if (sh == null) - setSurface(null); - else - setSurface(sh.getSurface()); - } - - @Override - public void setSurface(Surface surface) { - mSurface = surface; - if (mInternalPlayer != null) { - if (surface != null && !surface.isValid()) { - mSurface = null; - } - mInternalPlayer.setVideoSurface(surface); - } + super(context); } @Override @@ -140,670 +91,30 @@ public class GSYExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev } @Override + @Deprecated public void setDataSource(String path) { throw new UnsupportedOperationException("Deprecated, try setDataSource(List uris, Map headers)"); } @Override + @Deprecated public void setDataSource(FileDescriptor fd) { throw new UnsupportedOperationException("Deprecated, try setDataSource(List uris, Map headers)"); } public void setDataSource(List uris, Map headers, boolean cache) { mHeaders = headers; - this.uris.clear(); - if (uris != null) { - this.uris.addAll(uris); - } else { + if (uris == null) { return; } ConcatenatingMediaSource concatenatedSource = new ConcatenatingMediaSource(); for (String uri : uris) { - MediaSource mediaSource = getMediaSource(Uri.parse(uri).toString(), false, cache); + MediaSource mediaSource = mExoHelper.getMediaSource(uri, isPreview, cache, false, mCacheDir); concatenatedSource.addMediaSource(mediaSource); } mMediaSource = concatenatedSource; } - @Override - public String getDataSource() { - return null; - } - - public MediaSource getMediaSource() { - return mMediaSource; - } - - public List getDataSourceList() { - return uris; - } - - @Override - public void prepareAsync() throws IllegalStateException { - if (mInternalPlayer != null) - throw new IllegalStateException("can't prepare a prepared player"); - TrackSelection.Factory videoTrackSelectionFactory = - new AdaptiveTrackSelection.Factory(new DefaultBandwidthMeter()); - mTrackSelector = new DefaultTrackSelector(videoTrackSelectionFactory); - - mEventLogger = new EventLogger(mTrackSelector); - - boolean preferExtensionDecoders = true; - boolean useExtensionRenderers = true;//是否开启扩展 - @DefaultRenderersFactory.ExtensionRendererMode int extensionRendererMode = useExtensionRenderers - ? (preferExtensionDecoders ? DefaultRenderersFactory.EXTENSION_RENDERER_MODE_PREFER - : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_ON) - : DefaultRenderersFactory.EXTENSION_RENDERER_MODE_OFF; - - renderersFactory = new DefaultRenderersFactory(mAppContext, extensionRendererMode); - DefaultLoadControl loadControl = new DefaultLoadControl(); - mInternalPlayer = ExoPlayerFactory.newSimpleInstance(renderersFactory, mTrackSelector, loadControl, null); - mInternalPlayer.addListener(this); - mInternalPlayer.addAnalyticsListener(this); - mInternalPlayer.addListener(mEventLogger); - if (mSpeedPlaybackParameters != null) { - mInternalPlayer.setPlaybackParameters(mSpeedPlaybackParameters); - } - if (mSurface != null) - mInternalPlayer.setVideoSurface(mSurface); - - mInternalPlayer.prepare(mMediaSource); - mInternalPlayer.setPlayWhenReady(false); - } - - @Override - public void start() throws IllegalStateException { - if (mInternalPlayer == null) - return; - mInternalPlayer.setPlayWhenReady(true); - } - - @Override - public void stop() throws IllegalStateException { - if (mInternalPlayer == null) - return; - mInternalPlayer.release(); - } - - @Override - public void pause() throws IllegalStateException { - if (mInternalPlayer == null) - return; - mInternalPlayer.setPlayWhenReady(false); - } - - @Override - public void setWakeMode(Context context, int mode) { - // FIXME: implement - } - - @Override - public void setScreenOnWhilePlaying(boolean screenOn) { - // TODO: do nothing - } - - @Override - public IjkTrackInfo[] getTrackInfo() { - // TODO: implement - return null; - } - - @Override - public int getVideoWidth() { - return mVideoWidth; - } - - @Override - public int getVideoHeight() { - return mVideoHeight; - } - - @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 msec) throws IllegalStateException { - if (mInternalPlayer == null) - return; - mInternalPlayer.seekTo(msec); - } - - @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 getVideoSarNum() { - return 1; - } - - @Override - public int getVideoSarDen() { - return 1; - } - - @Override - public void reset() { - if (mInternalPlayer != null) { - mInternalPlayer.release(); - mInternalPlayer = null; - } - - mSurface = null; - mVideoWidth = 0; - mVideoHeight = 0; - } - - @Override - public void setLooping(boolean looping) { - isLooping = looping; - } - - @Override - public boolean isLooping() { - return isLooping; - } - - @Override - public void setVolume(float leftVolume, float rightVolume) { - if (mInternalPlayer != null) - mInternalPlayer.setVolume((leftVolume + rightVolume) / 2); - } - - @Override - public int getAudioSessionId() { - return audioSessionId; - } - - @Override - public MediaInfo getMediaInfo() { - // TODO: no support - return null; - } - - @Override - public void setLogEnabled(boolean enable) { - // do nothing - } - - @Override - public boolean isPlayable() { - return true; - } - - @Override - public void setAudioStreamType(int streamtype) { - // do nothing - } - - @Override - public void setKeepInBackground(boolean keepInBackground) { - // do nothing - } - - @Override - public void release() { - if (mInternalPlayer != null) { - reset(); - mEventLogger = null; - } - if (mCache != null) { - try { - mCache.release(); - } catch (Cache.CacheException e) { - e.printStackTrace(); - } - } - } - - public void stopPlayback() { - mInternalPlayer.stop(); - } - - /** - * 倍速播放 - * - * @param speed 倍速播放,默认为1 - * @param pitch 音量缩放,默认为1,修改会导致声音变调 - */ - public void setSpeed(@Size(min = 0) float speed, @Size(min = 0) float pitch) { - PlaybackParameters playbackParameters = new PlaybackParameters(speed, pitch); - mSpeedPlaybackParameters = playbackParameters; - if (mInternalPlayer != null) { - mInternalPlayer.setPlaybackParameters(playbackParameters); - } - } - - public float getSpeed() { - return mInternalPlayer.getPlaybackParameters().speed; - } - - public int getBufferedPercentage() { - if (mInternalPlayer == null) - return 0; - - return mInternalPlayer.getBufferedPercentage(); - } - - public static final int TYPE_RTMP = 4; - - /** - * Makes a best guess to infer the type from a file name. - * - * @param fileName Name of the file. It can include the path of the file. - * @return The content type. - */ - @C.ContentType - private int inferContentType(String fileName) { - fileName = Util.toLowerInvariant(fileName); - if (fileName.endsWith(".mpd")) { - return C.TYPE_DASH; - } else if (fileName.endsWith(".m3u8")) { - return C.TYPE_HLS; - } else if (fileName.endsWith(".ism") || fileName.endsWith(".isml") - || fileName.endsWith(".ism/manifest") || fileName.endsWith(".isml/manifest")) { - return C.TYPE_SS; - } else if (fileName.startsWith("rtmp:")) { - return TYPE_RTMP; - } else { - return C.TYPE_OTHER; - } - } - - private MediaSource getMediaSource(String dataSource, boolean preview, boolean cacheEnable) { - Uri contentUri = Uri.parse(dataSource); - int contentType = inferContentType(dataSource); - MediaSource mediaSource; - switch (contentType) { - case C.TYPE_SS: - mediaSource = new SsMediaSource.Factory( - new DefaultSsChunkSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)), - new DefaultDataSourceFactory(mAppContext, null, - getHttpDataSourceFactory(preview))).createMediaSource(contentUri); - break; - case C.TYPE_DASH: - mediaSource = new DashMediaSource.Factory(new DefaultDashChunkSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)), - new DefaultDataSourceFactory(mAppContext, null, - getHttpDataSourceFactory(preview))).createMediaSource(contentUri); - break; - case C.TYPE_HLS: - mediaSource = new HlsMediaSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)).createMediaSource(contentUri); - break; - case TYPE_RTMP: - RtmpDataSourceFactory rtmpDataSourceFactory = new RtmpDataSourceFactory(null); - mediaSource = new ExtractorMediaSource.Factory(rtmpDataSourceFactory) - .setExtractorsFactory(new DefaultExtractorsFactory()) - .createMediaSource(contentUri); - break; - case C.TYPE_OTHER: - default: - mediaSource = new ExtractorMediaSource.Factory(getDataSourceFactoryCache(dataSource, cacheEnable, preview)) - .setExtractorsFactory(new DefaultExtractorsFactory()) - .createMediaSource(contentUri); - break; - } - /*if (isLooping()) { - return new LoopingMediaSource(mediaSource); - }*/ - return mediaSource; - } - - /** - * 获取SourceFactory,是否带Cache - */ - private DataSource.Factory getDataSourceFactoryCache(String dataSource, boolean cacheEnable, boolean preview) { - if (cacheEnable) { - Cache cache = getCache(); - return new CacheDataSourceFactory(cache, getDataSourceFactory(preview), CacheDataSource.FLAG_IGNORE_CACHE_ON_ERROR); - } else { - return getDataSourceFactory(preview); - } - } - - /** - * 本地缓存目录 - */ - private Cache getCache() { - if (mCache == null) { - String path = mAppContext.getCacheDir().getAbsolutePath() + File.separator + "exo"; - boolean isLocked = SimpleCache.isCacheFolderLocked(new File(path)); - if (!isLocked) { - mCache = new SimpleCache(new File(path), new LeastRecentlyUsedCacheEvictor(1024 * 1024 * 100)); - } - } - return mCache; - } - - /** - * 获取SourceFactory - */ - private DataSource.Factory getDataSourceFactory(boolean preview) { - return new DefaultDataSourceFactory(mAppContext, preview ? null : new DefaultBandwidthMeter(), - getHttpDataSourceFactory(preview)); - } - - private DataSource.Factory getHttpDataSourceFactory(boolean preview) { - DefaultHttpDataSourceFactory dataSourceFactory = new DefaultHttpDataSourceFactory(Util.getUserAgent(mAppContext, - TAG), preview ? null : new DefaultBandwidthMeter()); - if (mHeaders != null && mHeaders.size() > 0) { - for (Map.Entry header : mHeaders.entrySet()) { - dataSourceFactory.getDefaultRequestProperties().set(header.getKey(), header.getValue()); - } - } - return dataSourceFactory; - } - - @Override - public void onTimelineChanged(Timeline timeline, Object manifest, int reason) { - - } - - @Override - public void onTracksChanged(TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - - } - - @Override - public void onLoadingChanged(boolean isLoading) { - - } - - @Override - public void onPlayerStateChanged(boolean playWhenReady, int playbackState) { - //重新播放状态顺序为:STATE_IDLE -》STATE_BUFFERING -》STATE_READY - //缓冲时顺序为:STATE_BUFFERING -》STATE_READY - //Log.e(TAG, "onPlayerStateChanged: playWhenReady = " + playWhenReady + ", playbackState = " + playbackState); - if (lastReportedPlayWhenReady != playWhenReady || lastReportedPlaybackState != playbackState) { - if (mIsBuffering) { - switch (playbackState) { - case Player.STATE_ENDED: - case Player.STATE_READY: - notifyOnInfo(IMediaPlayer.MEDIA_INFO_BUFFERING_END, mInternalPlayer.getBufferedPercentage()); - mIsBuffering = false; - break; - } - } - - if (mIsPrepareing) { - switch (playbackState) { - case Player.STATE_READY: - notifyOnPrepared(); - mIsPrepareing = false; - break; - } - } - - switch (playbackState) { - case Player.STATE_BUFFERING: - notifyOnInfo(IMediaPlayer.MEDIA_INFO_BUFFERING_START, mInternalPlayer.getBufferedPercentage()); - mIsBuffering = true; - break; - case Player.STATE_READY: - break; - case Player.STATE_ENDED: - notifyOnCompletion(); - break; - default: - break; - } - } - lastReportedPlayWhenReady = playWhenReady; - lastReportedPlaybackState = playbackState; - } - - @Override - public void onRepeatModeChanged(int repeatMode) { - - } - - @Override - public void onShuffleModeEnabledChanged(boolean shuffleModeEnabled) { - - } - - @Override - public void onPlayerError(ExoPlaybackException error) { - notifyOnError(IMediaPlayer.MEDIA_ERROR_UNKNOWN, IMediaPlayer.MEDIA_ERROR_UNKNOWN); - } - - @Override - public void onPositionDiscontinuity(int reason) { - - } - - @Override - public void onPlaybackParametersChanged(PlaybackParameters playbackParameters) { - - } - - @Override - public void onSeekProcessed() { - - } - - /////////////////////////////////////AudioRendererEventListener///////////////////////////////////////////// - - - @Override - public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int playbackState) { - - } - - @Override - public void onTimelineChanged(EventTime eventTime, int reason) { - - } - - @Override - public void onPositionDiscontinuity(EventTime eventTime, int reason) { - - } - - @Override - public void onSeekStarted(EventTime eventTime) { - - } - - @Override - public void onSeekProcessed(EventTime eventTime) { - - } - - @Override - public void onPlaybackParametersChanged(EventTime eventTime, PlaybackParameters playbackParameters) { - - } - - @Override - public void onRepeatModeChanged(EventTime eventTime, int repeatMode) { - - } - - @Override - public void onShuffleModeChanged(EventTime eventTime, boolean shuffleModeEnabled) { - - } - - @Override - public void onLoadingChanged(EventTime eventTime, boolean isLoading) { - - } - - @Override - public void onPlayerError(EventTime eventTime, ExoPlaybackException error) { - - } - - @Override - public void onTracksChanged(EventTime eventTime, TrackGroupArray trackGroups, TrackSelectionArray trackSelections) { - - } - - @Override - public void onLoadStarted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) { - - } - - @Override - public void onLoadCompleted(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) { - - } - - @Override - public void onLoadCanceled(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData) { - - } - - @Override - public void onLoadError(EventTime eventTime, MediaSourceEventListener.LoadEventInfo loadEventInfo, MediaSourceEventListener.MediaLoadData mediaLoadData, IOException error, boolean wasCanceled) { - - } - - @Override - public void onDownstreamFormatChanged(EventTime eventTime, MediaSourceEventListener.MediaLoadData mediaLoadData) { - - } - - @Override - public void onUpstreamDiscarded(EventTime eventTime, MediaSourceEventListener.MediaLoadData mediaLoadData) { - - } - - @Override - public void onMediaPeriodCreated(EventTime eventTime) { - - } - - @Override - public void onMediaPeriodReleased(EventTime eventTime) { - - } - - @Override - public void onReadingStarted(EventTime eventTime) { - - } - - @Override - public void onBandwidthEstimate(EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) { - - } - - @Override - public void onViewportSizeChange(EventTime eventTime, int width, int height) { - - } - - @Override - public void onNetworkTypeChanged(EventTime eventTime, @Nullable NetworkInfo networkInfo) { - - } - - @Override - public void onMetadata(EventTime eventTime, Metadata metadata) { - - } - - @Override - public void onDecoderEnabled(EventTime eventTime, int trackType, DecoderCounters decoderCounters) { - - } - - @Override - public void onDecoderInitialized(EventTime eventTime, int trackType, String decoderName, long initializationDurationMs) { - - } - - @Override - public void onDecoderInputFormatChanged(EventTime eventTime, int trackType, Format format) { - - } - - @Override - public void onDecoderDisabled(EventTime eventTime, int trackType, DecoderCounters decoderCounters) { - audioSessionId = C.AUDIO_SESSION_ID_UNSET; - } - - @Override - public void onAudioSessionId(EventTime eventTime, int audioSessionId) { - this.audioSessionId = audioSessionId; - } - - @Override - public void onAudioUnderrun(EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { - - } - - @Override - public void onDroppedVideoFrames(EventTime eventTime, int droppedFrames, long elapsedMs) { - - } - - @Override - public void onVideoSizeChanged(EventTime eventTime, int width, int height, int unappliedRotationDegrees, float pixelWidthHeightRatio) { - mVideoWidth = width; - mVideoHeight = height; - notifyOnVideoSizeChanged(width, height, 1, 1); - if (unappliedRotationDegrees > 0) - notifyOnInfo(IMediaPlayer.MEDIA_INFO_VIDEO_ROTATION_CHANGED, unappliedRotationDegrees); - } - - @Override - public void onRenderedFirstFrame(EventTime eventTime, Surface surface) { - - } - - @Override - public void onDrmKeysLoaded(EventTime eventTime) { - - } - - @Override - public void onDrmSessionManagerError(EventTime eventTime, Exception error) { - - } - - @Override - public void onDrmKeysRestored(EventTime eventTime) { - - } - - @Override - public void onDrmKeysRemoved(EventTime eventTime) { - - } - - - - /*************自定义***************/ - - - private final Timeline.Window window = new Timeline.Window(); - private static final long MAX_POSITION_FOR_SEEK_TO_PREVIOUS = 3000; - /** * 上一集 */ diff --git a/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java index 15bc5b7..60cb07e 100644 --- a/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java +++ b/gsyvideoplayer-exo2/src/main/java/tv/danmaku/ijk/media/exo2/IjkExo2MediaPlayer.java @@ -52,41 +52,41 @@ public class IjkExo2MediaPlayer extends AbstractMediaPlayer implements Player.Ev private static final String TAG = "IjkExo2MediaPlayer"; - private Context mAppContext; - private SimpleExoPlayer mInternalPlayer; - private EventLogger mEventLogger; - private DefaultRenderersFactory rendererFactory; - private MediaSource mMediaSource; - private DefaultTrackSelector mTrackSelector; - private String mDataSource; - private Surface mSurface; - private Map mHeaders = new HashMap<>(); - private PlaybackParameters mSpeedPlaybackParameters; - private int mVideoWidth; - private int mVideoHeight; - private int lastReportedPlaybackState; - private boolean isLastReportedPlayWhenReady; - private boolean isPreparing = true; - private boolean isBuffering = false; - private boolean isLooping = false; + protected Context mAppContext; + protected SimpleExoPlayer mInternalPlayer; + protected EventLogger mEventLogger; + protected DefaultRenderersFactory rendererFactory; + protected MediaSource mMediaSource; + protected DefaultTrackSelector mTrackSelector; + protected String mDataSource; + protected Surface mSurface; + protected Map mHeaders = new HashMap<>(); + protected PlaybackParameters mSpeedPlaybackParameters; + protected int mVideoWidth; + protected int mVideoHeight; + protected int lastReportedPlaybackState; + protected boolean isLastReportedPlayWhenReady; + protected boolean isPreparing = true; + protected boolean isBuffering = false; + protected boolean isLooping = false; /** * 是否带上header */ - private boolean isPreview = false; + protected boolean isPreview = false; /** * 是否开启缓存 */ - private boolean isCache = false; + protected boolean isCache = false; /** * dataSource等的帮组类 */ - private ExoSourceManager mExoHelper; + protected ExoSourceManager mExoHelper; /** * 缓存目录,可以为空 */ - private File mCacheDir; + protected File mCacheDir; - private int audioSessionId = C.AUDIO_SESSION_ID_UNSET; + protected int audioSessionId = C.AUDIO_SESSION_ID_UNSET; public IjkExo2MediaPlayer(Context context) { -- GitLab