-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=117224172
This commit is contained in:
olly 2016-03-15 04:01:18 -07:00 committed by Oliver Woodman
parent 99606f6e2e
commit 9cfff0b028
9 changed files with 131 additions and 74 deletions

View File

@ -30,9 +30,10 @@ import com.google.android.exoplayer.demo.player.HlsSourceBuilder;
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.CookieHandler;
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 class PlayerActivity extends Activity implements SurfaceHolder.Callback,
// DemoPlayer.MetadataListener implementation
@Override
public void onId3Metadata(Map<String, Object> metadata) {
for (Map.Entry<String, Object> 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<Id3Frame> 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));
}
}
}

View File

@ -34,9 +34,10 @@ import com.google.android.exoplayer.chunk.ChunkSampleSource;
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 android.view.Surface;
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<Map<String, Object>>,
DashChunkSource.EventListener, TextRenderer, MetadataRenderer<List<Id3Frame>>,
DebugTextViewHelper.Provider {
/**
@ -140,7 +140,7 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
* A listener for receiving ID3 metadata parsed from the media stream.
*/
public interface Id3MetadataListener {
void onId3Metadata(Map<String, Object> metadata);
void onId3Metadata(List<Id3Frame> id3Frames);
}
// Constants pulled into this class for convenience.
@ -187,8 +187,8 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
true, mainHandler, this, AudioCapabilities.getCapabilities(context),
AudioManager.STREAM_MUSIC);
TrackRenderer textRenderer = new TextTrackRenderer(this, mainHandler.getLooper());
MetadataTrackRenderer<Map<String, Object>> id3Renderer = new MetadataTrackRenderer<>(
new Id3Parser(), this, mainHandler.getLooper());
MetadataTrackRenderer<List<Id3Frame>> id3Renderer = new MetadataTrackRenderer<>(new Id3Parser(),
this, mainHandler.getLooper());
TrackRenderer[] renderers = new TrackRenderer[] {videoRenderer, audioRenderer, textRenderer,
id3Renderer};
@ -434,9 +434,9 @@ public class DemoPlayer implements ExoPlayer.Listener, DefaultTrackSelector.Even
}
@Override
public void onMetadata(Map<String, Object> metadata) {
public void onMetadata(List<Id3Frame> id3Frames) {
if (id3MetadataListener != null && trackInfo.getTrackSelection(TYPE_METADATA) != null) {
id3MetadataListener.onId3Metadata(metadata);
id3MetadataListener.onId3Metadata(id3Frames);
}
}

View File

@ -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}
@ -28,16 +28,14 @@ public class Id3ParserTest extends TestCase {
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};
Id3Parser parser = new Id3Parser();
try {
Map<String, Object> 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<Id3Frame> 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());
}

View File

@ -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;
}
}

View File

@ -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;

View File

@ -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;
}
}

View File

@ -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<Map<String, Object>> {
public final class Id3Parser implements MetadataParser<List<Id3Frame>> {
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 final class Id3Parser implements MetadataParser<Map<String, Object>> {
}
@Override
public Map<String, Object> parse(byte[] data, int size)
throws UnsupportedEncodingException, ParserException {
Map<String, Object> metadata = new HashMap<>();
public List<Id3Frame> parse(byte[] data, int size) throws UnsupportedEncodingException,
ParserException {
List<Id3Frame> id3Frames = new ArrayList<>();
ParsableByteArray id3Data = new ParsableByteArray(data, size);
int id3Size = parseId3Header(id3Data);
@ -70,9 +71,8 @@ public final class Id3Parser implements MetadataParser<Map<String, Object>> {
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 final class Id3Parser implements MetadataParser<Map<String, Object>> {
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 final class Id3Parser implements MetadataParser<Map<String, Object>> {
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 @@ public final class Id3Parser implements MetadataParser<Map<String, Object>> {
}
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;
}
/**

View File

@ -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;
}

View File

@ -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;
}