SsDownloader.java 4.4 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
/*
 * 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 com.google.android.exoplayer2.source.smoothstreaming.offline;

import android.net.Uri;
import com.google.android.exoplayer2.C;
import com.google.android.exoplayer2.offline.DownloaderConstructorHelper;
import com.google.android.exoplayer2.offline.SegmentDownloader;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifest.StreamElement;
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsManifestParser;
25
import com.google.android.exoplayer2.source.smoothstreaming.manifest.SsUtil;
26 27 28 29 30 31 32 33 34 35 36
import com.google.android.exoplayer2.source.smoothstreaming.manifest.TrackKey;
import com.google.android.exoplayer2.upstream.DataSource;
import com.google.android.exoplayer2.upstream.DataSpec;
import com.google.android.exoplayer2.upstream.ParsingLoadable;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * Helper class to download SmoothStreaming streams.
 *
37 38
 * <p>Except {@link #getTotalSegments()}, {@link #getDownloadedSegments()} and {@link
 * #getDownloadedBytes()}, this class isn't thread safe.
39 40 41
 *
 * <p>Example usage:
 *
42
 * <pre>{@code
43 44 45 46 47 48 49 50
 * SimpleCache cache = new SimpleCache(downloadFolder, new NoOpCacheEvictor());
 * DefaultHttpDataSourceFactory factory = new DefaultHttpDataSourceFactory("ExoPlayer", null);
 * DownloaderConstructorHelper constructorHelper =
 *     new DownloaderConstructorHelper(cache, factory);
 * SsDownloader ssDownloader = new SsDownloader(manifestUrl, constructorHelper);
 * // Select the first track of the first stream element
 * ssDownloader.selectRepresentations(new TrackKey[] {new TrackKey(0, 0)});
 * ssDownloader.download(new ProgressListener() {
O
Oliver Woodman 已提交
51
 *   {@literal @}Override
52 53 54 55 56 57 58
 *   public void onDownloadProgress(Downloader downloader, float downloadPercentage,
 *       long downloadedBytes) {
 *     // Invoked periodically during the download.
 *   }
 * });
 * // Access downloaded data using CacheDataSource
 * CacheDataSource cacheDataSource =
59 60
 *     new CacheDataSource(cache, factory.createDataSource(), CacheDataSource.FLAG_BLOCK_ON_CACHE);
 * }</pre>
61 62 63 64 65 66 67
 */
public final class SsDownloader extends SegmentDownloader<SsManifest, TrackKey> {

  /**
   * @see SegmentDownloader#SegmentDownloader(Uri, DownloaderConstructorHelper)
   */
  public SsDownloader(Uri manifestUri, DownloaderConstructorHelper constructorHelper)  {
68
    super(SsUtil.fixManifestUri(manifestUri), constructorHelper);
69 70 71
  }

  @Override
72 73 74 75 76 77 78 79 80 81 82 83 84 85
  public TrackKey[] getAllRepresentationKeys() throws IOException {
    ArrayList<TrackKey> keys = new ArrayList<>();
    SsManifest manifest = getManifest();
    for (int i = 0; i < manifest.streamElements.length; i++) {
      StreamElement streamElement = manifest.streamElements[i];
      for (int j = 0; j < streamElement.formats.length; j++) {
        keys.add(new TrackKey(i, j));
      }
    }
    return keys.toArray(new TrackKey[keys.size()]);
  }

  @Override
  protected SsManifest getManifest(DataSource dataSource, Uri uri) throws IOException {
86 87
    ParsingLoadable<SsManifest> loadable =
        new ParsingLoadable<>(dataSource, uri, C.DATA_TYPE_MANIFEST, new SsManifestParser());
88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106
    loadable.load();
    return loadable.getResult();
  }

  @Override
  protected List<Segment> getSegments(DataSource dataSource, SsManifest manifest,
      TrackKey[] keys, boolean allowIndexLoadErrors) throws InterruptedException, IOException {
    ArrayList<Segment> segments = new ArrayList<>();
    for (TrackKey key : keys) {
      StreamElement streamElement = manifest.streamElements[key.streamElementIndex];
      for (int i = 0; i < streamElement.chunkCount; i++) {
        segments.add(new Segment(streamElement.getStartTimeUs(i),
            new DataSpec(streamElement.buildRequestUri(key.trackIndex, i))));
      }
    }
    return segments;
  }

}