diff --git a/app/build.gradle b/app/build.gradle index 03209a4..11653bf 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -13,6 +13,10 @@ android { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } + compileOptions { + sourceCompatibility JavaVersion.VERSION_1_8 + targetCompatibility JavaVersion.VERSION_1_8 + } sourceSets { main.java.srcDirs += 'src/main/kotlin' } @@ -35,7 +39,13 @@ dependencies { implementation project(':playermanager') implementation project(':ima') - implementation "com.android.support:appcompat-v7:$APP_COMPAT_VERSION" + // overwrite support libraries + implementation "com.android.support:support-fragment:$APP_COMPAT_VERSION" + implementation "com.android.support:customtabs:$APP_COMPAT_VERSION" + implementation "com.android.support:recyclerview-v7:$APP_COMPAT_VERSION" + implementation "com.android.support:support-v4:$APP_COMPAT_VERSION" + implementation "com.android.support:support-compat:$APP_COMPAT_VERSION" + implementation "com.android.support:support-annotations:$APP_COMPAT_VERSION" // exo palyer implementation "com.google.android.exoplayer:exoplayer:$EXO_PLAYER_VERSION" diff --git a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/CustomDataSourceFactory.kt b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/CustomDataSourceFactory.kt index 802c34d..5a89bf9 100644 --- a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/CustomDataSourceFactory.kt +++ b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/CustomDataSourceFactory.kt @@ -2,12 +2,13 @@ package com.github.aakira.playermanager.sample.datasource import android.content.Context import com.google.android.exoplayer2.upstream.DataSource -import com.google.android.exoplayer2.upstream.TransferListener -class CustomDataSourceFactory(val context: Context, val listener: TransferListener, - val dataSourceFactory: DataSource.Factory) : DataSource.Factory { +class CustomDataSourceFactory( + private val context: Context, + private val dataSourceFactory: DataSource.Factory +) : DataSource.Factory { override fun createDataSource(): DataSource { - return PlayerDataSource(context, listener, dataSourceFactory.createDataSource()) + return PlayerDataSource(context, dataSourceFactory.createDataSource()) } } \ No newline at end of file diff --git a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/PlayerDataSource.kt b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/PlayerDataSource.kt index 8ece3bb..9190891 100644 --- a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/PlayerDataSource.kt +++ b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/PlayerDataSource.kt @@ -2,23 +2,24 @@ package com.github.aakira.playermanager.sample.datasource import android.content.Context import android.net.Uri -import com.google.android.exoplayer2.upstream.AssetDataSource -import com.google.android.exoplayer2.upstream.ContentDataSource -import com.google.android.exoplayer2.upstream.DataSource -import com.google.android.exoplayer2.upstream.DataSpec -import com.google.android.exoplayer2.upstream.FileDataSource -import com.google.android.exoplayer2.upstream.TransferListener +import com.google.android.exoplayer2.upstream.* import com.google.android.exoplayer2.util.Assertions import com.google.android.exoplayer2.util.Util import java.io.IOException -class PlayerDataSource(context: Context, listener: TransferListener?, - private var baseDataSource: DataSource) : DataSource { +class PlayerDataSource(context: Context, private var baseDataSource: DataSource) : DataSource { private var dataSource: DataSource? = null - private val fileDataSource: DataSource by lazy { FileDataSource(listener) } - private val assetDataSource: DataSource by lazy { AssetDataSource(context, listener) } - private val contentDataSource: DataSource by lazy { ContentDataSource(context, listener) } + private val fileDataSource: DataSource = FileDataSource() + private val assetDataSource: DataSource = AssetDataSource(context) + private val contentDataSource: DataSource = ContentDataSource(context) + + override fun addTransferListener(transferListener: TransferListener?) { + baseDataSource.addTransferListener(transferListener) + fileDataSource.addTransferListener(transferListener) + assetDataSource.addTransferListener(transferListener) + contentDataSource.addTransferListener(transferListener) + } @Throws(IOException::class) override fun open(dataSpec: DataSpec): Long { diff --git a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/VideoKeyUriSource.kt b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/VideoKeyUriSource.kt index dd23694..15e6230 100644 --- a/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/VideoKeyUriSource.kt +++ b/app/src/main/kotlin/com/github/aakira/playermanager/sample/datasource/VideoKeyUriSource.kt @@ -3,6 +3,7 @@ package com.github.aakira.playermanager.sample.datasource import android.net.Uri import com.google.android.exoplayer2.upstream.DataSource import com.google.android.exoplayer2.upstream.DataSpec +import com.google.android.exoplayer2.upstream.TransferListener import java.io.IOException import javax.crypto.spec.SecretKeySpec @@ -12,6 +13,9 @@ import javax.crypto.spec.SecretKeySpec */ class VideoKeyUriSource(private val spec: SecretKeySpec) : DataSource { + override fun addTransferListener(transferListener: TransferListener?) { + } + private var dataSpec: DataSpec? = null override fun getUri(): Uri { diff --git a/build.gradle b/build.gradle index 8d44405..1bf514e 100644 --- a/build.gradle +++ b/build.gradle @@ -3,25 +3,25 @@ buildscript { // This library version - ext.LIBRARY_VERSION_CODE = 13 - ext.LIBRARY_VERSION_NAME = "0.13.0" + ext.LIBRARY_VERSION_CODE = 14 + ext.LIBRARY_VERSION_NAME = "0.14.0" // App information - ext.COMPILE_SDK_VERSION = 27 - ext.BUILD_TOOLS_VERSION = "27.0.3" + ext.COMPILE_SDK_VERSION = 28 + ext.BUILD_TOOLS_VERSION = "28.0.3" ext.MIN_SDK_VERSION = 16 - ext.TARGET_SDK_VERSION = 25 + ext.TARGET_SDK_VERSION = 28 // Using libraries // Base libraries - ext.KOTLIN_VERSION = "1.2.30" - ext.EXO_PLAYER_VERSION = "2.8.1" + ext.KOTLIN_VERSION = "1.2.71" + ext.EXO_PLAYER_VERSION = "2.9.0" ext.IMA_VERSION = "3.7.2" // Others - ext.APP_COMPAT_VERSION = "27.0.2" - ext.PLAY_SERVICE_VERSION = "11.2.0" + ext.APP_COMPAT_VERSION = "27.1.1" + ext.PLAY_SERVICE_VERSION = "16.0.0" ext.KOTTER_KNIFE_VERSION = "0.1.0-SNAPSHOT" ext.TIMBER_VERSION = "4.3.1@aar" diff --git a/ima/build.gradle b/ima/build.gradle index 41d7282..a6ace05 100644 --- a/ima/build.gradle +++ b/ima/build.gradle @@ -26,6 +26,12 @@ afterEvaluate { dependencies { implementation project(':playermanager') + // overwrite support libraries + implementation "com.android.support:support-v4:$APP_COMPAT_VERSION" + implementation "com.android.support:support-compat:$APP_COMPAT_VERSION" + implementation "com.android.support:support-annotations:$APP_COMPAT_VERSION" + implementation "com.android.support:customtabs:$APP_COMPAT_VERSION" + // kotlin implementation "org.jetbrains.kotlin:kotlin-stdlib:$KOTLIN_VERSION" diff --git a/playermanager/src/main/java/com/github/aakira/playermanager/EventLogger.java b/playermanager/src/main/java/com/github/aakira/playermanager/EventLogger.java deleted file mode 100644 index 2869b0b..0000000 --- a/playermanager/src/main/java/com/github/aakira/playermanager/EventLogger.java +++ /dev/null @@ -1,607 +0,0 @@ -/* - * Copyright (C) 2016 The Android Open Source Project - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package com.github.aakira.playermanager; - -import android.net.NetworkInfo; -import android.os.SystemClock; -import android.support.annotation.Nullable; -import android.util.Log; -import android.view.Surface; - -import com.google.android.exoplayer2.C; -import com.google.android.exoplayer2.ExoPlaybackException; -import com.google.android.exoplayer2.Format; -import com.google.android.exoplayer2.PlaybackParameters; -import com.google.android.exoplayer2.Player; -import com.google.android.exoplayer2.RendererCapabilities; -import com.google.android.exoplayer2.Timeline; -import com.google.android.exoplayer2.analytics.AnalyticsListener; -import com.google.android.exoplayer2.decoder.DecoderCounters; -import com.google.android.exoplayer2.metadata.Metadata; -import com.google.android.exoplayer2.source.MediaSourceEventListener.LoadEventInfo; -import com.google.android.exoplayer2.source.MediaSourceEventListener.MediaLoadData; -import com.google.android.exoplayer2.source.TrackGroup; -import com.google.android.exoplayer2.source.TrackGroupArray; -import com.google.android.exoplayer2.trackselection.MappingTrackSelector; -import com.google.android.exoplayer2.trackselection.MappingTrackSelector.MappedTrackInfo; -import com.google.android.exoplayer2.trackselection.TrackSelection; -import com.google.android.exoplayer2.trackselection.TrackSelectionArray; -import com.google.android.exoplayer2.util.Util; - -import java.io.IOException; -import java.text.NumberFormat; -import java.util.Locale; - -/** Logs events from {@link Player} and other core components using {@link Log}. */ -public class EventLogger implements AnalyticsListener { - - private static final String TAG = "EventLogger"; - private static final int MAX_TIMELINE_ITEM_LINES = 3; - private static final NumberFormat TIME_FORMAT; - static { - TIME_FORMAT = NumberFormat.getInstance(Locale.US); - TIME_FORMAT.setMinimumFractionDigits(2); - TIME_FORMAT.setMaximumFractionDigits(2); - TIME_FORMAT.setGroupingUsed(false); - } - - private final @Nullable MappingTrackSelector trackSelector; - private final Timeline.Window window; - private final Timeline.Period period; - private final long startTimeMs; - - /** - * Creates event logger. - * - * @param trackSelector The mapping track selector used by the player. May be null if detailed - * logging of track mapping is not required. - */ - public EventLogger(@Nullable MappingTrackSelector trackSelector) { - this.trackSelector = trackSelector; - window = new Timeline.Window(); - period = new Timeline.Period(); - startTimeMs = SystemClock.elapsedRealtime(); - } - - // AnalyticsListener - - @Override - public void onLoadingChanged(EventTime eventTime, boolean isLoading) { - logd(eventTime, "loading", Boolean.toString(isLoading)); - } - - @Override - public void onPlayerStateChanged(EventTime eventTime, boolean playWhenReady, int state) { - logd(eventTime, "state", playWhenReady + ", " + getStateString(state)); - } - - @Override - public void onRepeatModeChanged(EventTime eventTime, @Player.RepeatMode int repeatMode) { - logd(eventTime, "repeatMode", getRepeatModeString(repeatMode)); - } - - @Override - public void onShuffleModeChanged(EventTime eventTime, boolean shuffleModeEnabled) { - logd(eventTime, "shuffleModeEnabled", Boolean.toString(shuffleModeEnabled)); - } - - @Override - public void onPositionDiscontinuity(EventTime eventTime, @Player.DiscontinuityReason int reason) { - logd(eventTime, "positionDiscontinuity", getDiscontinuityReasonString(reason)); - } - - @Override - public void onSeekStarted(EventTime eventTime) { - logd(eventTime, "seekStarted"); - } - - @Override - public void onPlaybackParametersChanged( - EventTime eventTime, PlaybackParameters playbackParameters) { - logd( - eventTime, - "playbackParameters", - Util.formatInvariant( - "speed=%.2f, pitch=%.2f, skipSilence=%s", - playbackParameters.speed, playbackParameters.pitch, playbackParameters.skipSilence)); - } - - @Override - public void onTimelineChanged(EventTime eventTime, @Player.TimelineChangeReason int reason) { - int periodCount = eventTime.timeline.getPeriodCount(); - int windowCount = eventTime.timeline.getWindowCount(); - logd( - "timelineChanged [" - + getEventTimeString(eventTime) - + ", periodCount=" - + periodCount - + ", windowCount=" - + windowCount - + ", reason=" - + getTimelineChangeReasonString(reason)); - for (int i = 0; i < Math.min(periodCount, MAX_TIMELINE_ITEM_LINES); i++) { - eventTime.timeline.getPeriod(i, period); - logd(" " + "period [" + getTimeString(period.getDurationMs()) + "]"); - } - if (periodCount > MAX_TIMELINE_ITEM_LINES) { - logd(" ..."); - } - for (int i = 0; i < Math.min(windowCount, MAX_TIMELINE_ITEM_LINES); i++) { - eventTime.timeline.getWindow(i, window); - logd( - " " - + "window [" - + getTimeString(window.getDurationMs()) - + ", " - + window.isSeekable - + ", " - + window.isDynamic - + "]"); - } - if (windowCount > MAX_TIMELINE_ITEM_LINES) { - logd(" ..."); - } - logd("]"); - } - - @Override - public void onPlayerError(EventTime eventTime, ExoPlaybackException e) { - loge(eventTime, "playerFailed", e); - } - - @Override - public void onTracksChanged( - EventTime eventTime, TrackGroupArray ignored, TrackSelectionArray trackSelections) { - MappedTrackInfo mappedTrackInfo = - trackSelector != null ? trackSelector.getCurrentMappedTrackInfo() : null; - if (mappedTrackInfo == null) { - logd(eventTime, "tracksChanged", "[]"); - return; - } - logd("tracksChanged [" + getEventTimeString(eventTime) + ", "); - // Log tracks associated to renderers. - int rendererCount = mappedTrackInfo.getRendererCount(); - for (int rendererIndex = 0; rendererIndex < rendererCount; rendererIndex++) { - TrackGroupArray rendererTrackGroups = mappedTrackInfo.getTrackGroups(rendererIndex); - TrackSelection trackSelection = trackSelections.get(rendererIndex); - if (rendererTrackGroups.length > 0) { - logd(" Renderer:" + rendererIndex + " ["); - for (int groupIndex = 0; groupIndex < rendererTrackGroups.length; groupIndex++) { - TrackGroup trackGroup = rendererTrackGroups.get(groupIndex); - String adaptiveSupport = - getAdaptiveSupportString( - trackGroup.length, - mappedTrackInfo.getAdaptiveSupport(rendererIndex, groupIndex, false)); - logd(" Group:" + groupIndex + ", adaptive_supported=" + adaptiveSupport + " ["); - for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { - String status = getTrackStatusString(trackSelection, trackGroup, trackIndex); - String formatSupport = - getFormatSupportString( - mappedTrackInfo.getTrackSupport(rendererIndex, groupIndex, trackIndex)); - logd( - " " - + status - + " Track:" - + trackIndex - + ", " - + Format.toLogString(trackGroup.getFormat(trackIndex)) - + ", supported=" - + formatSupport); - } - logd(" ]"); - } - // Log metadata for at most one of the tracks selected for the renderer. - if (trackSelection != null) { - for (int selectionIndex = 0; selectionIndex < trackSelection.length(); selectionIndex++) { - Metadata metadata = trackSelection.getFormat(selectionIndex).metadata; - if (metadata != null) { - logd(" Metadata ["); - printMetadata(metadata, " "); - logd(" ]"); - break; - } - } - } - logd(" ]"); - } - } - // Log tracks not associated with a renderer. - TrackGroupArray unassociatedTrackGroups = mappedTrackInfo.getUnmappedTrackGroups(); - if (unassociatedTrackGroups.length > 0) { - logd(" Renderer:None ["); - for (int groupIndex = 0; groupIndex < unassociatedTrackGroups.length; groupIndex++) { - logd(" Group:" + groupIndex + " ["); - TrackGroup trackGroup = unassociatedTrackGroups.get(groupIndex); - for (int trackIndex = 0; trackIndex < trackGroup.length; trackIndex++) { - String status = getTrackStatusString(false); - String formatSupport = - getFormatSupportString(RendererCapabilities.FORMAT_UNSUPPORTED_TYPE); - logd( - " " - + status - + " Track:" - + trackIndex - + ", " - + Format.toLogString(trackGroup.getFormat(trackIndex)) - + ", supported=" - + formatSupport); - } - logd(" ]"); - } - logd(" ]"); - } - logd("]"); - } - - @Override - public void onSeekProcessed(EventTime eventTime) { - logd(eventTime, "seekProcessed"); - } - - @Override - public void onMetadata(EventTime eventTime, Metadata metadata) { - logd("metadata [" + getEventTimeString(eventTime) + ", "); - printMetadata(metadata, " "); - logd("]"); - } - - @Override - public void onDecoderEnabled(EventTime eventTime, int trackType, DecoderCounters counters) { - logd(eventTime, "decoderEnabled", getTrackTypeString(trackType)); - } - - @Override - public void onAudioSessionId(EventTime eventTime, int audioSessionId) { - logd(eventTime, "audioSessionId", Integer.toString(audioSessionId)); - } - - @Override - public void onDecoderInitialized( - EventTime eventTime, int trackType, String decoderName, long initializationDurationMs) { - logd(eventTime, "decoderInitialized", getTrackTypeString(trackType) + ", " + decoderName); - } - - @Override - public void onDecoderInputFormatChanged(EventTime eventTime, int trackType, Format format) { - logd( - eventTime, - "decoderInputFormatChanged", - getTrackTypeString(trackType) + ", " + Format.toLogString(format)); - } - - @Override - public void onDecoderDisabled(EventTime eventTime, int trackType, DecoderCounters counters) { - logd(eventTime, "decoderDisabled", getTrackTypeString(trackType)); - } - - @Override - public void onAudioUnderrun( - EventTime eventTime, int bufferSize, long bufferSizeMs, long elapsedSinceLastFeedMs) { - loge( - eventTime, - "audioTrackUnderrun", - bufferSize + ", " + bufferSizeMs + ", " + elapsedSinceLastFeedMs + "]", - null); - } - - @Override - public void onDroppedVideoFrames(EventTime eventTime, int count, long elapsedMs) { - logd(eventTime, "droppedFrames", Integer.toString(count)); - } - - @Override - public void onVideoSizeChanged( - EventTime eventTime, - int width, - int height, - int unappliedRotationDegrees, - float pixelWidthHeightRatio) { - logd(eventTime, "videoSizeChanged", width + ", " + height); - } - - @Override - public void onRenderedFirstFrame(EventTime eventTime, Surface surface) { - logd(eventTime, "renderedFirstFrame", surface.toString()); - } - - @Override - public void onMediaPeriodCreated(EventTime eventTime) { - logd(eventTime, "mediaPeriodCreated"); - } - - @Override - public void onMediaPeriodReleased(EventTime eventTime) { - logd(eventTime, "mediaPeriodReleased"); - } - - @Override - public void onLoadStarted( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - // Do nothing. - } - - @Override - public void onLoadError( - EventTime eventTime, - LoadEventInfo loadEventInfo, - MediaLoadData mediaLoadData, - IOException error, - boolean wasCanceled) { - printInternalError(eventTime, "loadError", error); - } - - @Override - public void onLoadCanceled( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - // Do nothing. - } - - @Override - public void onLoadCompleted( - EventTime eventTime, LoadEventInfo loadEventInfo, MediaLoadData mediaLoadData) { - // Do nothing. - } - - @Override - public void onReadingStarted(EventTime eventTime) { - logd(eventTime, "mediaPeriodReadingStarted"); - } - - @Override - public void onBandwidthEstimate( - EventTime eventTime, int totalLoadTimeMs, long totalBytesLoaded, long bitrateEstimate) { - // Do nothing. - } - - @Override - public void onViewportSizeChange(EventTime eventTime, int width, int height) { - logd(eventTime, "viewportSizeChanged", width + ", " + height); - } - - @Override - public void onNetworkTypeChanged(EventTime eventTime, @Nullable NetworkInfo networkInfo) { - logd(eventTime, "networkTypeChanged", networkInfo == null ? "none" : networkInfo.toString()); - } - - @Override - public void onUpstreamDiscarded(EventTime eventTime, MediaLoadData mediaLoadData) { - logd(eventTime, "upstreamDiscarded", Format.toLogString(mediaLoadData.trackFormat)); - } - - @Override - public void onDownstreamFormatChanged(EventTime eventTime, MediaLoadData mediaLoadData) { - logd(eventTime, "downstreamFormatChanged", Format.toLogString(mediaLoadData.trackFormat)); - } - - @Override - public void onDrmSessionManagerError(EventTime eventTime, Exception e) { - printInternalError(eventTime, "drmSessionManagerError", e); - } - - @Override - public void onDrmKeysRestored(EventTime eventTime) { - logd(eventTime, "drmKeysRestored"); - } - - @Override - public void onDrmKeysRemoved(EventTime eventTime) { - logd(eventTime, "drmKeysRemoved"); - } - - @Override - public void onDrmKeysLoaded(EventTime eventTime) { - logd(eventTime, "drmKeysLoaded"); - } - - /** - * Logs a debug message. - * - * @param msg The message to log. - */ - protected void logd(String msg) { - Log.d(TAG, msg); - } - - /** - * Logs an error message and exception. - * - * @param msg The message to log. - * @param tr The exception to log. - */ - protected void loge(String msg, Throwable tr) { - Log.e(TAG, msg, tr); - } - - // Internal methods - - private void logd(EventTime eventTime, String eventName) { - logd(getEventString(eventTime, eventName)); - } - - private void logd(EventTime eventTime, String eventName, String eventDescription) { - logd(getEventString(eventTime, eventName, eventDescription)); - } - - private void loge(EventTime eventTime, String eventName, Throwable throwable) { - loge(getEventString(eventTime, eventName), throwable); - } - - private void loge( - EventTime eventTime, String eventName, String eventDescription, Throwable throwable) { - loge(getEventString(eventTime, eventName, eventDescription), throwable); - } - - private void printInternalError(EventTime eventTime, String type, Exception e) { - loge(eventTime, "internalError", type, e); - } - - private void printMetadata(Metadata metadata, String prefix) { - for (int i = 0; i < metadata.length(); i++) { - logd(prefix + metadata.get(i)); - } - } - - private String getEventString(EventTime eventTime, String eventName) { - return eventName + " [" + getEventTimeString(eventTime) + "]"; - } - - private String getEventString(EventTime eventTime, String eventName, String eventDescription) { - return eventName + " [" + getEventTimeString(eventTime) + ", " + eventDescription + "]"; - } - - private String getEventTimeString(EventTime eventTime) { - String windowPeriodString = "window=" + eventTime.windowIndex; - if (eventTime.mediaPeriodId != null) { - windowPeriodString += ", period=" + eventTime.mediaPeriodId.periodIndex; - if (eventTime.mediaPeriodId.isAd()) { - windowPeriodString += ", adGroup=" + eventTime.mediaPeriodId.adGroupIndex; - windowPeriodString += ", ad=" + eventTime.mediaPeriodId.adIndexInAdGroup; - } - } - return getTimeString(eventTime.realtimeMs - startTimeMs) - + ", " - + getTimeString(eventTime.currentPlaybackPositionMs) - + ", " - + windowPeriodString; - } - - private static String getTimeString(long timeMs) { - return timeMs == C.TIME_UNSET ? "?" : TIME_FORMAT.format((timeMs) / 1000f); - } - - private static String getStateString(int state) { - switch (state) { - case Player.STATE_BUFFERING: - return "BUFFERING"; - case Player.STATE_ENDED: - return "ENDED"; - case Player.STATE_IDLE: - return "IDLE"; - case Player.STATE_READY: - return "READY"; - default: - return "?"; - } - } - - private static String getFormatSupportString(int formatSupport) { - switch (formatSupport) { - case RendererCapabilities.FORMAT_HANDLED: - return "YES"; - case RendererCapabilities.FORMAT_EXCEEDS_CAPABILITIES: - return "NO_EXCEEDS_CAPABILITIES"; - case RendererCapabilities.FORMAT_UNSUPPORTED_DRM: - return "NO_UNSUPPORTED_DRM"; - case RendererCapabilities.FORMAT_UNSUPPORTED_SUBTYPE: - return "NO_UNSUPPORTED_TYPE"; - case RendererCapabilities.FORMAT_UNSUPPORTED_TYPE: - return "NO"; - default: - return "?"; - } - } - - private static String getAdaptiveSupportString(int trackCount, int adaptiveSupport) { - if (trackCount < 2) { - return "N/A"; - } - switch (adaptiveSupport) { - case RendererCapabilities.ADAPTIVE_SEAMLESS: - return "YES"; - case RendererCapabilities.ADAPTIVE_NOT_SEAMLESS: - return "YES_NOT_SEAMLESS"; - case RendererCapabilities.ADAPTIVE_NOT_SUPPORTED: - return "NO"; - default: - return "?"; - } - } - - // Suppressing reference equality warning because the track group stored in the track selection - // must point to the exact track group object to be considered part of it. - @SuppressWarnings("ReferenceEquality") - private static String getTrackStatusString(TrackSelection selection, TrackGroup group, - int trackIndex) { - return getTrackStatusString(selection != null && selection.getTrackGroup() == group - && selection.indexOf(trackIndex) != C.INDEX_UNSET); - } - - private static String getTrackStatusString(boolean enabled) { - return enabled ? "[X]" : "[ ]"; - } - - private static String getRepeatModeString(@Player.RepeatMode int repeatMode) { - switch (repeatMode) { - case Player.REPEAT_MODE_OFF: - return "OFF"; - case Player.REPEAT_MODE_ONE: - return "ONE"; - case Player.REPEAT_MODE_ALL: - return "ALL"; - default: - return "?"; - } - } - - private static String getDiscontinuityReasonString(@Player.DiscontinuityReason int reason) { - switch (reason) { - case Player.DISCONTINUITY_REASON_PERIOD_TRANSITION: - return "PERIOD_TRANSITION"; - case Player.DISCONTINUITY_REASON_SEEK: - return "SEEK"; - case Player.DISCONTINUITY_REASON_SEEK_ADJUSTMENT: - return "SEEK_ADJUSTMENT"; - case Player.DISCONTINUITY_REASON_AD_INSERTION: - return "AD_INSERTION"; - case Player.DISCONTINUITY_REASON_INTERNAL: - return "INTERNAL"; - default: - return "?"; - } - } - - private static String getTimelineChangeReasonString(@Player.TimelineChangeReason int reason) { - switch (reason) { - case Player.TIMELINE_CHANGE_REASON_PREPARED: - return "PREPARED"; - case Player.TIMELINE_CHANGE_REASON_RESET: - return "RESET"; - case Player.TIMELINE_CHANGE_REASON_DYNAMIC: - return "DYNAMIC"; - default: - return "?"; - } - } - - private static String getTrackTypeString(int trackType) { - switch (trackType) { - case C.TRACK_TYPE_AUDIO: - return "audio"; - case C.TRACK_TYPE_DEFAULT: - return "default"; - case C.TRACK_TYPE_METADATA: - return "metadata"; - case C.TRACK_TYPE_NONE: - return "none"; - case C.TRACK_TYPE_TEXT: - return "text"; - case C.TRACK_TYPE_VIDEO: - return "video"; - default: - return trackType >= C.TRACK_TYPE_CUSTOM_BASE ? "custom (" + trackType + ")" : "?"; - } - } -} diff --git a/playermanager/src/main/kotlin/com/github/aakira/playermanager/DataSourceCreatorInterface.kt b/playermanager/src/main/kotlin/com/github/aakira/playermanager/DataSourceCreatorInterface.kt index 34f7a47..87f08cc 100644 --- a/playermanager/src/main/kotlin/com/github/aakira/playermanager/DataSourceCreatorInterface.kt +++ b/playermanager/src/main/kotlin/com/github/aakira/playermanager/DataSourceCreatorInterface.kt @@ -2,9 +2,7 @@ package com.github.aakira.playermanager import android.content.Context import com.google.android.exoplayer2.upstream.DataSource -import com.google.android.exoplayer2.upstream.TransferListener interface DataSourceCreatorInterface { - fun create(context: Context, listener: TransferListener, - dataSourceFactory: DataSource.Factory): DataSource.Factory + fun create(context: Context, dataSourceFactory: DataSource.Factory): DataSource.Factory } \ No newline at end of file diff --git a/playermanager/src/main/kotlin/com/github/aakira/playermanager/EventProxy.kt b/playermanager/src/main/kotlin/com/github/aakira/playermanager/EventProxy.kt index dbd9c47..7489f1f 100644 --- a/playermanager/src/main/kotlin/com/github/aakira/playermanager/EventProxy.kt +++ b/playermanager/src/main/kotlin/com/github/aakira/playermanager/EventProxy.kt @@ -1,13 +1,7 @@ package com.github.aakira.playermanager -import android.net.NetworkInfo import android.view.Surface -import com.google.android.exoplayer2.C -import com.google.android.exoplayer2.ExoPlaybackException -import com.google.android.exoplayer2.Format -import com.google.android.exoplayer2.PlaybackParameters -import com.google.android.exoplayer2.Player -import com.google.android.exoplayer2.Timeline +import com.google.android.exoplayer2.* import com.google.android.exoplayer2.analytics.AnalyticsListener import com.google.android.exoplayer2.decoder.DecoderCounters import com.google.android.exoplayer2.metadata.Metadata @@ -15,9 +9,8 @@ import com.google.android.exoplayer2.source.MediaSourceEventListener import com.google.android.exoplayer2.source.TrackGroupArray import com.google.android.exoplayer2.trackselection.TrackSelectionArray import java.io.IOException -import java.lang.Exception -class EventProxy : Player.DefaultEventListener(), AnalyticsListener { +class EventProxy : Player.EventListener, AnalyticsListener { var onTracksChangedListener: TracksChangedListener? = null var onPlayerStateChangedListener: PlayerStateChangedListener? = null @@ -283,16 +276,6 @@ class EventProxy : Player.DefaultEventListener(), AnalyticsListener { totalBytesLoaded: Long, bitrateEstimate: Long) { } - // AnalyticsListener - override fun onNetworkTypeChanged(eventTime: AnalyticsListener.EventTime?, - networkInfo: NetworkInfo?) { - } - - // AnalyticsListener - override fun onViewportSizeChange(eventTime: AnalyticsListener.EventTime?, width: Int, - height: Int) { - } - // AnalyticsListener override fun onDrmKeysRestored(eventTime: AnalyticsListener.EventTime?) { } diff --git a/playermanager/src/main/kotlin/com/github/aakira/playermanager/ExoPlayerManager.kt b/playermanager/src/main/kotlin/com/github/aakira/playermanager/ExoPlayerManager.kt index efdf0ef..c0edf28 100644 --- a/playermanager/src/main/kotlin/com/github/aakira/playermanager/ExoPlayerManager.kt +++ b/playermanager/src/main/kotlin/com/github/aakira/playermanager/ExoPlayerManager.kt @@ -2,18 +2,8 @@ package com.github.aakira.playermanager import android.content.Context import com.github.aakira.playermanager.ExoPlayerManager.Builder -import com.google.android.exoplayer2.DefaultLoadControl -import com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_AFTER_REBUFFER_MS -import com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_BUFFER_FOR_PLAYBACK_MS -import com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_MAX_BUFFER_MS -import com.google.android.exoplayer2.DefaultLoadControl.DEFAULT_MIN_BUFFER_MS -import com.google.android.exoplayer2.DefaultRenderersFactory -import com.google.android.exoplayer2.ExoPlayerFactory -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.* +import com.google.android.exoplayer2.DefaultLoadControl.* import com.google.android.exoplayer2.analytics.AnalyticsListener import com.google.android.exoplayer2.drm.DrmSessionManager import com.google.android.exoplayer2.drm.FrameworkMediaCrypto @@ -26,10 +16,10 @@ import com.google.android.exoplayer2.source.hls.HlsMediaSource import com.google.android.exoplayer2.trackselection.AdaptiveTrackSelection import com.google.android.exoplayer2.trackselection.DefaultTrackSelector import com.google.android.exoplayer2.ui.PlayerView -import com.google.android.exoplayer2.upstream.DataSource import com.google.android.exoplayer2.upstream.DefaultHttpDataSource import com.google.android.exoplayer2.upstream.DefaultHttpDataSourceFactory import com.google.android.exoplayer2.upstream.TransferListener +import com.google.android.exoplayer2.util.EventLogger import okhttp3.OkHttpClient import java.io.IOException @@ -175,7 +165,7 @@ class ExoPlayerManager private constructor( mediaSource = HlsMediaSource.Factory( dataSourceCreator.dataSourceCreatorInterface?.let { - dataSourceCreator.dataSourceCreatorInterface.create(context, bandwidthMeter, dataSource) + dataSourceCreator.dataSourceCreatorInterface.create(context, dataSource) } ?: dataSource ) .createMediaSource(dataSourceCreator.uri) @@ -203,7 +193,7 @@ class ExoPlayerManager private constructor( mediaSource = ExtractorMediaSource.Factory( dataSourceCreator.dataSourceCreatorInterface?.let { - dataSourceCreator.dataSourceCreatorInterface.create(context, bandwidthMeter, dataSource) + dataSourceCreator.dataSourceCreatorInterface.create(context, dataSource) } ?: dataSource ) .setExtractorsFactory(DefaultExtractorsFactory()) @@ -240,7 +230,9 @@ class ExoPlayerManager private constructor( } /** - * init player and reconnect to a video stream + * init player and reconnect to a video stream immediately + * this method is not different from [ExoPlayer.retry] that is since ExoPlayer2.9.0 + * write `playerManager.player?.retry()` if you want use it in your code */ fun restart() { player?.release() @@ -434,7 +426,7 @@ class ExoPlayerManager private constructor( } private fun initializePlayer() { - player = ExoPlayerFactory.newSimpleInstance(renderersFactory, trackSelector, loadControl, + player = ExoPlayerFactory.newSimpleInstance(context, renderersFactory, trackSelector, loadControl, drmSessionManager).apply { addListener(eventProxy) @@ -463,20 +455,20 @@ class ExoPlayerManager private constructor( } private fun buildDataSourceFactory(userAgent: String, - bandwidthMeter: TransferListener, + bandwidthMeter: TransferListener, okHttpClient: OkHttpClient?) = okHttpClient?.let { buildOkHttpDataSourceFactory(userAgent, bandwidthMeter, okHttpClient) } ?: buildDefaultHttpDataSourceFactory(userAgent, bandwidthMeter) private fun buildDefaultHttpDataSourceFactory(userAgent: String, - listener: TransferListener, + listener: TransferListener, allowCrossProtocolRedirects: Boolean = false) = DefaultHttpDataSourceFactory(userAgent, listener, DefaultHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS, DefaultHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS, allowCrossProtocolRedirects) private fun buildOkHttpDataSourceFactory(userAgent: String, - listener: TransferListener, + listener: TransferListener, okHttpClient: OkHttpClient) = OkHttpDataSourceFactory(okHttpClient, userAgent, listener) } diff --git a/playermanager/src/main/kotlin/com/github/aakira/playermanager/LimitBandwidhthMeter.kt b/playermanager/src/main/kotlin/com/github/aakira/playermanager/LimitBandwidhthMeter.kt index 0023257..e2e9489 100644 --- a/playermanager/src/main/kotlin/com/github/aakira/playermanager/LimitBandwidhthMeter.kt +++ b/playermanager/src/main/kotlin/com/github/aakira/playermanager/LimitBandwidhthMeter.kt @@ -6,7 +6,7 @@ import com.google.android.exoplayer2.upstream.TransferListener class LimitBandwidthMeter( private val default: DefaultBandwidthMeter = DefaultBandwidthMeter() -) : BandwidthMeter by default, TransferListener by default { +) : BandwidthMeter by default, TransferListener by default { private var limitBitrate = Long.MAX_VALUE