From 2eedb080b2bf1a4826542317f159360f23ff30f2 Mon Sep 17 00:00:00 2001 From: Sascha Peilicke Date: Tue, 25 Sep 2018 20:19:57 +0200 Subject: [PATCH] Switch to OkHttpDataSource As requested in ExoPlayer issue 3735 [0]. Changes exoplayer dependencies to 'api' to ensure library users automatically get it. [0] https://github.com/google/ExoPlayer/issues/3735 --- example/build.gradle | 1 - .../exoplayer2/ext/icy/MainActivity.kt | 5 +- exoplayer2-ext-icy/build.gradle | 3 +- .../exoplayer2/ext/icy/IcyHttpDataSource.java | 57 +++++++++---------- .../ext/icy/IcyHttpDataSourceFactory.java | 56 +++++++++--------- .../ext/icy/IcyHttpDataSourceFactoryTest.java | 8 +-- .../ext/icy/IcyHttpDataSourceTest.java | 8 +-- .../exoplayer2/ext/icy/test/Constants.java | 3 - 8 files changed, 66 insertions(+), 75 deletions(-) diff --git a/example/build.gradle b/example/build.gradle index e463b12..bd30652 100644 --- a/example/build.gradle +++ b/example/build.gradle @@ -21,7 +21,6 @@ dependencies { implementation 'com.android.support:appcompat-v7:28.0.0' implementation 'com.android.support.constraint:constraint-layout:1.1.3' implementation 'com.android.support:design:28.0.0' - implementation 'com.google.android.exoplayer:exoplayer-core:2.8.4' implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:0.26.1' implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:0.26.1' diff --git a/example/src/main/java/com/example/exoplayer2/ext/icy/MainActivity.kt b/example/src/main/java/com/example/exoplayer2/ext/icy/MainActivity.kt index 63e42e0..1639b58 100644 --- a/example/src/main/java/com/example/exoplayer2/ext/icy/MainActivity.kt +++ b/example/src/main/java/com/example/exoplayer2/ext/icy/MainActivity.kt @@ -18,6 +18,7 @@ import kotlinx.coroutines.experimental.CoroutineStart import kotlinx.coroutines.experimental.Dispatchers import kotlinx.coroutines.experimental.GlobalScope import kotlinx.coroutines.experimental.async +import okhttp3.OkHttpClient import saschpe.exoplayer2.ext.icy.IcyHttpDataSourceFactory /** @@ -67,7 +68,9 @@ class MainActivity : AppCompatActivity() { // Custom HTTP data source factory which requests Icy metadata and parses it if // the stream server supports it - val icyHttpDataSourceFactory = IcyHttpDataSourceFactory.Builder(userAgent) + val client = OkHttpClient.Builder().build() + val icyHttpDataSourceFactory = IcyHttpDataSourceFactory.Builder(client) + .setUserAgent(userAgent) .setIcyHeadersListener { icyHeaders -> Log.d(TAG, "onIcyMetaData: icyHeaders=$icyHeaders") } diff --git a/exoplayer2-ext-icy/build.gradle b/exoplayer2-ext-icy/build.gradle index 0931fcf..e607294 100644 --- a/exoplayer2-ext-icy/build.gradle +++ b/exoplayer2-ext-icy/build.gradle @@ -53,7 +53,8 @@ android { dependencies { // Runtime dependencies - implementation 'com.google.android.exoplayer:exoplayer-core:2.8.4' + api 'com.google.android.exoplayer:exoplayer-core:2.8.4' + api 'com.google.android.exoplayer:extension-okhttp:2.8.4' // Test dependencies testImplementation 'junit:junit:4.12' diff --git a/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSource.java b/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSource.java index e625e45..b7a4829 100644 --- a/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSource.java +++ b/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSource.java @@ -4,9 +4,9 @@ import android.support.annotation.Nullable; import android.util.Log; +import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.DataSpec; -import com.google.android.exoplayer2.upstream.DefaultHttpDataSource; import com.google.android.exoplayer2.upstream.TransferListener; import com.google.android.exoplayer2.util.Predicate; @@ -14,11 +14,14 @@ import java.util.List; import java.util.Map; +import okhttp3.CacheControl; +import okhttp3.Call; + /** * https://cast.readme.io/v1.0/docs/icy * http://www.smackfu.com/stuff/programming/shoutcast.html */ -public final class IcyHttpDataSource extends DefaultHttpDataSource { +public final class IcyHttpDataSource extends OkHttpDataSource { private static final String TAG = IcyHttpDataSource.class.getSimpleName(); private static final String REQUEST_HEADER_ICY_METAINT_KEY = "Icy-MetaData"; @@ -49,14 +52,13 @@ public interface IcyMetadataListener { } private IcyHttpDataSource( - @NonNull final String userAgent, + @NonNull Call.Factory callFactory, + @Nullable final String userAgent, @Nullable final Predicate contentTypePredicate, - @Nullable final TransferListener listener, - final int connectTimeoutMillis, - final int readTimeoutMillis, - final boolean allowCrossProtocolRedirects, - @Nullable final RequestProperties defaultRequestProperties) { - super(userAgent, contentTypePredicate, listener, connectTimeoutMillis, readTimeoutMillis, allowCrossProtocolRedirects, defaultRequestProperties); + @Nullable final TransferListener listener, + @Nullable CacheControl cacheControl, + @NonNull RequestProperties defaultRequestProperties) { + super(callFactory, userAgent, contentTypePredicate, listener, cacheControl, defaultRequestProperties); defaultRequestProperties.set(REQUEST_HEADER_ICY_METAINT_KEY, REQUEST_HEADER_ICY_METAINT_VALUE); // See class Builder } @@ -202,18 +204,22 @@ private IcyMetadata parseMetadata(final String metaDataString) { } public final static class Builder { + private Call.Factory callFactory; private String userAgent; private Predicate contentTypePredicate; - private TransferListener listener; - private int connectTimeoutMillis; - private int readTimeoutMillis; - private boolean allowCrossProtocolRedirects; + private TransferListener listener; + private CacheControl cacheControl; private RequestProperties defaultRequestProperties = new RequestProperties(); private IcyHeadersListener icyHeadersListener; private IcyMetadataListener icyMetadataListener; - public Builder(@NonNull final String userAgent) { + public Builder(@NonNull Call.Factory callFactory) { + this.callFactory = callFactory; + } + + public Builder setUserAgent(@NonNull final String userAgent) { this.userAgent = userAgent; + return this; } public Builder setContentTypePredicate(@NonNull final Predicate contentTypePredicate) { @@ -226,18 +232,8 @@ public Builder setTransferListener(@NonNull final TransferListener * The exact contents isn't specified and implementation specific. It's therefore up to the * user to figure what format a given stream returns. */ diff --git a/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactory.java b/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactory.java index 454da17..47840bc 100644 --- a/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactory.java +++ b/exoplayer2-ext-icy/src/main/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactory.java @@ -2,17 +2,24 @@ import android.support.annotation.NonNull; +import com.google.android.exoplayer2.ext.okhttp.OkHttpDataSource; import com.google.android.exoplayer2.upstream.DataSource; import com.google.android.exoplayer2.upstream.HttpDataSource; import com.google.android.exoplayer2.upstream.TransferListener; +import com.google.android.exoplayer2.util.Predicate; -/** A {@link HttpDataSource.Factory} that produces {@link IcyHttpDataSource} instances. */ -public final class IcyHttpDataSourceFactory extends HttpDataSource.BaseFactory { +import okhttp3.CacheControl; +import okhttp3.Call; + +/** + * A {@link HttpDataSource.Factory} that produces {@link IcyHttpDataSource} instances. + */ +public final class IcyHttpDataSourceFactory extends OkHttpDataSource.BaseFactory { + private Call.Factory callFactory; private String userAgent; + private Predicate contentTypePredicate; private TransferListener listener; - private int connectTimeoutMillis; - private int readTimeoutMillis; - private boolean allowCrossProtocolRedirects; + private CacheControl cacheControl; private IcyHttpDataSource.IcyHeadersListener icyHeadersListener; private IcyHttpDataSource.IcyMetadataListener icyMetadataListener; @@ -26,41 +33,30 @@ private IcyHttpDataSourceFactory() { public final static class Builder { private final IcyHttpDataSourceFactory factory; - /** - * Sets {@link - * IcyHttpDataSource#DEFAULT_CONNECT_TIMEOUT_MILLIS} as the connection timeout, {@link - * IcyHttpDataSource#DEFAULT_READ_TIMEOUT_MILLIS} as the read timeout and disables - * cross-protocol redirects. - * - * @param userAgent The user agent - */ - public Builder(@NonNull final String userAgent) { + public Builder(@NonNull Call.Factory callFactory) { // Apply defaults factory = new IcyHttpDataSourceFactory(); - factory.userAgent = userAgent; + factory.callFactory = callFactory; factory.listener = null; - factory.connectTimeoutMillis = IcyHttpDataSource.DEFAULT_CONNECT_TIMEOUT_MILLIS; - factory.readTimeoutMillis = IcyHttpDataSource.DEFAULT_READ_TIMEOUT_MILLIS; - factory.allowCrossProtocolRedirects = false; } - public Builder setTransferListener(@NonNull final TransferListener listener) { - factory.listener = listener; + public Builder setUserAgent(@NonNull final String userAgent) { + factory.userAgent = userAgent; return this; } - public Builder setConnectTimeoutMillis(@NonNull final int connectTimeoutMillis) { - factory.connectTimeoutMillis = connectTimeoutMillis; + public Builder setContentTypePredicate(@NonNull final Predicate contentTypePredicate) { + factory.contentTypePredicate = contentTypePredicate; return this; } - public Builder setReadTimeoutMillis(@NonNull final int readTimeoutMillis) { - factory.readTimeoutMillis = readTimeoutMillis; + public Builder setTransferListener(@NonNull final TransferListener listener) { + factory.listener = listener; return this; } - public Builder setAllowCrossProtocolRedirects(@NonNull final boolean allowCrossProtocolRedirects) { - factory.allowCrossProtocolRedirects = allowCrossProtocolRedirects; + public Builder setCacheControl(@NonNull final CacheControl cacheControl) { + factory.cacheControl = cacheControl; return this; } @@ -81,11 +77,11 @@ public IcyHttpDataSourceFactory build() { @Override protected IcyHttpDataSource createDataSourceInternal(@NonNull HttpDataSource.RequestProperties defaultRequestProperties) { - return new IcyHttpDataSource.Builder(userAgent) + return new IcyHttpDataSource.Builder(callFactory) + .setUserAgent(userAgent) + .setContentTypePredicate(contentTypePredicate) .setTransferListener(listener) - .setConnectTimeoutMillis(connectTimeoutMillis) - .setReadTimeoutMillis(readTimeoutMillis) - .setAllowCrossProtocolRedirects(allowCrossProtocolRedirects) + .setCacheControl(cacheControl) .setDefaultRequestProperties(defaultRequestProperties) .setIcyHeadersListener(icyHeadersListener) .setIcyMetadataListener(icyMetadataListener) diff --git a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactoryTest.java b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactoryTest.java index 26d532e..cf42535 100644 --- a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactoryTest.java +++ b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceFactoryTest.java @@ -10,6 +10,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import okhttp3.OkHttpClient; import saschpe.exoplayer2.ext.icy.test.Constants; import static org.junit.Assert.assertNotNull; @@ -49,11 +50,10 @@ public void onIcyMetaData(IcyHttpDataSource.IcyMetadata icyMetadata) { @Test public void createDataSourceViaFactoryFromFactoryBuilder() { // Arrange - IcyHttpDataSourceFactory factory = new IcyHttpDataSourceFactory.Builder(Constants.TEST_USER_AGENT) + OkHttpClient client = new OkHttpClient.Builder().build(); + IcyHttpDataSourceFactory factory = new IcyHttpDataSourceFactory.Builder(client) + .setUserAgent(Constants.TEST_USER_AGENT) .setTransferListener(TEST_TRANSFER_LISTENER) - .setConnectTimeoutMillis(Constants.TEST_CONNECT_TIMEOUT_MS) - .setReadTimeoutMillis(Constants.TEST_READ_TIMEOUT_MS) - .setAllowCrossProtocolRedirects(Constants.TEST_ALLOW_CROSS_PROTOCOL_REDIRECTS) .setIcyHeadersListener(TEST_ICY_HEADERS_LISTENER) .setIcyMetadataChangeListener(TEST_ICY_METADATA_LISTENER) .build(); diff --git a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceTest.java b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceTest.java index d93b316..b4ead61 100644 --- a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceTest.java +++ b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/IcyHttpDataSourceTest.java @@ -5,6 +5,7 @@ import org.robolectric.RobolectricTestRunner; import org.robolectric.annotation.Config; +import okhttp3.OkHttpClient; import saschpe.exoplayer2.ext.icy.test.Constants; import static org.junit.Assert.assertNotNull; @@ -15,10 +16,9 @@ public final class IcyHttpDataSourceTest { @Test public void createDataSourceFromBuilder() { // Arrange, act - IcyHttpDataSource source = new IcyHttpDataSource.Builder(Constants.TEST_USER_AGENT) - .setConnectTimeoutMillis(Constants.TEST_CONNECT_TIMEOUT_MS) - .setReadTimeoutMillis(Constants.TEST_READ_TIMEOUT_MS) - .setAllowCrossProtocolRedirects(Constants.TEST_ALLOW_CROSS_PROTOCOL_REDIRECTS) + OkHttpClient client = new OkHttpClient.Builder().build(); + IcyHttpDataSource source = new IcyHttpDataSource.Builder(client) + .setUserAgent(Constants.TEST_USER_AGENT) .build(); // Assert diff --git a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/test/Constants.java b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/test/Constants.java index 847b6c3..62337ea 100644 --- a/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/test/Constants.java +++ b/exoplayer2-ext-icy/src/test/java/saschpe/exoplayer2/ext/icy/test/Constants.java @@ -5,7 +5,4 @@ */ public final class Constants { public static final String TEST_USER_AGENT = "test-agent"; - public static final int TEST_CONNECT_TIMEOUT_MS = 100; - public static final int TEST_READ_TIMEOUT_MS = 100; - public static final boolean TEST_ALLOW_CROSS_PROTOCOL_REDIRECTS = true; }