diff --git a/RELEASENOTES.md b/RELEASENOTES.md index 56440638f5..215730473f 100644 --- a/RELEASENOTES.md +++ b/RELEASENOTES.md @@ -145,6 +145,10 @@ * Add support for non-square DASH thumbnail grids ([#1300](https://github.com/androidx/media/pull/1300)). * Add support for AVIF for API 34+. +* DataSource: + * Allow `ByteArrayDataSource` to resolve a URI to a byte array during + `open()`, instead of being hard-coded at construction + ([#1405](https://github.com/androidx/media/issues/1405)). * DRM: * Allow setting a `LoadErrorHandlingPolicy` on `DefaultDrmSessionManagerProvider` diff --git a/libraries/datasource/src/main/java/androidx/media3/datasource/ByteArrayDataSource.java b/libraries/datasource/src/main/java/androidx/media3/datasource/ByteArrayDataSource.java index d62445a886..eff8e71d15 100644 --- a/libraries/datasource/src/main/java/androidx/media3/datasource/ByteArrayDataSource.java +++ b/libraries/datasource/src/main/java/androidx/media3/datasource/ByteArrayDataSource.java @@ -15,13 +15,15 @@ */ package androidx.media3.datasource; +import static androidx.media3.common.util.Assertions.checkArgument; +import static androidx.media3.common.util.Assertions.checkNotNull; +import static androidx.media3.common.util.Assertions.checkStateNotNull; import static java.lang.Math.min; import android.net.Uri; import androidx.annotation.Nullable; import androidx.media3.common.C; import androidx.media3.common.PlaybackException; -import androidx.media3.common.util.Assertions; import androidx.media3.common.util.UnstableApi; import java.io.IOException; @@ -29,27 +31,55 @@ import java.io.IOException; @UnstableApi public final class ByteArrayDataSource extends BaseDataSource { - private final byte[] data; + /** Functional interface to resolve from {@link Uri} to {@link byte[]}. */ + public interface UriResolver { + /** + * Resolves a {@link Uri} to a {@link byte[]}. + * + *
Called during {@link DataSource#open(DataSpec)} from a loading thread, so can do blocking
+ * work.
+ *
+ * @return The resolved byte array.
+ * @throws IOException if the provided URI is not recognized, or an error occurs during
+ * resolution.
+ */
+ byte[] resolve(Uri uri) throws IOException;
+ }
+
+ private final UriResolver uriResolver;
@Nullable private Uri uri;
+ @Nullable private byte[] data;
private int readPosition;
private int bytesRemaining;
private boolean opened;
/**
+ * Creates an instance.
+ *
* @param data The data to be read.
*/
public ByteArrayDataSource(byte[] data) {
+ this(/* uriResolver= */ unusedUri -> data);
+ checkArgument(data.length > 0);
+ }
+
+ /**
+ * Creates an instance.
+ *
+ * @param uriResolver Function to resolve from {@link Uri} to {@link byte[]} during {@link
+ * #open(DataSpec)}.
+ */
+ public ByteArrayDataSource(UriResolver uriResolver) {
super(/* isNetwork= */ false);
- Assertions.checkNotNull(data);
- Assertions.checkArgument(data.length > 0);
- this.data = data;
+ this.uriResolver = checkNotNull(uriResolver);
}
@Override
public long open(DataSpec dataSpec) throws IOException {
- uri = dataSpec.uri;
transferInitializing(dataSpec);
+ uri = dataSpec.uri;
+ data = uriResolver.resolve(uri);
if (dataSpec.position > data.length) {
throw new DataSourceException(PlaybackException.ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE);
}
@@ -72,7 +102,7 @@ public final class ByteArrayDataSource extends BaseDataSource {
}
length = min(length, bytesRemaining);
- System.arraycopy(data, readPosition, buffer, offset, length);
+ System.arraycopy(checkStateNotNull(data), readPosition, buffer, offset, length);
readPosition += length;
bytesRemaining -= length;
bytesTransferred(length);
@@ -92,5 +122,6 @@ public final class ByteArrayDataSource extends BaseDataSource {
transferEnded();
}
uri = null;
+ data = null;
}
}
diff --git a/libraries/datasource/src/test/java/androidx/media3/datasource/ByteArrayDataSourceContractTest.java b/libraries/datasource/src/test/java/androidx/media3/datasource/ByteArrayDataSourceContractTest.java
index ac26c8b703..09a0e7a7ff 100644
--- a/libraries/datasource/src/test/java/androidx/media3/datasource/ByteArrayDataSourceContractTest.java
+++ b/libraries/datasource/src/test/java/androidx/media3/datasource/ByteArrayDataSourceContractTest.java
@@ -20,53 +20,45 @@ import androidx.media3.test.utils.DataSourceContractTest;
import androidx.media3.test.utils.TestUtil;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import com.google.common.collect.ImmutableList;
-import org.junit.Ignore;
-import org.junit.Test;
+import java.io.IOException;
import org.junit.runner.RunWith;
/** {@link DataSource} contract tests for {@link ByteArrayDataSource}. */
@RunWith(AndroidJUnit4.class)
public class ByteArrayDataSourceContractTest extends DataSourceContractTest {
- private static final byte[] DATA = TestUtil.buildTestData(20);
+ private static final Uri URI_1 = Uri.parse("uri1");
+ private static final byte[] DATA_1 = TestUtil.buildTestData(20);
+ private static final Uri URI_2 = Uri.parse("uri2");
+ private static final byte[] DATA_2 = TestUtil.buildTestData(10);
@Override
protected ImmutableList