Search in sources :

Example 1 with DataSourceException

use of com.google.android.exoplayer2.upstream.DataSourceException in project ExoPlayer by google.

the class CronetDataSource method open.

@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException {
    Assertions.checkNotNull(dataSpec);
    Assertions.checkState(!opened);
    operation.close();
    resetConnectTimeout();
    currentDataSpec = dataSpec;
    currentUrlRequest = buildRequest(dataSpec);
    currentUrlRequest.start();
    boolean requestStarted = blockUntilConnectTimeout();
    if (exception != null) {
        throw new OpenException(exception, currentDataSpec, getStatus(currentUrlRequest));
    } else if (!requestStarted) {
        // The timeout was reached before the connection was opened.
        throw new OpenException(new SocketTimeoutException(), dataSpec, getStatus(currentUrlRequest));
    }
    // Check for a valid response code.
    int responseCode = responseInfo.getHttpStatusCode();
    if (responseCode < 200 || responseCode > 299) {
        InvalidResponseCodeException exception = new InvalidResponseCodeException(responseCode, responseInfo.getAllHeaders(), currentDataSpec);
        if (responseCode == 416) {
            exception.initCause(new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE));
        }
        throw exception;
    }
    // Check for a valid content type.
    if (contentTypePredicate != null) {
        List<String> contentTypeHeaders = responseInfo.getAllHeaders().get(CONTENT_TYPE);
        String contentType = isEmpty(contentTypeHeaders) ? null : contentTypeHeaders.get(0);
        if (!contentTypePredicate.evaluate(contentType)) {
            throw new InvalidContentTypeException(contentType, currentDataSpec);
        }
    }
    // If we requested a range starting from a non-zero position and received a 200 rather than a
    // 206, then the server does not support partial requests. We'll need to manually skip to the
    // requested position.
    bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0;
    // Calculate the content length.
    if (!getIsCompressed(responseInfo)) {
        if (dataSpec.length != C.LENGTH_UNSET) {
            bytesRemaining = dataSpec.length;
        } else {
            bytesRemaining = getContentLength(responseInfo);
        }
    } else {
        // If the response is compressed then the content length will be that of the compressed data
        // which isn't what we want. Always use the dataSpec length in this case.
        bytesRemaining = currentDataSpec.length;
    }
    opened = true;
    if (listener != null) {
        listener.onTransferStart(this, dataSpec);
    }
    return bytesRemaining;
}
Also used : SocketTimeoutException(java.net.SocketTimeoutException) DataSourceException(com.google.android.exoplayer2.upstream.DataSourceException)

Example 2 with DataSourceException

use of com.google.android.exoplayer2.upstream.DataSourceException in project ExoPlayer by google.

the class OkHttpDataSource method open.

@Override
public long open(DataSpec dataSpec) throws HttpDataSourceException {
    this.dataSpec = dataSpec;
    this.bytesRead = 0;
    this.bytesSkipped = 0;
    Request request = makeRequest(dataSpec);
    try {
        response = callFactory.newCall(request).execute();
        responseByteStream = response.body().byteStream();
    } catch (IOException e) {
        throw new HttpDataSourceException("Unable to connect to " + dataSpec.uri.toString(), e, dataSpec, HttpDataSourceException.TYPE_OPEN);
    }
    int responseCode = response.code();
    // Check for a valid response code.
    if (!response.isSuccessful()) {
        Map<String, List<String>> headers = request.headers().toMultimap();
        closeConnectionQuietly();
        InvalidResponseCodeException exception = new InvalidResponseCodeException(responseCode, headers, dataSpec);
        if (responseCode == 416) {
            exception.initCause(new DataSourceException(DataSourceException.POSITION_OUT_OF_RANGE));
        }
        throw exception;
    }
    // Check for a valid content type.
    MediaType mediaType = response.body().contentType();
    String contentType = mediaType != null ? mediaType.toString() : null;
    if (contentTypePredicate != null && !contentTypePredicate.evaluate(contentType)) {
        closeConnectionQuietly();
        throw new InvalidContentTypeException(contentType, dataSpec);
    }
    // If we requested a range starting from a non-zero position and received a 200 rather than a
    // 206, then the server does not support partial requests. We'll need to manually skip to the
    // requested position.
    bytesToSkip = responseCode == 200 && dataSpec.position != 0 ? dataSpec.position : 0;
    // Determine the length of the data to be read, after skipping.
    if (dataSpec.length != C.LENGTH_UNSET) {
        bytesToRead = dataSpec.length;
    } else {
        long contentLength = response.body().contentLength();
        bytesToRead = contentLength != -1 ? (contentLength - bytesToSkip) : C.LENGTH_UNSET;
    }
    opened = true;
    if (listener != null) {
        listener.onTransferStart(this, dataSpec);
    }
    return bytesToRead;
}
Also used : DataSourceException(com.google.android.exoplayer2.upstream.DataSourceException) Request(okhttp3.Request) MediaType(okhttp3.MediaType) List(java.util.List) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException)

Example 3 with DataSourceException

use of com.google.android.exoplayer2.upstream.DataSourceException in project ExoPlayer by google.

the class CacheDataSource method openNextSource.

/**
   * Opens the next source. If the cache contains data spanning the current read position then
   * {@link #cacheReadDataSource} is opened to read from it. Else {@link #upstreamDataSource} is
   * opened to read from the upstream source and write into the cache.
   * @param initial Whether it is the initial open call.
   */
private boolean openNextSource(boolean initial) throws IOException {
    DataSpec dataSpec;
    CacheSpan span;
    if (currentRequestIgnoresCache) {
        span = null;
    } else if (blockOnCache) {
        try {
            span = cache.startReadWrite(key, readPosition);
        } catch (InterruptedException e) {
            throw new InterruptedIOException();
        }
    } else {
        span = cache.startReadWriteNonBlocking(key, readPosition);
    }
    if (span == null) {
        // The data is locked in the cache, or we're ignoring the cache. Bypass the cache and read
        // from upstream.
        currentDataSource = upstreamDataSource;
        dataSpec = new DataSpec(uri, readPosition, bytesRemaining, key, flags);
    } else if (span.isCached) {
        // Data is cached, read from cache.
        Uri fileUri = Uri.fromFile(span.file);
        long filePosition = readPosition - span.position;
        long length = span.length - filePosition;
        if (bytesRemaining != C.LENGTH_UNSET) {
            length = Math.min(length, bytesRemaining);
        }
        dataSpec = new DataSpec(fileUri, readPosition, filePosition, length, key, flags);
        currentDataSource = cacheReadDataSource;
    } else {
        // Data is not cached, and data is not locked, read from upstream with cache backing.
        long length;
        if (span.isOpenEnded()) {
            length = bytesRemaining;
        } else {
            length = span.length;
            if (bytesRemaining != C.LENGTH_UNSET) {
                length = Math.min(length, bytesRemaining);
            }
        }
        dataSpec = new DataSpec(uri, readPosition, length, key, flags);
        if (cacheWriteDataSource != null) {
            currentDataSource = cacheWriteDataSource;
            lockedSpan = span;
        } else {
            currentDataSource = upstreamDataSource;
            cache.releaseHoleSpan(span);
        }
    }
    currentRequestUnbounded = dataSpec.length == C.LENGTH_UNSET;
    boolean successful = false;
    long currentBytesRemaining = 0;
    try {
        currentBytesRemaining = currentDataSource.open(dataSpec);
        successful = true;
    } catch (IOException e) {
        // end of the stream.
        if (!initial && currentRequestUnbounded) {
            Throwable cause = e;
            while (cause != null) {
                if (cause instanceof DataSourceException) {
                    int reason = ((DataSourceException) cause).reason;
                    if (reason == DataSourceException.POSITION_OUT_OF_RANGE) {
                        e = null;
                        break;
                    }
                }
                cause = cause.getCause();
            }
        }
        if (e != null) {
            throw e;
        }
    }
    // bytesRemaining == C.LENGTH_UNSET) and got a resolved length from open() request
    if (currentRequestUnbounded && currentBytesRemaining != C.LENGTH_UNSET) {
        bytesRemaining = currentBytesRemaining;
        setContentLength(dataSpec.position + bytesRemaining);
    }
    return successful;
}
Also used : InterruptedIOException(java.io.InterruptedIOException) DataSourceException(com.google.android.exoplayer2.upstream.DataSourceException) DataSpec(com.google.android.exoplayer2.upstream.DataSpec) IOException(java.io.IOException) InterruptedIOException(java.io.InterruptedIOException) Uri(android.net.Uri)

Aggregations

DataSourceException (com.google.android.exoplayer2.upstream.DataSourceException)3 IOException (java.io.IOException)2 InterruptedIOException (java.io.InterruptedIOException)2 Uri (android.net.Uri)1 DataSpec (com.google.android.exoplayer2.upstream.DataSpec)1 SocketTimeoutException (java.net.SocketTimeoutException)1 List (java.util.List)1 MediaType (okhttp3.MediaType)1 Request (okhttp3.Request)1