From 9cfff0b0283d038976ed437bd656cdea197bb30c Mon Sep 17 00:00:00 2001 From: olly Date: Tue, 15 Mar 2016 04:01:18 -0700 Subject: [PATCH] Merge cleaned version of https://github.com/google/ExoPlayer/pull/1234. ------------- Created by MOE: https://github.com/google/moe MOE_MIGRATED_REVID=117224172 --- .../exoplayer/demo/PlayerActivity.java | 36 +++++++++---------- .../exoplayer/demo/player/DemoPlayer.java | 16 ++++----- .../metadata/{ => id3}/Id3ParserTest.java | 22 ++++++------ .../exoplayer/metadata/id3/BinaryFrame.java | 30 ++++++++++++++++ .../{GeobMetadata.java => id3/GeobFrame.java} | 12 +++---- .../exoplayer/metadata/id3/Id3Frame.java | 32 +++++++++++++++++ .../metadata/{ => id3}/Id3Parser.java | 33 +++++++++-------- .../{PrivMetadata.java => id3/PrivFrame.java} | 12 +++---- .../{TxxxMetadata.java => id3/TxxxFrame.java} | 12 +++---- 9 files changed, 131 insertions(+), 74 deletions(-) rename library/src/androidTest/java/com/google/android/exoplayer/metadata/{ => id3}/Id3ParserTest.java (63%) create mode 100644 library/src/main/java/com/google/android/exoplayer/metadata/id3/BinaryFrame.java rename library/src/main/java/com/google/android/exoplayer/metadata/{GeobMetadata.java => id3/GeobFrame.java} (72%) create mode 100644 library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Frame.java rename library/src/main/java/com/google/android/exoplayer/metadata/{ => id3}/Id3Parser.java (89%) rename library/src/main/java/com/google/android/exoplayer/metadata/{PrivMetadata.java => id3/PrivFrame.java} (73%) rename library/src/main/java/com/google/android/exoplayer/metadata/{TxxxMetadata.java => id3/TxxxFrame.java} (71%) diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java index 6b5c7abfe39..d78e19abd22 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/PlayerActivity.java @@ -30,9 +30,10 @@ import com.google.android.exoplayer.demo.player.SmoothStreamingSourceBuilder; import com.google.android.exoplayer.demo.ui.TrackSelectionHelper; import com.google.android.exoplayer.drm.UnsupportedDrmException; -import com.google.android.exoplayer.metadata.GeobMetadata; -import com.google.android.exoplayer.metadata.PrivMetadata; -import com.google.android.exoplayer.metadata.TxxxMetadata; +import com.google.android.exoplayer.metadata.id3.GeobFrame; +import com.google.android.exoplayer.metadata.id3.Id3Frame; +import com.google.android.exoplayer.metadata.id3.PrivFrame; +import com.google.android.exoplayer.metadata.id3.TxxxFrame; import com.google.android.exoplayer.text.CaptionStyleCompat; import com.google.android.exoplayer.text.Cue; import com.google.android.exoplayer.text.SubtitleLayout; @@ -67,7 +68,6 @@ import java.net.CookieManager; import java.net.CookiePolicy; import java.util.List; -import java.util.Map; /** * An activity that plays media using {@link DemoPlayer}. @@ -447,23 +447,21 @@ public void onCues(List cues) { // DemoPlayer.MetadataListener implementation @Override - public void onId3Metadata(Map metadata) { - for (Map.Entry entry : metadata.entrySet()) { - if (TxxxMetadata.TYPE.equals(entry.getKey())) { - TxxxMetadata txxxMetadata = (TxxxMetadata) entry.getValue(); - Log.i(TAG, String.format("ID3 TimedMetadata %s: description=%s, value=%s", - TxxxMetadata.TYPE, txxxMetadata.description, txxxMetadata.value)); - } else if (PrivMetadata.TYPE.equals(entry.getKey())) { - PrivMetadata privMetadata = (PrivMetadata) entry.getValue(); - Log.i(TAG, String.format("ID3 TimedMetadata %s: owner=%s", - PrivMetadata.TYPE, privMetadata.owner)); - } else if (GeobMetadata.TYPE.equals(entry.getKey())) { - GeobMetadata geobMetadata = (GeobMetadata) entry.getValue(); + public void onId3Metadata(List id3Frames) { + for (Id3Frame id3Frame : id3Frames) { + if (id3Frame instanceof TxxxFrame) { + TxxxFrame txxxFrame = (TxxxFrame) id3Frame; + Log.i(TAG, String.format("ID3 TimedMetadata %s: description=%s, value=%s", txxxFrame.id, + txxxFrame.description, txxxFrame.value)); + } else if (id3Frame instanceof PrivFrame) { + PrivFrame privFrame = (PrivFrame) id3Frame; + Log.i(TAG, String.format("ID3 TimedMetadata %s: owner=%s", privFrame.id, privFrame.owner)); + } else if (id3Frame instanceof GeobFrame) { + GeobFrame geobFrame = (GeobFrame) id3Frame; Log.i(TAG, String.format("ID3 TimedMetadata %s: mimeType=%s, filename=%s, description=%s", - GeobMetadata.TYPE, geobMetadata.mimeType, geobMetadata.filename, - geobMetadata.description)); + geobFrame.id, geobFrame.mimeType, geobFrame.filename, geobFrame.description)); } else { - Log.i(TAG, String.format("ID3 TimedMetadata %s", entry.getKey())); + Log.i(TAG, String.format("ID3 TimedMetadata %s", id3Frame.id)); } } } diff --git a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java index 3582ee9c13a..4912d06c10a 100644 --- a/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java +++ b/demo/src/main/java/com/google/android/exoplayer/demo/player/DemoPlayer.java @@ -34,9 +34,10 @@ import com.google.android.exoplayer.dash.DashChunkSource; import com.google.android.exoplayer.drm.StreamingDrmSessionManager; import com.google.android.exoplayer.hls.HlsSampleSource; -import com.google.android.exoplayer.metadata.Id3Parser; import com.google.android.exoplayer.metadata.MetadataTrackRenderer; import com.google.android.exoplayer.metadata.MetadataTrackRenderer.MetadataRenderer; +import com.google.android.exoplayer.metadata.id3.Id3Frame; +import com.google.android.exoplayer.metadata.id3.Id3Parser; import com.google.android.exoplayer.text.Cue; import com.google.android.exoplayer.text.TextRenderer; import com.google.android.exoplayer.text.TextTrackRenderer; @@ -54,7 +55,6 @@ import java.io.IOException; import java.util.List; -import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; /** @@ -66,7 +66,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even ChunkSampleSource.EventListener, HlsSampleSource.EventListener, DefaultBandwidthMeter.EventListener, MediaCodecVideoTrackRenderer.EventListener, MediaCodecAudioTrackRenderer.EventListener, StreamingDrmSessionManager.EventListener, - DashChunkSource.EventListener, TextRenderer, MetadataRenderer>, + DashChunkSource.EventListener, TextRenderer, MetadataRenderer>, DebugTextViewHelper.Provider { /** @@ -140,7 +140,7 @@ public interface CaptionListener { * A listener for receiving ID3 metadata parsed from the media stream. */ public interface Id3MetadataListener { - void onId3Metadata(Map metadata); + void onId3Metadata(List id3Frames); } // Constants pulled into this class for convenience. @@ -187,8 +187,8 @@ public DemoPlayer(Context context, SourceBuilder sourceBuilder) { true, mainHandler, this, AudioCapabilities.getCapabilities(context), AudioManager.STREAM_MUSIC); TrackRenderer textRenderer = new TextTrackRenderer(this, mainHandler.getLooper()); - MetadataTrackRenderer> id3Renderer = new MetadataTrackRenderer<>( - new Id3Parser(), this, mainHandler.getLooper()); + MetadataTrackRenderer> id3Renderer = new MetadataTrackRenderer<>(new Id3Parser(), + this, mainHandler.getLooper()); TrackRenderer[] renderers = new TrackRenderer[] {videoRenderer, audioRenderer, textRenderer, id3Renderer}; @@ -434,9 +434,9 @@ public void onCues(List cues) { } @Override - public void onMetadata(Map metadata) { + public void onMetadata(List id3Frames) { if (id3MetadataListener != null && trackInfo.getTrackSelection(TYPE_METADATA) != null) { - id3MetadataListener.onId3Metadata(metadata); + id3MetadataListener.onId3Metadata(id3Frames); } } diff --git a/library/src/androidTest/java/com/google/android/exoplayer/metadata/Id3ParserTest.java b/library/src/androidTest/java/com/google/android/exoplayer/metadata/id3/Id3ParserTest.java similarity index 63% rename from library/src/androidTest/java/com/google/android/exoplayer/metadata/Id3ParserTest.java rename to library/src/androidTest/java/com/google/android/exoplayer/metadata/id3/Id3ParserTest.java index 1dead0a139d..6946ba3b071 100644 --- a/library/src/androidTest/java/com/google/android/exoplayer/metadata/Id3ParserTest.java +++ b/library/src/androidTest/java/com/google/android/exoplayer/metadata/id3/Id3ParserTest.java @@ -13,11 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.metadata; +package com.google.android.exoplayer.metadata.id3; import junit.framework.TestCase; -import java.util.Map; +import java.util.List; /** * Test for {@link Id3Parser} @@ -25,19 +25,17 @@ public class Id3ParserTest extends TestCase { public void testParseTxxxFrames() { - byte[] rawId3 = new byte[] { 73, 68, 51, 4, 0, 0, 0, 0, 0, 41, 84, 88, 88, 88, 0, 0, 0, 31, + byte[] rawId3 = new byte[] {73, 68, 51, 4, 0, 0, 0, 0, 0, 41, 84, 88, 88, 88, 0, 0, 0, 31, 0, 0, 3, 0, 109, 100, 105, 97, 108, 111, 103, 95, 86, 73, 78, 68, 73, 67, 79, 49, 53, 50, - 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0 }; - + 55, 54, 54, 52, 95, 115, 116, 97, 114, 116, 0}; Id3Parser parser = new Id3Parser(); try { - Map metadata = parser.parse(rawId3, rawId3.length); - assertNotNull(metadata); - assertEquals(1, metadata.size()); - TxxxMetadata txxx = (TxxxMetadata) metadata.get(TxxxMetadata.TYPE); - assertNotNull(txxx); - assertEquals("", txxx.description); - assertEquals("mdialog_VINDICO1527664_start", txxx.value); + List id3Frames = parser.parse(rawId3, rawId3.length); + assertNotNull(id3Frames); + assertEquals(1, id3Frames.size()); + TxxxFrame txxxFrame = (TxxxFrame) id3Frames.get(0); + assertEquals("", txxxFrame.description); + assertEquals("mdialog_VINDICO1527664_start", txxxFrame.value); } catch (Exception exception) { fail(exception.getMessage()); } diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/id3/BinaryFrame.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/BinaryFrame.java new file mode 100644 index 00000000000..65eda909c25 --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/BinaryFrame.java @@ -0,0 +1,30 @@ +/* + * 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.id3; + +/** + * Binary ID3 frame. + */ +public final class BinaryFrame extends Id3Frame { + + public final byte[] data; + + public BinaryFrame(String type, byte[] data) { + super(type); + this.data = data; + } + +} diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/GeobMetadata.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/GeobFrame.java similarity index 72% rename from library/src/main/java/com/google/android/exoplayer/metadata/GeobMetadata.java rename to library/src/main/java/com/google/android/exoplayer/metadata/id3/GeobFrame.java index 6cc61dd4686..109b1fb4b0c 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/GeobMetadata.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/GeobFrame.java @@ -13,22 +13,22 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.metadata; +package com.google.android.exoplayer.metadata.id3; /** - * A metadata that contains parsed ID3 GEOB (General Encapsulated Object) frame data associated - * with time indices. + * GEOB (General Encapsulated Object) ID3 frame. */ -public final class GeobMetadata { +public final class GeobFrame extends Id3Frame { - public static final String TYPE = "GEOB"; + public static final String ID = "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) { + public GeobFrame(String mimeType, String filename, String description, byte[] data) { + super(ID); this.mimeType = mimeType; this.filename = filename; this.description = description; diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Frame.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Frame.java new file mode 100644 index 00000000000..11e6f33f0c2 --- /dev/null +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Frame.java @@ -0,0 +1,32 @@ +/* + * 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.id3; + +/** + * Base class for ID3 frames. + */ +public abstract class Id3Frame { + + /** + * The frame ID. + */ + public final String id; + + public Id3Frame(String id) { + this.id = id; + } + +} diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/Id3Parser.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Parser.java similarity index 89% rename from library/src/main/java/com/google/android/exoplayer/metadata/Id3Parser.java rename to library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Parser.java index 6b52cb5371f..deac62d8e50 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/Id3Parser.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/Id3Parser.java @@ -13,22 +13,23 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.metadata; +package com.google.android.exoplayer.metadata.id3; import com.google.android.exoplayer.ParserException; +import com.google.android.exoplayer.metadata.MetadataParser; import com.google.android.exoplayer.util.MimeTypes; import com.google.android.exoplayer.util.ParsableByteArray; import java.io.UnsupportedEncodingException; +import java.util.ArrayList; import java.util.Collections; -import java.util.HashMap; +import java.util.List; import java.util.Locale; -import java.util.Map; /** * Extracts individual TXXX text frames from raw ID3 data. */ -public final class Id3Parser implements MetadataParser> { +public final class Id3Parser implements MetadataParser> { private static final int ID3_TEXT_ENCODING_ISO_8859_1 = 0; private static final int ID3_TEXT_ENCODING_UTF_16 = 1; @@ -41,9 +42,9 @@ public boolean canParse(String mimeType) { } @Override - public Map parse(byte[] data, int size) - throws UnsupportedEncodingException, ParserException { - Map metadata = new HashMap<>(); + public List parse(byte[] data, int size) throws UnsupportedEncodingException, + ParserException { + List id3Frames = new ArrayList<>(); ParsableByteArray id3Data = new ParsableByteArray(data, size); int id3Size = parseId3Header(id3Data); @@ -70,9 +71,8 @@ public Map parse(byte[] data, int size) String description = new String(frame, 0, firstZeroIndex, charset); int valueStartIndex = firstZeroIndex + delimiterLength(encoding); int valueEndIndex = indexOfEOS(frame, valueStartIndex, encoding); - String value = new String(frame, valueStartIndex, valueEndIndex - valueStartIndex, - charset); - metadata.put(TxxxMetadata.TYPE, new TxxxMetadata(description, value)); + String value = new String(frame, valueStartIndex, valueEndIndex - valueStartIndex, charset); + id3Frames.add(new TxxxFrame(description, value)); } else if (frameId0 == 'P' && frameId1 == 'R' && frameId2 == 'I' && frameId3 == 'V') { // Check frame ID == PRIV byte[] frame = new byte[frameSize]; @@ -82,7 +82,7 @@ public Map parse(byte[] data, int size) String owner = new String(frame, 0, firstZeroIndex, "ISO-8859-1"); 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)); + id3Frames.add(new PrivFrame(owner, privateData)); } else if (frameId0 == 'G' && frameId1 == 'E' && frameId2 == 'O' && frameId3 == 'B') { // Check frame ID == GEOB int encoding = id3Data.readUnsignedByte(); @@ -106,19 +106,18 @@ public Map parse(byte[] data, int size) byte[] objectData = new byte[objectDataSize]; System.arraycopy(frame, descriptionEndIndex + delimiterLength(encoding), objectData, 0, objectDataSize); - metadata.put(GeobMetadata.TYPE, new GeobMetadata(mimeType, filename, - description, objectData)); + id3Frames.add(new GeobFrame(mimeType, filename, description, objectData)); } else { String type = String.format(Locale.US, "%c%c%c%c", frameId0, frameId1, frameId2, frameId3); byte[] frame = new byte[frameSize]; id3Data.readBytes(frame, 0, frameSize); - metadata.put(type, frame); + id3Frames.add(new BinaryFrame(type, frame)); } id3Size -= frameSize + 10 /* header size */; } - return Collections.unmodifiableMap(metadata); + return Collections.unmodifiableList(id3Frames); } private static int indexOf(byte[] data, int fromIndex, byte key) { @@ -150,8 +149,8 @@ private static int indexOfEOS(byte[] data, int fromIndex, int encodingByte) { } private static int delimiterLength(int encodingByte) { - return (encodingByte == ID3_TEXT_ENCODING_ISO_8859_1 - || encodingByte == ID3_TEXT_ENCODING_UTF_8) ? 1 : 2; + return (encodingByte == ID3_TEXT_ENCODING_ISO_8859_1 || encodingByte == ID3_TEXT_ENCODING_UTF_8) + ? 1 : 2; } /** diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/PrivMetadata.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/PrivFrame.java similarity index 73% rename from library/src/main/java/com/google/android/exoplayer/metadata/PrivMetadata.java rename to library/src/main/java/com/google/android/exoplayer/metadata/id3/PrivFrame.java index 94ba6e52cc8..3a429b19e4e 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/PrivMetadata.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/PrivFrame.java @@ -13,20 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.metadata; +package com.google.android.exoplayer.metadata.id3; /** - * A metadata that contains parsed ID3 PRIV (Private) frame data associated - * with time indices. + * PRIV (Private) ID3 frame. */ -public final class PrivMetadata { +public final class PrivFrame extends Id3Frame { - public static final String TYPE = "PRIV"; + public static final String ID = "PRIV"; public final String owner; public final byte[] privateData; - public PrivMetadata(String owner, byte[] privateData) { + public PrivFrame(String owner, byte[] privateData) { + super(ID); this.owner = owner; this.privateData = privateData; } diff --git a/library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java b/library/src/main/java/com/google/android/exoplayer/metadata/id3/TxxxFrame.java similarity index 71% rename from library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java rename to library/src/main/java/com/google/android/exoplayer/metadata/id3/TxxxFrame.java index c0f1d2c5b38..f31ad9d54f6 100644 --- a/library/src/main/java/com/google/android/exoplayer/metadata/TxxxMetadata.java +++ b/library/src/main/java/com/google/android/exoplayer/metadata/id3/TxxxFrame.java @@ -13,20 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.google.android.exoplayer.metadata; +package com.google.android.exoplayer.metadata.id3; /** - * A metadata that contains parsed ID3 TXXX (User defined text information) frame data associated - * with time indices. + * TXXX (User defined text information) ID3 frame. */ -public final class TxxxMetadata { +public final class TxxxFrame extends Id3Frame { - public static final String TYPE = "TXXX"; + public static final String ID = "TXXX"; public final String description; public final String value; - public TxxxMetadata(String description, String value) { + public TxxxFrame(String description, String value) { + super(ID); this.description = description; this.value = value; }