@Override public long open(DataSpec dataSpec) throws EncryptedFileDataSourceException { // if we're open, we shouldn't need to open again, fast-fail if (mOpened) { return mBytesRemaining; } // #getUri is part of the contract... mUri = dataSpec.uri; // put all our throwable work in a single block, wrap the error in a custom Exception try { setupInputStream(); skipToPosition(dataSpec); computeBytesRemaining(dataSpec); } catch (IOException e) { throw new EncryptedFileDataSourceException(e); } // if we made it this far, we're open mOpened = true; // notify if (mTransferListener != null) { mTransferListener.onTransferStart(this, dataSpec); } // report return mBytesRemaining; }
@Override public long open(DataSpec dataSpec) throws IOException { Assertions.checkState(dataSource == null); String scheme = dataSpec.uri.getScheme(); if (Util.isLocalFileUri(dataSpec.uri)) { if (dataSpec.uri.getPath().startsWith("/android_asset/")) { dataSource = getAssetDataSource(); } else { dataSource = getFileDataSource(); } } else if (SCHEME_ASSET.equals(scheme)) { dataSource = getAssetDataSource(); } else if (SCHEME_CONTENT.equals(scheme)) { dataSource = getContentDataSource(); } else if (SCHEME_RTMP.equals(scheme)) { dataSource = getRtmpDataSource(); } else { dataSource = baseDataSource; } // Open the source and return. return dataSource.open(dataSpec); }
@Override public long open(DataSpec dataSpec) throws FileDataSourceException { try { uri = dataSpec.uri; file = new RandomAccessFile(dataSpec.uri.getPath(), "r"); boolean ass = isEncrypted(file); if (ass) { file.seek(dataSpec.position + length); } bytesRemaining = dataSpec.length == C.LENGTH_UNSET ? file.length() - dataSpec.position : dataSpec.length; if (bytesRemaining < 0) { throw new EOFException(); } } catch (IOException e) { throw new FileDataSourceException(e); } opened = true; if (listener != null) { listener.onTransferStart(this, dataSpec); } return bytesRemaining; }
/** * Sets a {@link CachingCounters} to contain the number of bytes already downloaded and the * length for the content defined by a {@code dataSpec}. {@link CachingCounters#newlyCachedBytes} * is reset to 0. * * @param dataSpec Defines the data to be checked. * @param cache A {@link Cache} which has the data. * @param counters The {@link CachingCounters} to update. */ public static void getCached(DataSpec dataSpec, Cache cache, CachingCounters counters) { String key = getKey(dataSpec); long start = dataSpec.absoluteStreamPosition; long left = dataSpec.length != C.LENGTH_UNSET ? dataSpec.length : cache.getContentLength(key); counters.contentLength = left; counters.alreadyCachedBytes = 0; counters.newlyCachedBytes = 0; while (left != 0) { long blockLength = cache.getCachedBytes(key, start, left != C.LENGTH_UNSET ? left : Long.MAX_VALUE); if (blockLength > 0) { counters.alreadyCachedBytes += blockLength; } else { blockLength = -blockLength; if (blockLength == Long.MAX_VALUE) { return; } } start += blockLength; left -= left == C.LENGTH_UNSET ? 0 : blockLength; } }
@Override protected List<SampleGroup> doInBackground(String... uris) { List<SampleGroup> result = new ArrayList<>(); Context context = getApplicationContext(); String userAgent = Util.getUserAgent(context, "ExoPlayerDemo"); DataSource dataSource = new DefaultDataSource(context, null, userAgent, false); for (String uri : uris) { DataSpec dataSpec = new DataSpec(Uri.parse(uri)); InputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { readSampleGroups(new JsonReader(new InputStreamReader(inputStream, "UTF-8")), result); } catch (Exception e) { Log.e(TAG, "Error loading sample list: " + uri, e); sawError = true; } finally { Util.closeQuietly(dataSource); } } return result; }
private byte[] executePost(String url, byte[] data, Map<String, String> requestProperties) throws IOException { HttpDataSource dataSource = dataSourceFactory.createDataSource(); if (requestProperties != null) { for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) { dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue()); } } DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { return Util.toByteArray(inputStream); } finally { Util.closeQuietly(inputStream); } }
private void maybeLoadInitData() throws IOException, InterruptedException { if (previousExtractor == extractor || initLoadCompleted || initDataSpec == null) { // According to spec, for packed audio, initDataSpec is expected to be null. return; } DataSpec initSegmentDataSpec = Util.getRemainderDataSpec(initDataSpec, initSegmentBytesLoaded); try { ExtractorInput input = new DefaultExtractorInput(initDataSource, initSegmentDataSpec.absoluteStreamPosition, initDataSource.open(initSegmentDataSpec)); try { int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { result = extractor.read(input, null); } } finally { initSegmentBytesLoaded = (int) (input.getPosition() - initDataSpec.absoluteStreamPosition); } } finally { Util.closeQuietly(dataSource); } initLoadCompleted = true; }
private static byte[] executePost(HttpDataSource.Factory dataSourceFactory, String url, byte[] data, Map<String, String> requestProperties) throws IOException { HttpDataSource dataSource = dataSourceFactory.createDataSource(); if (requestProperties != null) { for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) { dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue()); } } DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { return Util.toByteArray(inputStream); } finally { Util.closeQuietly(inputStream); } }
public void loadError(final DataSpec dataSpec, final int dataType, final int trackType, final Format trackFormat, final int trackSelectionReason, final Object trackSelectionData, final long mediaStartTimeUs, final long mediaEndTimeUs, final long elapsedRealtimeMs, final long loadDurationMs, final long bytesLoaded, final IOException error, final boolean wasCanceled) { if (listener != null) { handler.post(new Runnable() { @Override public void run() { listener.onLoadError(dataSpec, dataType, trackType, trackFormat, trackSelectionReason, trackSelectionData, adjustMediaTime(mediaStartTimeUs), adjustMediaTime(mediaEndTimeUs), elapsedRealtimeMs, loadDurationMs, bytesLoaded, error, wasCanceled); } }); } }
@SuppressWarnings("NonAtomicVolatileUpdate") @Override public void load() throws IOException, InterruptedException { DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded); try { // Create and open the input. ExtractorInput input = new DefaultExtractorInput(dataSource, loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec)); if (bytesLoaded == 0) { extractorWrapper.init(null); } // Load and decode the initialization data. try { Extractor extractor = extractorWrapper.extractor; int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { result = extractor.read(input, null); } Assertions.checkState(result != Extractor.RESULT_SEEK); } finally { bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition); } } finally { Util.closeQuietly(dataSource); } }
@Override public void load() throws IOException, InterruptedException { // We always load from the beginning, so reset the sampleSize to 0. sampleSize = 0; try { // Create and open the input. dataSource.open(new DataSpec(uri)); // Load the sample data. int result = 0; while (result != C.RESULT_END_OF_INPUT) { sampleSize += result; if (sampleData == null) { sampleData = new byte[INITIAL_SAMPLE_SIZE]; } else if (sampleSize == sampleData.length) { sampleData = Arrays.copyOf(sampleData, sampleData.length * 2); } result = dataSource.read(sampleData, sampleSize, sampleData.length - sampleSize); } } finally { Util.closeQuietly(dataSource); } }
public void testUnsatisfiableRange() throws Exception { // Bounded request but the content length is unknown. This forces all data to be cached but not // the length assertCacheAndRead(false, true); // Now do an unbounded request. This will read all of the data from cache and then try to read // more from upstream which will cause to a 416 so CDS will store the length. CacheDataSource cacheDataSource = createCacheDataSource(true, true); assertReadDataContentLength(cacheDataSource, true, true); // If the user try to access off range then it should throw an IOException try { cacheDataSource = createCacheDataSource(false, false); cacheDataSource.open(new DataSpec(Uri.EMPTY, TEST_DATA.length, 5, KEY_1)); fail(); } catch (IOException e) { // success } }
@SuppressWarnings({"checkstyle:ParameterNumber", "PMD.ExcessiveParameterList"}) // This implements an interface method defined by ExoPlayer @Override public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) { for (AdaptiveMediaSourceEventListener listener : listeners) { listener.onLoadStarted( dataSpec, dataType, trackType, trackFormat, trackSelectionReason, trackSelectionData, mediaStartTimeMs, mediaEndTimeMs, elapsedRealtimeMs ); } }
@SuppressWarnings({"checkstyle:ParameterNumber", "PMD.ExcessiveParameterList"}) // This implements an interface method defined by ExoPlayer @Override public void onLoadStarted(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs) { HashMap<String, String> callingMethodParameters = new HashMap<>(); callingMethodParameters.put(Parameters.DATA_SPEC, String.valueOf(dataSpec)); callingMethodParameters.put(Parameters.DATA_TYPE, String.valueOf(dataType)); callingMethodParameters.put(Parameters.TRACK_TYPE, String.valueOf(trackType)); callingMethodParameters.put(Parameters.TRACK_FORMAT, String.valueOf(trackFormat)); callingMethodParameters.put(Parameters.TRACK_SELECTION_REASON, String.valueOf(trackSelectionReason)); callingMethodParameters.put(Parameters.TRACK_SELECTION_DATA, String.valueOf(trackSelectionData)); callingMethodParameters.put(Parameters.MEDIA_START_TIME_MS, String.valueOf(mediaStartTimeMs)); callingMethodParameters.put(Parameters.MEDIA_END_TIME_MS, String.valueOf(mediaEndTimeMs)); callingMethodParameters.put(Parameters.ELAPSED_REALTIME_MS, String.valueOf(elapsedRealtimeMs)); infoListener.onNewInfo(Methods.ON_LOAD_STARTED, callingMethodParameters); }
@Override public long open(DataSpec dataSpec) throws IOException { try { uri = dataSpec.uri; flags = dataSpec.flags; key = dataSpec.key; readPosition = dataSpec.position; currentRequestIgnoresCache = (ignoreCacheOnError && seenCacheError) || (bypassUnboundedRequests && dataSpec.length == C.LENGTH_UNSET); if (dataSpec.length != C.LENGTH_UNSET || currentRequestIgnoresCache) { bytesRemaining = dataSpec.length; } else { bytesRemaining = cache.getContentLength(key); if (bytesRemaining != C.LENGTH_UNSET) { bytesRemaining -= dataSpec.position; } } openNextSource(true); return bytesRemaining; } catch (IOException e) { handleBeforeThrow(e); throw e; } }
@Override public void load() throws IOException, InterruptedException { // We always load from the beginning, so reset the sampleSize to 0. sampleSize = 0; try { // Create and open the input. dataSource.open(new DataSpec(uri)); // Load the sample data. int result = 0; while (result != C.RESULT_END_OF_INPUT) { sampleSize += result; if (sampleData == null) { sampleData = new byte[INITIAL_SAMPLE_SIZE]; } else if (sampleSize == sampleData.length) { sampleData = Arrays.copyOf(sampleData, sampleData.length * 2); } result = dataSource.read(sampleData, sampleSize, sampleData.length - sampleSize); } } finally { dataSource.close(); } }
@SuppressWarnings("NonAtomicVolatileUpdate") @Override public void load() throws IOException, InterruptedException { DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded); try { // Create and open the input. long length = dataSource.open(loadDataSpec); if (length != C.LENGTH_UNSET) { length += bytesLoaded; } ExtractorInput extractorInput = new DefaultExtractorInput(dataSource, bytesLoaded, length); DefaultTrackOutput trackOutput = getTrackOutput(); trackOutput.formatWithOffset(sampleFormat, 0); // Load the sample data. int result = 0; while (result != C.RESULT_END_OF_INPUT) { bytesLoaded += result; result = trackOutput.sampleData(extractorInput, Integer.MAX_VALUE, true); } int sampleSize = bytesLoaded; trackOutput.sampleMetadata(startTimeUs, C.BUFFER_FLAG_KEY_FRAME, sampleSize, 0, null); } finally { dataSource.close(); } loadCompleted = true; }
@SuppressWarnings("NonAtomicVolatileUpdate") @Override public void load() throws IOException, InterruptedException { DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded); try { // Create and open the input. ExtractorInput input = new DefaultExtractorInput(dataSource, loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec)); if (bytesLoaded == 0) { // Set the target to ourselves. extractorWrapper.init(this, this); } // Load and decode the initialization data. try { int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { result = extractorWrapper.read(input); } } finally { bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition); } } finally { dataSource.close(); } }
@Override public void load() throws IOException, InterruptedException { DataSpec loadDataSpec = Util.getRemainderDataSpec(dataSpec, bytesLoaded); try { ExtractorInput input = new DefaultExtractorInput(dataSource, loadDataSpec.absoluteStreamPosition, dataSource.open(loadDataSpec)); try { int result = Extractor.RESULT_CONTINUE; while (result == Extractor.RESULT_CONTINUE && !loadCanceled) { result = extractor.read(input, null); } } finally { bytesLoaded = (int) (input.getPosition() - dataSpec.absoluteStreamPosition); } } finally { dataSource.close(); } }
private static Chunk newInitializationChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, RangedUri initializationUri, RangedUri indexUri) { RangedUri requestUri; String baseUrl = representationHolder.representation.baseUrl; if (initializationUri != null) { // It's common for initialization and index data to be stored adjacently. Attempt to merge // the two requests together to request both at once. requestUri = initializationUri.attemptMerge(indexUri, baseUrl); if (requestUri == null) { requestUri = initializationUri; } } else { requestUri = indexUri; } DataSpec dataSpec = new DataSpec(requestUri.resolveUri(baseUrl), requestUri.start, requestUri.length, representationHolder.representation.getCacheKey()); return new InitializationChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, representationHolder.extractorWrapper); }
private void assertReadData(CacheDataSource cacheDataSource, boolean unknownLength, int position, int length) throws IOException { int actualLength = TEST_DATA.length - position; if (length != C.LENGTH_UNSET) { actualLength = Math.min(actualLength, length); } assertEquals(unknownLength ? length : actualLength, cacheDataSource.open(new DataSpec(Uri.EMPTY, position, length, KEY_1))); byte[] buffer = new byte[100]; int index = 0; while (true) { int read = cacheDataSource.read(buffer, index, buffer.length - index); if (read == C.RESULT_END_OF_INPUT) { break; } index += read; } assertEquals(actualLength, index); MoreAsserts.assertEquals(Arrays.copyOfRange(TEST_DATA, position, position + actualLength), Arrays.copyOf(buffer, index)); cacheDataSource.close(); }
@Override public long open(DataSpec dataSpec) throws IOException { try { uri = dataSpec.uri; flags = dataSpec.flags; key = dataSpec.key != null ? dataSpec.key : uri.toString(); readPosition = dataSpec.position; currentRequestIgnoresCache = (ignoreCacheOnError && seenCacheError) || (dataSpec.length == C.LENGTH_UNSET && ignoreCacheForUnsetLengthRequests); if (dataSpec.length != C.LENGTH_UNSET || currentRequestIgnoresCache) { bytesRemaining = dataSpec.length; } else { bytesRemaining = cache.getContentLength(key); if (bytesRemaining != C.LENGTH_UNSET) { bytesRemaining -= dataSpec.position; } } openNextSource(true); return bytesRemaining; } catch (IOException e) { handleBeforeThrow(e); throw e; } }
private Chunk newMediaChunk(RepresentationHolder representationHolder, DataSource dataSource, Format trackFormat, int trackSelectionReason, Object trackSelectionData, Format sampleFormat, int segmentNum) { Representation representation = representationHolder.representation; long startTimeUs = representationHolder.getSegmentStartTimeUs(segmentNum); long endTimeUs = representationHolder.getSegmentEndTimeUs(segmentNum); RangedUri segmentUri = representationHolder.getSegmentUrl(segmentNum); DataSpec dataSpec = new DataSpec(segmentUri.getUri(), segmentUri.start, segmentUri.length, representation.getCacheKey()); if (representationHolder.extractorWrapper == null) { return new SingleSampleMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, segmentNum, trackFormat); } else { long sampleOffsetUs = -representation.presentationTimeOffsetUs; return new ContainerMediaChunk(dataSource, dataSpec, trackFormat, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, segmentNum, sampleOffsetUs, representationHolder.extractorWrapper, sampleFormat); } }
private byte[] executePost(String url, byte[] data, Map<String, String> requestProperties) throws IOException { HttpDataSource dataSource = dataSourceFactory.createDataSource(); if (requestProperties != null) { for (Map.Entry<String, String> requestProperty : requestProperties.entrySet()) { dataSource.setRequestProperty(requestProperty.getKey(), requestProperty.getValue()); } } DataSpec dataSpec = new DataSpec(Uri.parse(url), data, 0, 0, C.LENGTH_UNSET, null, DataSpec.FLAG_ALLOW_GZIP); DataSourceInputStream inputStream = new DataSourceInputStream(dataSource, dataSpec); try { return Util.toByteArray(inputStream); } finally { inputStream.close(); } }
public void testSkipFullyLarge() throws Exception { // Tests skipping an amount of data that's larger than any internal scratch space. int largeSkipSize = 1024 * 1024; FakeDataSource.Builder builder = new FakeDataSource.Builder(); builder.appendReadData(new byte[largeSkipSize]); FakeDataSource testDataSource = builder.build(); testDataSource.open(new DataSpec(Uri.parse(TEST_URI))); DefaultExtractorInput input = new DefaultExtractorInput(testDataSource, 0, C.LENGTH_UNSET); input.skipFully(largeSkipSize); assertEquals(largeSkipSize, input.getPosition()); // Check that we fail with EOFException we skip again. try { input.skipFully(1); fail(); } catch (EOFException e) { // Expected. } }
private void computeBytesRemaining(DataSpec dataSpec) throws IOException { if (dataSpec.length != C.LENGTH_UNSET) { mBytesRemaining = dataSpec.length; } else { mBytesRemaining = mInputStream.available(); if (mBytesRemaining == Integer.MAX_VALUE) { mBytesRemaining = C.LENGTH_UNSET; } } }
private DefaultProgressDownloader( Uri uri, String customCacheKey, DownloaderConstructorHelper constructorHelper) { this.dataSpec = new DataSpec(uri, 0, C.LENGTH_UNSET, customCacheKey, 0); this.cache = constructorHelper.getCache(); this.dataSource = constructorHelper.buildCacheDataSource(false); this.priorityTaskManager = constructorHelper.getPriorityTaskManager(); cachingCounters = new DefaultCacheUtil.CachingCounters(); }
@Override public long open(DataSpec dataSpec) throws IOException { Assertions.checkState(dataSource == null); // Choose the correct source for the scheme. //选择正确的数据源方案 String scheme = dataSpec.uri.getScheme(); //如果URI是一个本地文件路径或本地文件的引用。 Timber.e("解密:000000," + scheme + ",path:" + dataSpec.uri.getPath()); if (Util.isLocalFileUri(dataSpec.uri)) { //如果路径尾包含aitrip的文件名,使用解密类 if (dataSpec.uri.getPath().endsWith(".aitrip")) { Aes128DataSource aes128DataSource = new Aes128DataSource(getFileDataSource(), Aikey.getBytes(), Aikey.getBytes()); dataSource = aes128DataSource; } else {//否则,正常解析mp3 if (dataSpec.uri.getPath().startsWith("/android_asset/")) { dataSource = getAssetDataSource(); } else { dataSource = getFileDataSource(); } } } else if (SCHEME_ASSET.equals(scheme)) { dataSource = getAssetDataSource(); } else if (SCHEME_CONTENT.equals(scheme)) { dataSource = getContentDataSource(); } else if (SCHEME_RTMP.equals(scheme)) { dataSource = getRtmpDataSource(); } else { dataSource = baseDataSource; } // Open the source and return. return dataSource.open(dataSpec); }
@Override public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) { printInternalError("loadError", error); }
@Override public long open(DataSpec dataSpec) throws IOException { Assertions.checkState(!opened); // DataSpec requires a matching close call even if open fails. opened = true; uri = dataSpec.uri; openedDataSpecs.add(dataSpec); // If the source knows that the request is unsatisfiable then fail. if (dataSpec.position >= totalLength || (dataSpec.length != C.LENGTH_UNSET && (dataSpec.position + dataSpec.length > totalLength))) { throw new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE); } // Scan through the segments, configuring them for the current read. boolean findingCurrentSegmentIndex = true; currentSegmentIndex = 0; int scannedLength = 0; for (Segment segment : segments) { segment.bytesRead = (int) Math.min(Math.max(0, dataSpec.position - scannedLength), segment.length); scannedLength += segment.length; findingCurrentSegmentIndex &= segment.isErrorSegment() ? segment.exceptionCleared : segment.bytesRead == segment.length; if (findingCurrentSegmentIndex) { currentSegmentIndex++; } } // Configure bytesRemaining, and return. if (dataSpec.length == C.LENGTH_UNSET) { bytesRemaining = totalLength - dataSpec.position; return simulateUnknownLength ? C.LENGTH_UNSET : bytesRemaining; } else { bytesRemaining = dataSpec.length; return bytesRemaining; } }
/** * Returns the {@link DataSpec} instances passed to {@link #open(DataSpec)} since the last call to * this method. */ public DataSpec[] getAndClearOpenedDataSpecs() { DataSpec[] dataSpecs = new DataSpec[openedDataSpecs.size()]; openedDataSpecs.toArray(dataSpecs); openedDataSpecs.clear(); return dataSpecs; }
@Override public void onLoadError(DataSpec dataSpec, int dataType, int trackType, Format trackFormat, int trackSelectionReason, Object trackSelectionData, long mediaStartTimeMs, long mediaEndTimeMs, long elapsedRealtimeMs, long loadDurationMs, long bytesLoaded, IOException error, boolean wasCanceled) { Timber.tag(TAG).i("loadError %s", error.getMessage()); }
@Override public long open(DataSpec dataSpec) throws IOException { if (PartAuthority.isLocalUri(dataSpec.uri)) dataSource = partDataSource; else dataSource = defaultDataSource; return dataSource.open(dataSpec); }
@Override protected HttpURLConnection makeConnection(DataSpec dataSpec) throws IOException { // open a http connection for Icy-Metadata (Shoutcast) LogHelper.i(LOG_TAG, "makeConnection[" + dataSpec.position + "-" + dataSpec.length); URL url = new URL(dataSpec.uri.toString()); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setRequestProperty("Icy-Metadata", "1"); return connection; }
/** * @param dataSource The source from which the data should be loaded. * @param dataSpec Defines the data to be loaded. * @param initDataSpec Defines the initialization data to be fed to new extractors. May be null. * @param hlsUrl The url of the playlist from which this chunk was obtained. * @param muxedCaptionFormats List of muxed caption {@link Format}s. Null if no closed caption * information is available in the master playlist. * @param trackSelectionReason See {@link #trackSelectionReason}. * @param trackSelectionData See {@link #trackSelectionData}. * @param startTimeUs The start time of the chunk in microseconds. * @param endTimeUs The end time of the chunk in microseconds. * @param chunkIndex The media sequence number of the chunk. * @param discontinuitySequenceNumber The discontinuity sequence number of the chunk. * @param isMasterTimestampSource True if the chunk can initialize the timestamp adjuster. * @param timestampAdjuster Adjuster corresponding to the provided discontinuity sequence number. * @param previousChunk The {@link HlsMediaChunk} that preceded this one. May be null. * @param encryptionKey For AES encryption chunks, the encryption key. * @param encryptionIv For AES encryption chunks, the encryption initialization vector. */ public HlsMediaChunk(DataSource dataSource, DataSpec dataSpec, DataSpec initDataSpec, HlsUrl hlsUrl, List<Format> muxedCaptionFormats, int trackSelectionReason, Object trackSelectionData, long startTimeUs, long endTimeUs, int chunkIndex, int discontinuitySequenceNumber, boolean isMasterTimestampSource, TimestampAdjuster timestampAdjuster, HlsMediaChunk previousChunk, byte[] encryptionKey, byte[] encryptionIv) { super(buildDataSource(dataSource, encryptionKey, encryptionIv), dataSpec, hlsUrl.format, trackSelectionReason, trackSelectionData, startTimeUs, endTimeUs, chunkIndex); this.discontinuitySequenceNumber = discontinuitySequenceNumber; this.initDataSpec = initDataSpec; this.hlsUrl = hlsUrl; this.muxedCaptionFormats = muxedCaptionFormats; this.isMasterTimestampSource = isMasterTimestampSource; this.timestampAdjuster = timestampAdjuster; // Note: this.dataSource and dataSource may be different. this.isEncrypted = this.dataSource instanceof Aes128DataSource; lastPathSegment = dataSpec.uri.getLastPathSegment(); isPackedAudio = lastPathSegment.endsWith(AAC_FILE_EXTENSION) || lastPathSegment.endsWith(AC3_FILE_EXTENSION) || lastPathSegment.endsWith(EC3_FILE_EXTENSION) || lastPathSegment.endsWith(MP3_FILE_EXTENSION); if (previousChunk != null) { id3Decoder = previousChunk.id3Decoder; id3Data = previousChunk.id3Data; previousExtractor = previousChunk.extractor; shouldSpliceIn = previousChunk.hlsUrl != hlsUrl; needNewExtractor = previousChunk.discontinuitySequenceNumber != discontinuitySequenceNumber || shouldSpliceIn; } else { id3Decoder = isPackedAudio ? new Id3Decoder() : null; id3Data = isPackedAudio ? new ParsableByteArray(Id3Decoder.ID3_HEADER_LENGTH) : null; previousExtractor = null; shouldSpliceIn = false; needNewExtractor = true; } initDataSource = dataSource; uid = UID_SOURCE.getAndIncrement(); }
public void loadStarted(final DataSpec dataSpec, final int dataType, final int trackType, final Format trackFormat, final int trackSelectionReason, final Object trackSelectionData, final long mediaStartTimeUs, final long mediaEndTimeUs, final long elapsedRealtimeMs) { if (listener != null) { handler.post(new Runnable() { @Override public void run() { listener.onLoadStarted(dataSpec, dataType, trackType, trackFormat, trackSelectionReason, trackSelectionData, adjustMediaTime(mediaStartTimeUs), adjustMediaTime(mediaEndTimeUs), elapsedRealtimeMs); } }); } }