public final class

DownloadRequest

extends java.lang.Object

 java.lang.Object

↳androidx.media3.exoplayer.offline.DownloadRequest

Gradle dependencies

compile group: 'androidx.media3', name: 'media3-exoplayer', version: '1.5.0-alpha01'

  • groupId: androidx.media3
  • artifactId: media3-exoplayer
  • version: 1.5.0-alpha01

Artifact androidx.media3:media3-exoplayer:1.5.0-alpha01 it located at Google repository (https://maven.google.com/)

Overview

Defines content to be downloaded.

Summary

Fields
public static final <any>CREATOR

public final java.lang.StringcustomCacheKey

Custom key for cache indexing, or null.

public final byte[]data

Application defined data associated with the download.

public final java.lang.Stringid

The unique content id.

public final byte[]keySetId

The key set id of the offline licence if the content is protected with DRM.

public final java.lang.StringmimeType

The MIME type of this content.

public final java.util.List<StreamKey>streamKeys

Stream keys to be downloaded.

public final Uriuri

The uri being downloaded.

Methods
public DownloadRequestcopyWithId(java.lang.String id)

Returns a copy with the specified ID.

public DownloadRequestcopyWithKeySetId(byte[] keySetId[])

Returns a copy with the specified key set ID.

public DownloadRequestcopyWithMergedRequest(DownloadRequest newRequest)

Returns the result of merging newRequest into this request.

public intdescribeContents()

public booleanequals(java.lang.Object o)

public final inthashCode()

public MediaItemtoMediaItem()

Returns a MediaItem for the content defined by the request.

public java.lang.StringtoString()

public voidwriteToParcel(Parcel dest, int flags)

from java.lang.Objectclone, finalize, getClass, notify, notifyAll, wait, wait, wait

Fields

public final java.lang.String id

The unique content id.

public final Uri uri

The uri being downloaded.

public final java.lang.String mimeType

The MIME type of this content. Used as a hint to infer the content's type (DASH, HLS, SmoothStreaming). If null, a DownloadService will infer the content type from the DownloadRequest.uri.

public final java.util.List<StreamKey> streamKeys

Stream keys to be downloaded. If empty, all streams will be downloaded.

public final byte[] keySetId

The key set id of the offline licence if the content is protected with DRM.

public final java.lang.String customCacheKey

Custom key for cache indexing, or null. Must be null for DASH, HLS and SmoothStreaming downloads.

public final byte[] data

Application defined data associated with the download. May be empty.

public static final <any> CREATOR

Methods

public DownloadRequest copyWithId(java.lang.String id)

Returns a copy with the specified ID.

Parameters:

id: The ID of the copy.

Returns:

The copy with the specified ID.

public DownloadRequest copyWithKeySetId(byte[] keySetId[])

Returns a copy with the specified key set ID.

Parameters:

keySetId: The key set ID of the copy.

Returns:

The copy with the specified key set ID.

public DownloadRequest copyWithMergedRequest(DownloadRequest newRequest)

Returns the result of merging newRequest into this request. The requests must have the same DownloadRequest.id.

The resulting request contains the stream keys from both requests. For all other member variables, those in newRequest are preferred.

Parameters:

newRequest: The request being merged.

Returns:

The merged result.

public MediaItem toMediaItem()

Returns a MediaItem for the content defined by the request.

public java.lang.String toString()

public boolean equals(java.lang.Object o)

public final int hashCode()

public int describeContents()

public void writeToParcel(Parcel dest, int flags)

Source

/*
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package androidx.media3.exoplayer.offline;

import static androidx.media3.common.util.Util.castNonNull;

import android.net.Uri;
import android.os.Parcel;
import android.os.Parcelable;
import androidx.annotation.Nullable;
import androidx.media3.common.C;
import androidx.media3.common.MediaItem;
import androidx.media3.common.MimeTypes;
import androidx.media3.common.StreamKey;
import androidx.media3.common.util.Assertions;
import androidx.media3.common.util.UnstableApi;
import androidx.media3.common.util.Util;
import com.google.common.collect.ImmutableList;
import com.google.errorprone.annotations.CanIgnoreReturnValue;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;

/** Defines content to be downloaded. */
@UnstableApi
public final class DownloadRequest implements Parcelable {

  /** Thrown when the encoded request data belongs to an unsupported request type. */
  public static class UnsupportedRequestException extends IOException {}

  /** A builder for download requests. */
  public static class Builder {
    private final String id;
    private final Uri uri;
    @Nullable private String mimeType;
    @Nullable private List<StreamKey> streamKeys;
    @Nullable private byte[] keySetId;
    @Nullable private String customCacheKey;
    @Nullable private byte[] data;

    /** Creates a new instance with the specified id and uri. */
    public Builder(String id, Uri uri) {
      this.id = id;
      this.uri = uri;
    }

    /** Sets the {@link DownloadRequest#mimeType}. */
    @CanIgnoreReturnValue
    public Builder setMimeType(@Nullable String mimeType) {
      this.mimeType = MimeTypes.normalizeMimeType(mimeType);
      return this;
    }

    /** Sets the {@link DownloadRequest#streamKeys}. */
    @CanIgnoreReturnValue
    public Builder setStreamKeys(@Nullable List<StreamKey> streamKeys) {
      this.streamKeys = streamKeys;
      return this;
    }

    /** Sets the {@link DownloadRequest#keySetId}. */
    @CanIgnoreReturnValue
    public Builder setKeySetId(@Nullable byte[] keySetId) {
      this.keySetId = keySetId;
      return this;
    }

    /** Sets the {@link DownloadRequest#customCacheKey}. */
    @CanIgnoreReturnValue
    public Builder setCustomCacheKey(@Nullable String customCacheKey) {
      this.customCacheKey = customCacheKey;
      return this;
    }

    /** Sets the {@link DownloadRequest#data}. */
    @CanIgnoreReturnValue
    public Builder setData(@Nullable byte[] data) {
      this.data = data;
      return this;
    }

    public DownloadRequest build() {
      return new DownloadRequest(
          id,
          uri,
          mimeType,
          streamKeys != null ? streamKeys : ImmutableList.of(),
          keySetId,
          customCacheKey,
          data);
    }
  }

  /** The unique content id. */
  public final String id;

  /** The uri being downloaded. */
  public final Uri uri;

  /**
   * The MIME type of this content. Used as a hint to infer the content's type (DASH, HLS,
   * SmoothStreaming). If null, a {@code DownloadService} will infer the content type from the
   * {@link #uri}.
   */
  @Nullable public final String mimeType;

  /** Stream keys to be downloaded. If empty, all streams will be downloaded. */
  public final List<StreamKey> streamKeys;

  /** The key set id of the offline licence if the content is protected with DRM. */
  @Nullable public final byte[] keySetId;

  /**
   * Custom key for cache indexing, or null. Must be null for DASH, HLS and SmoothStreaming
   * downloads.
   */
  @Nullable public final String customCacheKey;

  /** Application defined data associated with the download. May be empty. */
  public final byte[] data;

  /**
   * @param id See {@link #id}.
   * @param uri See {@link #uri}.
   * @param mimeType See {@link #mimeType}
   * @param streamKeys See {@link #streamKeys}.
   * @param customCacheKey See {@link #customCacheKey}.
   * @param data See {@link #data}.
   */
  private DownloadRequest(
      String id,
      Uri uri,
      @Nullable String mimeType,
      List<StreamKey> streamKeys,
      @Nullable byte[] keySetId,
      @Nullable String customCacheKey,
      @Nullable byte[] data) {
    @C.ContentType int contentType = Util.inferContentTypeForUriAndMimeType(uri, mimeType);
    if (contentType == C.CONTENT_TYPE_DASH
        || contentType == C.CONTENT_TYPE_HLS
        || contentType == C.CONTENT_TYPE_SS) {
      Assertions.checkArgument(
          customCacheKey == null, "customCacheKey must be null for type: " + contentType);
    }
    this.id = id;
    this.uri = uri;
    this.mimeType = mimeType;
    ArrayList<StreamKey> mutableKeys = new ArrayList<>(streamKeys);
    Collections.sort(mutableKeys);
    this.streamKeys = Collections.unmodifiableList(mutableKeys);
    this.keySetId = keySetId != null ? Arrays.copyOf(keySetId, keySetId.length) : null;
    this.customCacheKey = customCacheKey;
    this.data = data != null ? Arrays.copyOf(data, data.length) : Util.EMPTY_BYTE_ARRAY;
  }

  /* package */ DownloadRequest(Parcel in) {
    id = castNonNull(in.readString());
    uri = Uri.parse(castNonNull(in.readString()));
    mimeType = in.readString();
    int streamKeyCount = in.readInt();
    ArrayList<StreamKey> mutableStreamKeys = new ArrayList<>(streamKeyCount);
    for (int i = 0; i < streamKeyCount; i++) {
      mutableStreamKeys.add(in.readParcelable(StreamKey.class.getClassLoader()));
    }
    streamKeys = Collections.unmodifiableList(mutableStreamKeys);
    keySetId = in.createByteArray();
    customCacheKey = in.readString();
    data = castNonNull(in.createByteArray());
  }

  /**
   * Returns a copy with the specified ID.
   *
   * @param id The ID of the copy.
   * @return The copy with the specified ID.
   */
  public DownloadRequest copyWithId(String id) {
    return new DownloadRequest(id, uri, mimeType, streamKeys, keySetId, customCacheKey, data);
  }

  /**
   * Returns a copy with the specified key set ID.
   *
   * @param keySetId The key set ID of the copy.
   * @return The copy with the specified key set ID.
   */
  public DownloadRequest copyWithKeySetId(@Nullable byte[] keySetId) {
    return new DownloadRequest(id, uri, mimeType, streamKeys, keySetId, customCacheKey, data);
  }

  /**
   * Returns the result of merging {@code newRequest} into this request. The requests must have the
   * same {@link #id}.
   *
   * <p>The resulting request contains the stream keys from both requests. For all other member
   * variables, those in {@code newRequest} are preferred.
   *
   * @param newRequest The request being merged.
   * @return The merged result.
   * @throws IllegalArgumentException If the requests do not have the same {@link #id}.
   */
  public DownloadRequest copyWithMergedRequest(DownloadRequest newRequest) {
    Assertions.checkArgument(id.equals(newRequest.id));
    List<StreamKey> mergedKeys;
    if (streamKeys.isEmpty() || newRequest.streamKeys.isEmpty()) {
      // If either streamKeys is empty then all streams should be downloaded.
      mergedKeys = Collections.emptyList();
    } else {
      mergedKeys = new ArrayList<>(streamKeys);
      for (int i = 0; i < newRequest.streamKeys.size(); i++) {
        StreamKey newKey = newRequest.streamKeys.get(i);
        if (!mergedKeys.contains(newKey)) {
          mergedKeys.add(newKey);
        }
      }
    }
    return new DownloadRequest(
        id,
        newRequest.uri,
        newRequest.mimeType,
        mergedKeys,
        newRequest.keySetId,
        newRequest.customCacheKey,
        newRequest.data);
  }

  /** Returns a {@link MediaItem} for the content defined by the request. */
  public MediaItem toMediaItem() {
    return new MediaItem.Builder()
        .setMediaId(id)
        .setUri(uri)
        .setCustomCacheKey(customCacheKey)
        .setMimeType(mimeType)
        .setStreamKeys(streamKeys)
        .build();
  }

  @Override
  public String toString() {
    return mimeType + ":" + id;
  }

  @Override
  public boolean equals(@Nullable Object o) {
    if (!(o instanceof DownloadRequest)) {
      return false;
    }
    DownloadRequest that = (DownloadRequest) o;
    return id.equals(that.id)
        && uri.equals(that.uri)
        && Util.areEqual(mimeType, that.mimeType)
        && streamKeys.equals(that.streamKeys)
        && Arrays.equals(keySetId, that.keySetId)
        && Util.areEqual(customCacheKey, that.customCacheKey)
        && Arrays.equals(data, that.data);
  }

  @Override
  public final int hashCode() {
    int result = 31 * id.hashCode();
    result = 31 * result + uri.hashCode();
    result = 31 * result + (mimeType != null ? mimeType.hashCode() : 0);
    result = 31 * result + streamKeys.hashCode();
    result = 31 * result + Arrays.hashCode(keySetId);
    result = 31 * result + (customCacheKey != null ? customCacheKey.hashCode() : 0);
    result = 31 * result + Arrays.hashCode(data);
    return result;
  }

  // Parcelable implementation.

  @Override
  public int describeContents() {
    return 0;
  }

  @Override
  public void writeToParcel(Parcel dest, int flags) {
    dest.writeString(id);
    dest.writeString(uri.toString());
    dest.writeString(mimeType);
    dest.writeInt(streamKeys.size());
    for (int i = 0; i < streamKeys.size(); i++) {
      dest.writeParcelable(streamKeys.get(i), /* parcelableFlags= */ 0);
    }
    dest.writeByteArray(keySetId);
    dest.writeString(customCacheKey);
    dest.writeByteArray(data);
  }

  public static final Parcelable.Creator<DownloadRequest> CREATOR =
      new Parcelable.Creator<DownloadRequest>() {

        @Override
        public DownloadRequest createFromParcel(Parcel in) {
          return new DownloadRequest(in);
        }

        @Override
        public DownloadRequest[] newArray(int size) {
          return new DownloadRequest[size];
        }
      };
}