Skip to content

Commit

Permalink
Switch to OkHttpDataSource
Browse files Browse the repository at this point in the history
As requested in ExoPlayer issue 3735 [0]. Changes exoplayer dependencies
to 'api' to ensure library users automatically get it.

[0] google/ExoPlayer#3735
  • Loading branch information
saschpe committed Sep 26, 2018
1 parent 757f603 commit 2eedb08
Show file tree
Hide file tree
Showing 8 changed files with 66 additions and 75 deletions.
1 change: 0 additions & 1 deletion example/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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

/**
Expand Down Expand Up @@ -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")
}
Expand Down
3 changes: 2 additions & 1 deletion exoplayer2-ext-icy/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@
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;

import java.util.HashMap;
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";
Expand Down Expand Up @@ -49,14 +52,13 @@ public interface IcyMetadataListener {
}

private IcyHttpDataSource(
@NonNull final String userAgent,
@NonNull Call.Factory callFactory,
@Nullable final String userAgent,
@Nullable final Predicate<String> contentTypePredicate,
@Nullable final TransferListener<? super DefaultHttpDataSource> 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<? super OkHttpDataSource> 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
}
Expand Down Expand Up @@ -202,18 +204,22 @@ private IcyMetadata parseMetadata(final String metaDataString) {
}

public final static class Builder {
private Call.Factory callFactory;
private String userAgent;
private Predicate<String> contentTypePredicate;
private TransferListener<? super DefaultHttpDataSource> listener;
private int connectTimeoutMillis;
private int readTimeoutMillis;
private boolean allowCrossProtocolRedirects;
private TransferListener<? super OkHttpDataSource> 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<String> contentTypePredicate) {
Expand All @@ -226,18 +232,8 @@ public Builder setTransferListener(@NonNull final TransferListener<? super DataS
return this;
}

public Builder setConnectTimeoutMillis(final int connectTimeoutMillis) {
this.connectTimeoutMillis = connectTimeoutMillis;
return this;
}

public Builder setReadTimeoutMillis(final int readTimeoutMillis) {
this.readTimeoutMillis = readTimeoutMillis;
return this;
}

public Builder setAllowCrossProtocolRedirects(final boolean allowCrossProtocolRedirects) {
this.allowCrossProtocolRedirects = allowCrossProtocolRedirects;
public Builder setCacheControl(@NonNull final CacheControl cacheControl) {
this.cacheControl = cacheControl;
return this;
}

Expand All @@ -258,12 +254,11 @@ public Builder setIcyMetadataListener(@NonNull final IcyMetadataListener icyMeta

IcyHttpDataSource build() {
final IcyHttpDataSource dataSource =
new IcyHttpDataSource(userAgent,
new IcyHttpDataSource(callFactory,
userAgent,
contentTypePredicate,
listener,
connectTimeoutMillis,
readTimeoutMillis,
allowCrossProtocolRedirects,
cacheControl,
defaultRequestProperties);
dataSource.icyHeadersListener = icyHeadersListener;
dataSource.icyMetadataListener = icyMetadataListener;
Expand Down Expand Up @@ -346,7 +341,7 @@ public String toString() {

/**
* Container for stream title and URL.
*
* <p>
* The exact contents isn't specified and implementation specific. It's therefore up to the
* user to figure what format a given stream returns.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> contentTypePredicate;
private TransferListener<? super DataSource> listener;
private int connectTimeoutMillis;
private int readTimeoutMillis;
private boolean allowCrossProtocolRedirects;
private CacheControl cacheControl;
private IcyHttpDataSource.IcyHeadersListener icyHeadersListener;
private IcyHttpDataSource.IcyMetadataListener icyMetadataListener;

Expand All @@ -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<? super DataSource> 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<String> contentTypePredicate) {
factory.contentTypePredicate = contentTypePredicate;
return this;
}

public Builder setReadTimeoutMillis(@NonNull final int readTimeoutMillis) {
factory.readTimeoutMillis = readTimeoutMillis;
public Builder setTransferListener(@NonNull final TransferListener<? super DataSource> 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;
}

Expand All @@ -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)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

0 comments on commit 2eedb08

Please sign in to comment.