Commit ebbd022a by J. Oliva

Added new ID3 frames

- Added support for ID3 frames of types GEOB and PRIV.

 - GEOB type is commonly used by dynamic ads provider to include in the
stream information about the ads to be played.
 - PRIV type is commonly used for time synchronization (example:
synchronizing playback of a live stream and its webvtt captions) and
also by analytics companies to include tracking information in the
stream.

- Added a sample stream from Apple that contains ID3 metadata.
parent ea95db23
......@@ -123,6 +123,9 @@ import java.util.Locale;
new Sample("Apple AAC media playlist",
"https://devimages.apple.com.edgekey.net/streaming/examples/bipbop_4x3/gear0/"
+ "prog_index.m3u8", DemoUtil.TYPE_HLS),
new Sample("Apple ID3 metadata",
"http://devimages.apple.com/samplecode/adDemo/"
+ "ad.m3u8", DemoUtil.TYPE_HLS),
};
public static final Sample[] MISC = new Sample[] {
......
/*
* 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.metadata;
/**
* A metadata that contains parsed ID3 GEOB (General Encapsulated Object) frame data associated
* with time indices.
*/
public class GeobMetadata {
public static final String TYPE = "GEOB";
public final String mimeType;
public final String filename;
public final String description;
public final byte[] data;
public GeobMetadata(String mimeType, String filename, String description, byte[] data) {
this.mimeType = mimeType;
this.filename = filename;
this.description = description;
this.data = data;
}
}
......@@ -67,6 +67,39 @@ public class Id3Parser implements MetadataParser<Map<String, Object>> {
String value = new String(frame, valueStartIndex, valueEndIndex - valueStartIndex,
charset);
metadata.put(TxxxMetadata.TYPE, new TxxxMetadata(description, value));
} else if (frameId0 == 'P' && frameId1 == 'R' && frameId2 == 'I' && frameId3 == 'V') {
// Check frame ID == PRIV
byte[] frame = new byte[frameSize];
id3Data.readBytes(frame, 0, frameSize);
int firstZeroIndex = indexOf(frame, 0, (byte) 0);
String owner = new String(frame, 0, firstZeroIndex);
byte[] privateData = new byte[frameSize - firstZeroIndex - 1];
System.arraycopy(frame, firstZeroIndex + 1, privateData, 0, frameSize - firstZeroIndex - 1);
metadata.put(PrivMetadata.TYPE, new PrivMetadata(owner, privateData));
} else if (frameId0 == 'G' && frameId1 == 'E' && frameId2 == 'O' && frameId3 == 'B') {
// Check frame ID == GEOB
int encoding = id3Data.readUnsignedByte();
String charset = getCharsetName(encoding);
byte[] frame = new byte[frameSize - 1];
id3Data.readBytes(frame, 0, frameSize - 1);
int firstZeroIndex = indexOf(frame, 0, (byte) 0);
String mimeType = new String(frame, 0, firstZeroIndex);
int filenameStartIndex = firstZeroIndex + 1;
int filenameEndIndex = indexOf(frame, filenameStartIndex, (byte) 0);
String filename = new String(frame, filenameStartIndex,
filenameEndIndex - filenameStartIndex, charset);
int descriptionStartIndex = filenameEndIndex + 1;
int descriptionEndIndex = indexOf(frame, descriptionStartIndex, (byte) 0);
String description = new String(frame, descriptionStartIndex,
descriptionEndIndex - descriptionStartIndex, charset);
byte[] objectData = new byte[frameSize - descriptionEndIndex - 2];
System.arraycopy(frame, descriptionEndIndex + 1, objectData, 0,
frameSize - descriptionEndIndex - 2);
metadata.put(GeobMetadata.TYPE, new GeobMetadata(mimeType, filename,
description, objectData));
} else {
String type = String.format("%c%c%c%c", frameId0, frameId1, frameId2, frameId3);
byte[] frame = new byte[frameSize];
......
/*
* 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.metadata;
/**
* A metadata that contains parsed ID3 PRIV (Private) frame data associated
* with time indices.
*/
public class PrivMetadata {
public static final String TYPE = "PRIV";
public final String owner;
public final byte[] privateData;
public PrivMetadata(String owner, byte [] privateData) {
this.owner = owner;
this.privateData = privateData;
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment