com.google.android.exoplayer.smoothstreaming.SmoothStreamingManifest Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of exoplayer Show documentation
Show all versions of exoplayer Show documentation
Custom implementation of exoplayer with slow motion
The newest version!
/*
* Copyright (C) 2014 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.exoplayer.smoothstreaming;
import com.google.android.exoplayer.util.MimeTypes;
import com.google.android.exoplayer.util.Util;
import java.util.UUID;
/**
* Represents a SmoothStreaming manifest.
*
* @see
* IIS Smooth Streaming Client Manifest Format
*/
public class SmoothStreamingManifest {
public final int majorVersion;
public final int minorVersion;
public final long timeScale;
public final int lookAheadCount;
public final ProtectionElement protectionElement;
public final StreamElement[] streamElements;
private final long duration;
public SmoothStreamingManifest(int majorVersion, int minorVersion, long timeScale, long duration,
int lookAheadCount, ProtectionElement protectionElement, StreamElement[] streamElements) {
this.majorVersion = majorVersion;
this.minorVersion = minorVersion;
this.timeScale = timeScale;
this.duration = duration;
this.lookAheadCount = lookAheadCount;
this.protectionElement = protectionElement;
this.streamElements = streamElements;
}
/**
* Gets the duration of the media.
*
*
* @return The duration of the media, in microseconds.
*/
public long getDurationUs() {
return (duration * 1000000L) / timeScale;
}
/**
* Represents a protection element containing a single header.
*/
public static class ProtectionElement {
public final UUID uuid;
public final byte[] data;
public ProtectionElement(UUID uuid, byte[] data) {
this.uuid = uuid;
this.data = data;
}
}
/**
* Represents a QualityLevel element.
*/
public static class TrackElement {
// Required for all
public final int index;
public final int bitrate;
// Audio-video
public final String fourCC;
public final byte[][] csd;
public final int profile;
public final int level;
// Audio-video (derived)
public final String mimeType;
// Video-only
public final int maxWidth;
public final int maxHeight;
// Audio-only
public final int sampleRate;
public final int numChannels;
public final int packetSize;
public final int audioTag;
public final int bitPerSample;
public final int nalUnitLengthField;
public final String content;
public TrackElement(int index, int bitrate, String fourCC, byte[][] csd, int profile, int level,
int maxWidth, int maxHeight, int sampleRate, int channels, int packetSize, int audioTag,
int bitPerSample, int nalUnitLengthField, String content) {
this.index = index;
this.bitrate = bitrate;
this.fourCC = fourCC;
this.csd = csd;
this.profile = profile;
this.level = level;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.sampleRate = sampleRate;
this.numChannels = channels;
this.packetSize = packetSize;
this.audioTag = audioTag;
this.bitPerSample = bitPerSample;
this.nalUnitLengthField = nalUnitLengthField;
this.content = content;
this.mimeType = fourCCToMimeType(fourCC);
}
private static String fourCCToMimeType(String fourCC) {
if (fourCC.equalsIgnoreCase("H264") || fourCC.equalsIgnoreCase("AVC1")
|| fourCC.equalsIgnoreCase("DAVC")) {
return MimeTypes.VIDEO_H264;
} else if (fourCC.equalsIgnoreCase("AACL") || fourCC.equalsIgnoreCase("AACH")) {
return MimeTypes.AUDIO_AAC;
} else if (fourCC.equalsIgnoreCase("TTML")) {
return MimeTypes.APPLICATION_TTML;
}
return null;
}
}
/**
* Represents a StreamIndex element.
*/
public static class StreamElement {
public static final int TYPE_UNKNOWN = -1;
public static final int TYPE_AUDIO = 0;
public static final int TYPE_VIDEO = 1;
public static final int TYPE_TEXT = 2;
private static final String URL_PLACEHOLDER_START_TIME = "{start time}";
private static final String URL_PLACEHOLDER_BITRATE = "{bitrate}";
public final int type;
public final String subType;
public final long timeScale;
public final String name;
public final int qualityLevels;
public final String url;
public final int maxWidth;
public final int maxHeight;
public final int displayWidth;
public final int displayHeight;
public final String language;
public final TrackElement[] tracks;
public final int chunkCount;
private final long[] chunkStartTimes;
public StreamElement(int type, String subType, long timeScale, String name,
int qualityLevels, String url, int maxWidth, int maxHeight, int displayWidth,
int displayHeight, String language, TrackElement[] tracks, long[] chunkStartTimes) {
this.type = type;
this.subType = subType;
this.timeScale = timeScale;
this.name = name;
this.qualityLevels = qualityLevels;
this.url = url;
this.maxWidth = maxWidth;
this.maxHeight = maxHeight;
this.displayWidth = displayWidth;
this.displayHeight = displayHeight;
this.language = language;
this.tracks = tracks;
this.chunkCount = chunkStartTimes.length;
this.chunkStartTimes = chunkStartTimes;
}
/**
* Gets the index of the chunk that contains the specified time.
*
* @param timeUs The time in microseconds.
* @return The index of the corresponding chunk.
*/
public int getChunkIndex(long timeUs) {
return Util.binarySearchFloor(chunkStartTimes, (timeUs * timeScale) / 1000000L, true, true);
}
/**
* Gets the start time of the specified chunk.
*
* @param chunkIndex The index of the chunk.
* @return The start time of the chunk, in microseconds.
*/
public long getStartTimeUs(int chunkIndex) {
return (chunkStartTimes[chunkIndex] * 1000000L) / timeScale;
}
/**
* Builds a URL for requesting the specified chunk of the specified track.
*
* @param track The index of the track for which to build the URL.
* @param chunkIndex The index of the chunk for which to build the URL.
* @return The request URL.
*/
public String buildRequestUrl(int track, int chunkIndex) {
assert (tracks != null);
assert (chunkStartTimes != null);
assert (chunkIndex < chunkStartTimes.length);
return url.replace(URL_PLACEHOLDER_BITRATE, Integer.toString(tracks[track].bitrate))
.replace(URL_PLACEHOLDER_START_TIME, Long.toString(chunkStartTimes[chunkIndex]));
}
}
}