Merge "MediaPlayer: initial timed id3 support"
diff --git a/api/current.txt b/api/current.txt
index 8f9641c..5bf0fbe 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -15996,6 +15996,7 @@
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
+ method public void setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackRate(float, int);
@@ -16053,6 +16054,10 @@
method public abstract void onSeekComplete(android.media.MediaPlayer);
}
+ public static abstract interface MediaPlayer.OnTimedMetaDataListener {
+ method public abstract void onTimedMetaData(android.media.MediaPlayer, android.media.TimedMetaData);
+ }
+
public static abstract interface MediaPlayer.OnTimedTextListener {
method public abstract void onTimedText(android.media.MediaPlayer, android.media.TimedText);
}
@@ -16068,6 +16073,7 @@
method public int getTrackType();
method public void writeToParcel(android.os.Parcel, int);
field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
+ field public static final int MEDIA_TRACK_TYPE_METADATA = 5; // 0x5
field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
field public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3; // 0x3
field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
@@ -16542,6 +16548,11 @@
field public static final int OPTIONS_RECYCLE_INPUT = 2; // 0x2
}
+ public class TimedMetaData {
+ method public byte[] getRawData();
+ method public long getTimeUs();
+ }
+
public final class TimedText {
method public android.graphics.Rect getBounds();
method public java.lang.String getText();
diff --git a/api/system-current.txt b/api/system-current.txt
index 0f837c2..44bbe5f 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -17209,6 +17209,7 @@
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
+ method public void setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener);
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
method public void setPlaybackRate(float, int);
@@ -17266,6 +17267,10 @@
method public abstract void onSeekComplete(android.media.MediaPlayer);
}
+ public static abstract interface MediaPlayer.OnTimedMetaDataListener {
+ method public abstract void onTimedMetaData(android.media.MediaPlayer, android.media.TimedMetaData);
+ }
+
public static abstract interface MediaPlayer.OnTimedTextListener {
method public abstract void onTimedText(android.media.MediaPlayer, android.media.TimedText);
}
@@ -17281,6 +17286,7 @@
method public int getTrackType();
method public void writeToParcel(android.os.Parcel, int);
field public static final int MEDIA_TRACK_TYPE_AUDIO = 2; // 0x2
+ field public static final int MEDIA_TRACK_TYPE_METADATA = 5; // 0x5
field public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4; // 0x4
field public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3; // 0x3
field public static final int MEDIA_TRACK_TYPE_UNKNOWN = 0; // 0x0
@@ -17757,6 +17763,11 @@
field public static final int OPTIONS_RECYCLE_INPUT = 2; // 0x2
}
+ public class TimedMetaData {
+ method public byte[] getRawData();
+ method public long getTimeUs();
+ }
+
public final class TimedText {
method public android.graphics.Rect getBounds();
method public java.lang.String getText();
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index cb80bc4..210d08f 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -1837,6 +1837,7 @@
public static final int MEDIA_TRACK_TYPE_AUDIO = 2;
public static final int MEDIA_TRACK_TYPE_TIMEDTEXT = 3;
public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
+ public static final int MEDIA_TRACK_TYPE_METADATA = 5;
final int mTrackType;
final MediaFormat mFormat;
@@ -2577,6 +2578,7 @@
private static final int MEDIA_ERROR = 100;
private static final int MEDIA_INFO = 200;
private static final int MEDIA_SUBTITLE_DATA = 201;
+ private static final int MEDIA_META_DATA = 202;
private TimeProvider mTimeProvider;
@@ -2724,6 +2726,18 @@
}
return;
+ case MEDIA_META_DATA:
+ if (mOnTimedMetaDataListener == null) {
+ return;
+ }
+ if (msg.obj instanceof Parcel) {
+ Parcel parcel = (Parcel) msg.obj;
+ TimedMetaData data = TimedMetaData.createTimedMetaDataFromParcel(parcel);
+ parcel.recycle();
+ mOnTimedMetaDataListener.onTimedMetaData(mMediaPlayer, data);
+ }
+ return;
+
case MEDIA_NOP: // interface test message - ignore
break;
@@ -2960,6 +2974,46 @@
private OnSubtitleDataListener mOnSubtitleDataListener;
+ /**
+ * Interface definition of a callback to be invoked when a
+ * track has timed metadata available.
+ *
+ * @see MediaPlayer#setOnTimedMetaDataListener(OnTimedMetaDataListener)
+ */
+ public interface OnTimedMetaDataListener
+ {
+ /**
+ * Called to indicate avaliable timed metadata
+ * <p>
+ * This method will be called as timed metadata is extracted from the media,
+ * in the same order as it occurs in the media. The timing of this event is
+ * not controlled by the associated timestamp.
+ *
+ * @param mp the MediaPlayer associated with this callback
+ * @param data the timed metadata sample associated with this event
+ */
+ public void onTimedMetaData(MediaPlayer mp, TimedMetaData data);
+ }
+
+ /**
+ * Register a callback to be invoked when a selected track has timed metadata available.
+ * <p>
+ * Currently only HTTP live streaming data URI's embedded with timed ID3 tags generates
+ * {@link TimedMetaData}.
+ *
+ * @see MediaPlayer#selectTrack(int)
+ * @see MediaPlayer.OnTimedMetaDataListener
+ * @see TimedMetaData
+ *
+ * @param listener the callback that will be run
+ */
+ public void setOnTimedMetaDataListener(OnTimedMetaDataListener listener)
+ {
+ mOnTimedMetaDataListener = listener;
+ }
+
+ private OnTimedMetaDataListener mOnTimedMetaDataListener;
+
/* Do not change these values without updating their counterparts
* in include/media/mediaplayer.h!
*/
diff --git a/media/java/android/media/TimedMetaData.java b/media/java/android/media/TimedMetaData.java
new file mode 100644
index 0000000..dceb050
--- /dev/null
+++ b/media/java/android/media/TimedMetaData.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2015 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 android.media;
+
+import android.os.Parcel;
+
+/**
+ * Class that embodies a piece of timed metadata, including
+ *
+ * <ul>
+ * <li> a time stamp, and </li>
+ * <li> raw uninterpreted byte-array extracted directly from the container. </li>
+ * </ul>
+ *
+ * @see MediaPlayer#setOnTimedMetaDataListener(android.media.MediaPlayer.OnTimedMetaDataListener)
+ */
+
+public class TimedMetaData {
+ private static final String TAG = "TimedMetaData";
+
+ private long mTimeUs;
+ private byte[] mRawData;
+
+ /**
+ * @hide
+ */
+ static TimedMetaData createTimedMetaDataFromParcel(Parcel parcel) {
+ return new TimedMetaData(parcel);
+ }
+
+ private TimedMetaData(Parcel parcel) {
+ if (!parseParcel(parcel)) {
+ throw new IllegalArgumentException("parseParcel() fails");
+ }
+ }
+
+ public long getTimeUs() {
+ return mTimeUs;
+ }
+
+ public byte[] getRawData() {
+ return mRawData;
+ }
+
+ private boolean parseParcel(Parcel parcel) {
+ parcel.setDataPosition(0);
+ if (parcel.dataAvail() == 0) {
+ return false;
+ }
+
+ mTimeUs = parcel.readLong();
+ mRawData = new byte[parcel.readInt()];
+ parcel.readByteArray(mRawData);
+
+ return true;
+ }
+}