diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java index 1fbc317ed7..03cf5b4e2c 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/full/FullPlayerActivity.java @@ -25,7 +25,7 @@ import com.google.android.exoplayer.demo.full.player.DemoPlayer; import com.google.android.exoplayer.demo.full.player.DemoPlayer.RendererBuilder; import com.google.android.exoplayer.demo.full.player.HlsRendererBuilder; import com.google.android.exoplayer.demo.full.player.SmoothStreamingRendererBuilder; -import com.google.android.exoplayer.metadata.Metadata; +import com.google.android.exoplayer.metadata.TxxxMetadata; import com.google.android.exoplayer.text.CaptionStyleCompat; import com.google.android.exoplayer.text.SubtitleView; import com.google.android.exoplayer.util.Util; @@ -56,7 +56,7 @@ import android.widget.PopupMenu; import android.widget.PopupMenu.OnMenuItemClickListener; import android.widget.TextView; -import java.util.List; +import java.util.Map; /** * An activity that plays media using {@link DemoPlayer}. @@ -415,10 +415,13 @@ public class FullPlayerActivity extends Activity implements SurfaceHolder.Callba // DemoPlayer.MetadataListener implementation @Override - public void onMetadata(List metadata) { + public void onMetadata(Map metadata) { for (int i = 0; i < metadata.size(); i++) { - Metadata next = metadata.get(i); - Log.i(TAG, "ID3 TimedMetadata: key=" + next.key + ", value=" + next.value); + if (metadata.containsKey(TxxxMetadata.TYPE)) { + TxxxMetadata txxxMetadata = (TxxxMetadata) metadata.get(TxxxMetadata.TYPE); + Log.i(TAG, String.format("ID3 TimedMetadata: description=%s, value=%s", + txxxMetadata.description, txxxMetadata.value)); + } } } diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java b/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java index b6a68bc98f..ad046fed00 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/full/player/DemoPlayer.java @@ -26,7 +26,6 @@ import com.google.android.exoplayer.TrackRenderer; import com.google.android.exoplayer.chunk.ChunkSampleSource; import com.google.android.exoplayer.chunk.MultiTrackChunkSource; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; -import com.google.android.exoplayer.metadata.Metadata; import com.google.android.exoplayer.metadata.MetadataTrackRenderer; import com.google.android.exoplayer.text.TextTrackRenderer; import com.google.android.exoplayer.upstream.DefaultBandwidthMeter; @@ -38,7 +37,7 @@ import android.os.Looper; import android.view.Surface; import java.io.IOException; -import java.util.List; +import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -141,7 +140,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi * A listener for receiving metadata parsed from the media stream. */ public interface MetadataListener { - void onMetadata(List metadata); + void onMetadata(Map metadata); } // Constants pulled into this class for convenience. @@ -475,7 +474,7 @@ public class DemoPlayer implements ExoPlayer.Listener, ChunkSampleSource.EventLi } @Override - public void onMetadata(List metadata) { + public void onMetadata(Map metadata) { if (metadataListener != null) { metadataListener.onMetadata(metadata); } diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java b/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java index 26313d57c6..778a026228 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/full/player/HlsRendererBuilder.java @@ -94,7 +94,7 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback parse(byte[] data, int size) + public Map parse(byte[] data, int size) throws UnsupportedEncodingException, ParserException { BitsArray id3Buffer = new BitsArray(data, size); int id3Size = parseId3Header(id3Buffer); - List metadata = new ArrayList(); + Map metadata = new HashMap(); while (id3Size > 0) { int frameId0 = id3Buffer.readUnsignedByte(); @@ -63,20 +63,23 @@ public class Id3Parser implements MetadataParser { id3Buffer.readBytes(frame, 0, frameSize - 1); int firstZeroIndex = indexOf(frame, 0, (byte) 0); - String key = new String(frame, 0, firstZeroIndex, charset); + String description = new String(frame, 0, firstZeroIndex, charset); int valueStartIndex = indexOfNot(frame, firstZeroIndex, (byte) 0); int valueEndIndex = indexOf(frame, valueStartIndex, (byte) 0); String value = new String(frame, valueStartIndex, valueEndIndex - valueStartIndex, charset); - metadata.add(new Metadata(key, value)); + metadata.put(TxxxMetadata.TYPE, new TxxxMetadata(description, value)); } else { - id3Buffer.skipBytes(frameSize); + String type = String.format("%c%c%c%c", frameId0, frameId1, frameId2, frameId3); + byte[] frame = new byte[frameSize]; + id3Buffer.readBytes(frame, 0, frameSize); + metadata.put(type, frame); } id3Size -= frameSize + 10 /* header size */; } - return Collections.unmodifiableList(metadata); + return Collections.unmodifiableMap(metadata); } private static int indexOf(byte[] data, int fromIndex, byte key) { diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataParser.java b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataParser.java index 46d2b1179a..1f9b0dcaef 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataParser.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataParser.java @@ -16,7 +16,7 @@ package com.google.android.exoplayer.metadata; import java.io.IOException; -import java.util.List; +import java.util.Map; /** * Parses {@link Metadata}s from binary data. @@ -32,14 +32,14 @@ public interface MetadataParser { public boolean canParse(String mimeType); /** - * Parses a list of {@link Metadata} objects from the provided binary data. + * Parses a map of metadata type to metadata objects from the provided binary data. * * @param data The raw binary data from which to parse the metadata. * @param size The size of the input data. - * @return A parsed {@link List} of {@link Metadata} objects. + * @return A parsed {@link Map} of metadata type to metadata objects. * @throws IOException If a problem occurred parsing the data. */ - public List parse(byte[] data, int size) + public Map parse(byte[] data, int size) throws IOException; } diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java index 5d5ad0c50d..48ed78f20c 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/MetadataTrackRenderer.java @@ -28,7 +28,7 @@ import android.os.Looper; import android.os.Message; import java.io.IOException; -import java.util.List; +import java.util.Map; /** * A {@link TrackRenderer} for metadata embedded in a media stream. @@ -45,7 +45,7 @@ public class MetadataTrackRenderer extends TrackRenderer implements Callback { * * @param metadata The metadata to process. */ - void onMetadata(List metadata); + void onMetadata(Map metadata); } @@ -63,7 +63,7 @@ public class MetadataTrackRenderer extends TrackRenderer implements Callback { private boolean inputStreamEnded; private long pendingMetadataTimestamp; - private List pendingMetadata; + private Map pendingMetadata; /** * @param source A source from which samples containing metadata can be read. @@ -185,7 +185,7 @@ public class MetadataTrackRenderer extends TrackRenderer implements Callback { return true; } - private void invokeRenderer(List metadata) { + private void invokeRenderer(Map metadata) { if (metadataHandler != null) { metadataHandler.obtainMessage(MSG_INVOKE_RENDERER, metadata).sendToTarget(); } else { @@ -198,13 +198,13 @@ public class MetadataTrackRenderer extends TrackRenderer implements Callback { public boolean handleMessage(Message msg) { switch (msg.what) { case MSG_INVOKE_RENDERER: - invokeRendererInternal((List) msg.obj); + invokeRendererInternal((Map) msg.obj); return true; } return false; } - private void invokeRendererInternal(List metadata) { + private void invokeRendererInternal(Map metadata) { metadataRenderer.onMetadata(metadata); } diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/Metadata.java b/library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java similarity index 69% rename from library/src/main/java/com/google/android/exoplayer/metadata/Metadata.java rename to library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java index d89b02f9bd..c455bb825d 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/Metadata.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java @@ -16,15 +16,18 @@ package com.google.android.exoplayer.metadata; /** - * A metadata that contains textual data associated with time indices. + * A metadata that contains parsed ID3 TXXX (User defined text information) frame data associated + * with time indices. */ -public class Metadata { +public class TxxxMetadata { - public final String key; + public static final String TYPE = "TXXX"; + + public final String description; public final String value; - public Metadata(String key, String value) { - this.key = key; + public TxxxMetadata(String description, String value) { + this.description = description; this.value = value; }