15
15
*/
16
16
package androidx .media3 .datasource ;
17
17
18
+ import static androidx .media3 .common .util .Assertions .checkArgument ;
19
+ import static androidx .media3 .common .util .Assertions .checkNotNull ;
20
+ import static androidx .media3 .common .util .Assertions .checkStateNotNull ;
18
21
import static java .lang .Math .min ;
19
22
20
23
import android .net .Uri ;
21
24
import androidx .annotation .Nullable ;
22
25
import androidx .media3 .common .C ;
23
26
import androidx .media3 .common .PlaybackException ;
24
- import androidx .media3 .common .util .Assertions ;
25
27
import androidx .media3 .common .util .UnstableApi ;
26
28
import java .io .IOException ;
27
29
28
30
/** A {@link DataSource} for reading from a byte array. */
29
31
@ UnstableApi
30
32
public final class ByteArrayDataSource extends BaseDataSource {
31
33
32
- private final byte [] data ;
34
+ /** Functional interface to resolve from {@link Uri} to {@link byte[]}. */
35
+ public interface UriResolver {
36
+ /**
37
+ * Resolves a {@link Uri} to a {@link byte[]}.
38
+ *
39
+ * <p>Called during {@link DataSource#open(DataSpec)} from a loading thread, so can do blocking
40
+ * work.
41
+ *
42
+ * @return The resolved byte array.
43
+ * @throws IOException if the provided URI is not recognized, or an error occurs during
44
+ * resolution.
45
+ */
46
+ byte [] resolve (Uri uri ) throws IOException ;
47
+ }
48
+
49
+ private final UriResolver uriResolver ;
33
50
34
51
@ Nullable private Uri uri ;
52
+ @ Nullable private byte [] data ;
35
53
private int readPosition ;
36
54
private int bytesRemaining ;
37
55
private boolean opened ;
38
56
39
57
/**
58
+ * Creates an instance.
59
+ *
40
60
* @param data The data to be read.
41
61
*/
42
62
public ByteArrayDataSource (byte [] data ) {
63
+ this (/* uriResolver= */ unusedUri -> data );
64
+ checkArgument (data .length > 0 );
65
+ }
66
+
67
+ /**
68
+ * Creates an instance.
69
+ *
70
+ * @param uriResolver Function to resolve from {@link Uri} to {@link byte[]} during {@link
71
+ * #open(DataSpec)}.
72
+ */
73
+ public ByteArrayDataSource (UriResolver uriResolver ) {
43
74
super (/* isNetwork= */ false );
44
- Assertions .checkNotNull (data );
45
- Assertions .checkArgument (data .length > 0 );
46
- this .data = data ;
75
+ this .uriResolver = checkNotNull (uriResolver );
47
76
}
48
77
49
78
@ Override
50
79
public long open (DataSpec dataSpec ) throws IOException {
51
- uri = dataSpec .uri ;
52
80
transferInitializing (dataSpec );
81
+ uri = dataSpec .uri ;
82
+ data = uriResolver .resolve (uri );
53
83
if (dataSpec .position > data .length ) {
54
84
throw new DataSourceException (PlaybackException .ERROR_CODE_IO_READ_POSITION_OUT_OF_RANGE );
55
85
}
@@ -72,7 +102,7 @@ public int read(byte[] buffer, int offset, int length) {
72
102
}
73
103
74
104
length = min (length , bytesRemaining );
75
- System .arraycopy (data , readPosition , buffer , offset , length );
105
+ System .arraycopy (checkStateNotNull ( data ) , readPosition , buffer , offset , length );
76
106
readPosition += length ;
77
107
bytesRemaining -= length ;
78
108
bytesTransferred (length );
@@ -92,5 +122,6 @@ public void close() {
92
122
transferEnded ();
93
123
}
94
124
uri = null ;
125
+ data = null ;
95
126
}
96
127
}
0 commit comments