use of com.google.android.exoplayer2.metadata.Metadata.Entry in project android-player-samples by BrightcoveOS.
the class MainActivity method onCreate.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
brightcoveVideoView.getEventEmitter().on(EventType.DID_SET_SOURCE, new EventListener() {
@Override
public void processEvent(Event event) {
ExoPlayerVideoDisplayComponent exoPlayerVideoDisplayComponent = (ExoPlayerVideoDisplayComponent) brightcoveVideoView.getVideoDisplay();
exoPlayerVideoDisplayComponent.setMetadataListener(new ExoPlayerVideoDisplayComponent.MetadataListener() {
@Override
public void onMetadata(Metadata metadata) {
for (int i = 0; i < metadata.length(); i++) {
Metadata.Entry entry = metadata.get(i);
if (entry instanceof Id3Frame) {
Id3Frame id3Frame = (Id3Frame) entry;
Log.v(TAG, "id3 Frame id: " + id3Frame.id);
}
}
}
});
}
});
Video video = Video.createVideo("https://s3.amazonaws.com/as-zencoder/hls-timed-metadata/test.m3u8", DeliveryType.HLS);
video.getProperties().put(Video.Fields.PUBLISHER_ID, "5420904993001");
brightcoveVideoView.add(video);
brightcoveVideoView.start();
// Log whether or not instance state in non-null.
if (savedInstanceState != null) {
Log.v(TAG, "Restoring saved position");
} else {
Log.v(TAG, "No saved state");
}
}
use of com.google.android.exoplayer2.metadata.Metadata.Entry in project ExoPlayer by google.
the class DrmInitData method createSessionCreationData.
/**
* Merges {@link DrmInitData} obtained from a media manifest and a media stream.
*
* <p>The result is generated as follows.
*
* <ol>
* <li>Include all {@link SchemeData}s from {@code manifestData} where {@link
* SchemeData#hasData()} is true.
* <li>Include all {@link SchemeData}s in {@code mediaData} where {@link SchemeData#hasData()}
* is true and for which we did not include an entry from the manifest targeting the same
* UUID.
* <li>If available, the scheme type from the manifest is used. If not, the scheme type from the
* media is used.
* </ol>
*
* @param manifestData DRM session acquisition data obtained from the manifest.
* @param mediaData DRM session acquisition data obtained from the media.
* @return A {@link DrmInitData} obtained from merging a media manifest and a media stream.
*/
@Nullable
public static DrmInitData createSessionCreationData(@Nullable DrmInitData manifestData, @Nullable DrmInitData mediaData) {
ArrayList<SchemeData> result = new ArrayList<>();
String schemeType = null;
if (manifestData != null) {
schemeType = manifestData.schemeType;
for (SchemeData data : manifestData.schemeDatas) {
if (data.hasData()) {
result.add(data);
}
}
}
if (mediaData != null) {
if (schemeType == null) {
schemeType = mediaData.schemeType;
}
int manifestDatasCount = result.size();
for (SchemeData data : mediaData.schemeDatas) {
if (data.hasData() && !containsSchemeDataWithUuid(result, manifestDatasCount, data.uuid)) {
result.add(data);
}
}
}
return result.isEmpty() ? null : new DrmInitData(schemeType, result);
}
use of com.google.android.exoplayer2.metadata.Metadata.Entry in project ExoPlayer by google.
the class MetadataRenderer method decodeWrappedMetadata.
/**
* Iterates through {@code metadata.entries} and checks each one to see if contains wrapped
* metadata. If it does, then we recursively decode the wrapped metadata. If it doesn't (recursion
* base-case), we add the {@link Metadata.Entry} to {@code decodedEntries} (output parameter).
*/
private void decodeWrappedMetadata(Metadata metadata, List<Metadata.Entry> decodedEntries) {
for (int i = 0; i < metadata.length(); i++) {
@Nullable Format wrappedMetadataFormat = metadata.get(i).getWrappedMetadataFormat();
if (wrappedMetadataFormat != null && decoderFactory.supportsFormat(wrappedMetadataFormat)) {
MetadataDecoder wrappedMetadataDecoder = decoderFactory.createDecoder(wrappedMetadataFormat);
// wrappedMetadataFormat != null so wrappedMetadataBytes must be non-null too.
byte[] wrappedMetadataBytes = Assertions.checkNotNull(metadata.get(i).getWrappedMetadataBytes());
buffer.clear();
buffer.ensureSpaceForWrite(wrappedMetadataBytes.length);
castNonNull(buffer.data).put(wrappedMetadataBytes);
buffer.flip();
@Nullable Metadata innerMetadata = wrappedMetadataDecoder.decode(buffer);
if (innerMetadata != null) {
// The decoding succeeded, so we'll try another level of unwrapping.
decodeWrappedMetadata(innerMetadata, decodedEntries);
}
} else {
// Entry doesn't contain any wrapped metadata, so output it directly.
decodedEntries.add(metadata.get(i));
}
}
}
use of com.google.android.exoplayer2.metadata.Metadata.Entry in project ExoPlayer by google.
the class AtomParsers method parseMdtaFromMeta.
/**
* Parses a metadata meta atom if it contains metadata with handler 'mdta'.
*
* @param meta The metadata atom to decode.
* @return Parsed metadata, or null.
*/
@Nullable
public static Metadata parseMdtaFromMeta(Atom.ContainerAtom meta) {
@Nullable Atom.LeafAtom hdlrAtom = meta.getLeafAtomOfType(Atom.TYPE_hdlr);
@Nullable Atom.LeafAtom keysAtom = meta.getLeafAtomOfType(Atom.TYPE_keys);
@Nullable Atom.LeafAtom ilstAtom = meta.getLeafAtomOfType(Atom.TYPE_ilst);
if (hdlrAtom == null || keysAtom == null || ilstAtom == null || parseHdlr(hdlrAtom.data) != TYPE_mdta) {
// There isn't enough information to parse the metadata, or the handler type is unexpected.
return null;
}
// Parse metadata keys.
ParsableByteArray keys = keysAtom.data;
keys.setPosition(Atom.FULL_HEADER_SIZE);
int entryCount = keys.readInt();
String[] keyNames = new String[entryCount];
for (int i = 0; i < entryCount; i++) {
int entrySize = keys.readInt();
// keyNamespace
keys.skipBytes(4);
int keySize = entrySize - 8;
keyNames[i] = keys.readString(keySize);
}
// Parse metadata items.
ParsableByteArray ilst = ilstAtom.data;
ilst.setPosition(Atom.HEADER_SIZE);
ArrayList<Metadata.Entry> entries = new ArrayList<>();
while (ilst.bytesLeft() > Atom.HEADER_SIZE) {
int atomPosition = ilst.getPosition();
int atomSize = ilst.readInt();
int keyIndex = ilst.readInt() - 1;
if (keyIndex >= 0 && keyIndex < keyNames.length) {
String key = keyNames[keyIndex];
@Nullable Metadata.Entry entry = MetadataUtil.parseMdtaMetadataEntryFromIlst(ilst, atomPosition + atomSize, key);
if (entry != null) {
entries.add(entry);
}
} else {
Log.w(TAG, "Skipped metadata with unknown key index: " + keyIndex);
}
ilst.setPosition(atomPosition + atomSize);
}
return entries.isEmpty() ? null : new Metadata(entries);
}
use of com.google.android.exoplayer2.metadata.Metadata.Entry in project ExoPlayer by google.
the class FragmentedMp4Extractor method parseSampleGroups.
private static void parseSampleGroups(ContainerAtom traf, @Nullable String schemeType, TrackFragment out) throws ParserException {
// Find sbgp and sgpd boxes with grouping_type == seig.
@Nullable ParsableByteArray sbgp = null;
@Nullable ParsableByteArray sgpd = null;
for (int i = 0; i < traf.leafChildren.size(); i++) {
LeafAtom leafAtom = traf.leafChildren.get(i);
ParsableByteArray leafAtomData = leafAtom.data;
if (leafAtom.type == Atom.TYPE_sbgp) {
leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
sbgp = leafAtomData;
}
} else if (leafAtom.type == Atom.TYPE_sgpd) {
leafAtomData.setPosition(Atom.FULL_HEADER_SIZE);
if (leafAtomData.readInt() == SAMPLE_GROUP_TYPE_seig) {
sgpd = leafAtomData;
}
}
}
if (sbgp == null || sgpd == null) {
return;
}
sbgp.setPosition(Atom.HEADER_SIZE);
int sbgpVersion = Atom.parseFullAtomVersion(sbgp.readInt());
// grouping_type == seig.
sbgp.skipBytes(4);
if (sbgpVersion == 1) {
// grouping_type_parameter.
sbgp.skipBytes(4);
}
if (sbgp.readInt() != 1) {
// entry_count.
throw ParserException.createForUnsupportedContainerFeature("Entry count in sbgp != 1 (unsupported).");
}
sgpd.setPosition(Atom.HEADER_SIZE);
int sgpdVersion = Atom.parseFullAtomVersion(sgpd.readInt());
// grouping_type == seig.
sgpd.skipBytes(4);
if (sgpdVersion == 1) {
if (sgpd.readUnsignedInt() == 0) {
throw ParserException.createForUnsupportedContainerFeature("Variable length description in sgpd found (unsupported)");
}
} else if (sgpdVersion >= 2) {
// default_sample_description_index.
sgpd.skipBytes(4);
}
if (sgpd.readUnsignedInt() != 1) {
// entry_count.
throw ParserException.createForUnsupportedContainerFeature("Entry count in sgpd != 1 (unsupported).");
}
// CencSampleEncryptionInformationGroupEntry
// reserved = 0.
sgpd.skipBytes(1);
int patternByte = sgpd.readUnsignedByte();
int cryptByteBlock = (patternByte & 0xF0) >> 4;
int skipByteBlock = patternByte & 0x0F;
boolean isProtected = sgpd.readUnsignedByte() == 1;
if (!isProtected) {
return;
}
int perSampleIvSize = sgpd.readUnsignedByte();
byte[] keyId = new byte[16];
sgpd.readBytes(keyId, 0, keyId.length);
@Nullable byte[] constantIv = null;
if (perSampleIvSize == 0) {
int constantIvSize = sgpd.readUnsignedByte();
constantIv = new byte[constantIvSize];
sgpd.readBytes(constantIv, 0, constantIvSize);
}
out.definesEncryptionData = true;
out.trackEncryptionBox = new TrackEncryptionBox(isProtected, schemeType, perSampleIvSize, keyId, cryptByteBlock, skipByteBlock, constantIv);
}
Aggregations