ID3 refactoring to match apple's player behavior #67

This commit is contained in:
Andrey Udovenko 2014-11-05 11:54:45 -05:00
parent b946ad9234
commit 71f918c01b
7 changed files with 41 additions and 33 deletions

View File

@ -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> metadata) {
public void onMetadata(Map<String, Object> 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));
}
}
}

View File

@ -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> metadata);
void onMetadata(Map<String, Object> 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> metadata) {
public void onMetadata(Map<String, Object> metadata) {
if (metadataListener != null) {
metadataListener.onMetadata(metadata);
}

View File

@ -94,7 +94,7 @@ public class HlsRendererBuilder implements RendererBuilder, ManifestCallback<Hls
DataSource dataSource = new UriDataSource(userAgent, null);
HlsChunkSource chunkSource = new HlsChunkSource(dataSource, manifest);
HlsSampleSource sampleSource = new HlsSampleSource(chunkSource, loadControl,
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 2);
VIDEO_BUFFER_SEGMENTS * BUFFER_SEGMENT_SIZE, true, 3);
MediaCodecVideoTrackRenderer videoRenderer = new MediaCodecVideoTrackRenderer(sampleSource,
MediaCodec.VIDEO_SCALING_MODE_SCALE_TO_FIT, 0, player.getMainHandler(), player, 50);
MediaCodecAudioTrackRenderer audioRenderer = new MediaCodecAudioTrackRenderer(sampleSource);

View File

@ -20,9 +20,9 @@ import com.google.android.exoplayer.parser.ts.BitsArray;
import com.google.android.exoplayer.util.MimeTypes;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.HashMap;
import java.util.Map;
/**
* Extracts individual TXXX text frames from raw ID3 data.
@ -35,12 +35,12 @@ public class Id3Parser implements MetadataParser {
}
@Override
public List<Metadata> parse(byte[] data, int size)
public Map<String, Object> parse(byte[] data, int size)
throws UnsupportedEncodingException, ParserException {
BitsArray id3Buffer = new BitsArray(data, size);
int id3Size = parseId3Header(id3Buffer);
List<Metadata> metadata = new ArrayList<Metadata>();
Map<String, Object> metadata = new HashMap<String, Object>();
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) {

View File

@ -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<Metadata> parse(byte[] data, int size)
public Map<String, Object> parse(byte[] data, int size)
throws IOException;
}

View File

@ -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> metadata);
void onMetadata(Map<String, Object> metadata);
}
@ -63,7 +63,7 @@ public class MetadataTrackRenderer extends TrackRenderer implements Callback {
private boolean inputStreamEnded;
private long pendingMetadataTimestamp;
private List<Metadata> pendingMetadata;
private Map<String, Object> 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> metadata) {
private void invokeRenderer(Map<String, Object> 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<Metadata>) msg.obj);
invokeRendererInternal((Map<String, Object>) msg.obj);
return true;
}
return false;
}
private void invokeRendererInternal(List<Metadata> metadata) {
private void invokeRendererInternal(Map<String, Object> metadata) {
metadataRenderer.onMetadata(metadata);
}

View File

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