Merge "Merge "MediaPlayer subtitle data / time discontinuity interfaces" into pi-dev am: 26ef7344c9" into pi-dev-plus-aosp
This commit is contained in:
committed by
Android (Google) Code Review
commit
77fca22044
@@ -23719,6 +23719,8 @@ package android.media {
|
|||||||
field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
|
field public static final java.lang.String MIMETYPE_AUDIO_VORBIS = "audio/vorbis";
|
||||||
field public static final java.lang.String MIMETYPE_IMAGE_ANDROID_HEIC = "image/vnd.android.heic";
|
field public static final java.lang.String MIMETYPE_IMAGE_ANDROID_HEIC = "image/vnd.android.heic";
|
||||||
field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
|
field public static final java.lang.String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
|
||||||
|
field public static final java.lang.String MIMETYPE_TEXT_CEA_708 = "text/cea-708";
|
||||||
|
field public static final java.lang.String MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
|
||||||
field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
|
field public static final java.lang.String MIMETYPE_TEXT_VTT = "text/vtt";
|
||||||
field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
|
field public static final java.lang.String MIMETYPE_VIDEO_AVC = "video/avc";
|
||||||
field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
|
field public static final java.lang.String MIMETYPE_VIDEO_DOLBY_VISION = "video/dolby-vision";
|
||||||
@@ -23900,6 +23902,8 @@ package android.media {
|
|||||||
method public void addTimedTextSource(java.io.FileDescriptor, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
|
method public void addTimedTextSource(java.io.FileDescriptor, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
|
||||||
method public void addTimedTextSource(java.io.FileDescriptor, long, long, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
|
method public void addTimedTextSource(java.io.FileDescriptor, long, long, java.lang.String) throws java.lang.IllegalArgumentException, java.lang.IllegalStateException;
|
||||||
method public void attachAuxEffect(int);
|
method public void attachAuxEffect(int);
|
||||||
|
method public void clearOnMediaTimeDiscontinuityListener();
|
||||||
|
method public void clearOnSubtitleDataListener();
|
||||||
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri);
|
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri);
|
||||||
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder);
|
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder);
|
||||||
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder, android.media.AudioAttributes, int);
|
method public static android.media.MediaPlayer create(android.content.Context, android.net.Uri, android.view.SurfaceHolder, android.media.AudioAttributes, int);
|
||||||
@@ -23964,8 +23968,12 @@ package android.media {
|
|||||||
method public void setOnDrmPreparedListener(android.media.MediaPlayer.OnDrmPreparedListener, android.os.Handler);
|
method public void setOnDrmPreparedListener(android.media.MediaPlayer.OnDrmPreparedListener, android.os.Handler);
|
||||||
method public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener);
|
method public void setOnErrorListener(android.media.MediaPlayer.OnErrorListener);
|
||||||
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
|
method public void setOnInfoListener(android.media.MediaPlayer.OnInfoListener);
|
||||||
|
method public void setOnMediaTimeDiscontinuityListener(android.media.MediaPlayer.OnMediaTimeDiscontinuityListener, android.os.Handler);
|
||||||
|
method public void setOnMediaTimeDiscontinuityListener(android.media.MediaPlayer.OnMediaTimeDiscontinuityListener);
|
||||||
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
|
method public void setOnPreparedListener(android.media.MediaPlayer.OnPreparedListener);
|
||||||
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
|
method public void setOnSeekCompleteListener(android.media.MediaPlayer.OnSeekCompleteListener);
|
||||||
|
method public void setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener, android.os.Handler);
|
||||||
|
method public void setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener);
|
||||||
method public void setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataAvailableListener);
|
method public void setOnTimedMetaDataAvailableListener(android.media.MediaPlayer.OnTimedMetaDataAvailableListener);
|
||||||
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
|
method public void setOnTimedTextListener(android.media.MediaPlayer.OnTimedTextListener);
|
||||||
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
|
method public void setOnVideoSizeChangedListener(android.media.MediaPlayer.OnVideoSizeChangedListener);
|
||||||
@@ -23998,7 +24006,7 @@ package android.media {
|
|||||||
field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
|
field public static final int MEDIA_INFO_VIDEO_NOT_PLAYING = 805; // 0x325
|
||||||
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
|
field public static final int MEDIA_INFO_VIDEO_RENDERING_START = 3; // 0x3
|
||||||
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
|
field public static final int MEDIA_INFO_VIDEO_TRACK_LAGGING = 700; // 0x2bc
|
||||||
field public static final java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
|
field public static final deprecated java.lang.String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
|
||||||
field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
|
field public static final int PREPARE_DRM_STATUS_PREPARATION_ERROR = 3; // 0x3
|
||||||
field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
|
field public static final int PREPARE_DRM_STATUS_PROVISIONING_NETWORK_ERROR = 1; // 0x1
|
||||||
field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
|
field public static final int PREPARE_DRM_STATUS_PROVISIONING_SERVER_ERROR = 2; // 0x2
|
||||||
@@ -24063,6 +24071,10 @@ package android.media {
|
|||||||
method public abstract boolean onInfo(android.media.MediaPlayer, int, int);
|
method public abstract boolean onInfo(android.media.MediaPlayer, int, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract interface MediaPlayer.OnMediaTimeDiscontinuityListener {
|
||||||
|
method public abstract void onMediaTimeDiscontinuity(android.media.MediaPlayer, android.media.MediaTimestamp);
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract interface MediaPlayer.OnPreparedListener {
|
public static abstract interface MediaPlayer.OnPreparedListener {
|
||||||
method public abstract void onPrepared(android.media.MediaPlayer);
|
method public abstract void onPrepared(android.media.MediaPlayer);
|
||||||
}
|
}
|
||||||
@@ -24071,6 +24083,10 @@ package android.media {
|
|||||||
method public abstract void onSeekComplete(android.media.MediaPlayer);
|
method public abstract void onSeekComplete(android.media.MediaPlayer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static abstract interface MediaPlayer.OnSubtitleDataListener {
|
||||||
|
method public abstract void onSubtitleData(android.media.MediaPlayer, android.media.SubtitleData);
|
||||||
|
}
|
||||||
|
|
||||||
public static abstract interface MediaPlayer.OnTimedMetaDataAvailableListener {
|
public static abstract interface MediaPlayer.OnTimedMetaDataAvailableListener {
|
||||||
method public abstract void onTimedMetaDataAvailable(android.media.MediaPlayer, android.media.TimedMetaData);
|
method public abstract void onTimedMetaDataAvailable(android.media.MediaPlayer, android.media.TimedMetaData);
|
||||||
}
|
}
|
||||||
@@ -24423,6 +24439,7 @@ package android.media {
|
|||||||
method public long getAnchorMediaTimeUs();
|
method public long getAnchorMediaTimeUs();
|
||||||
method public long getAnchorSytemNanoTime();
|
method public long getAnchorSytemNanoTime();
|
||||||
method public float getMediaClockRate();
|
method public float getMediaClockRate();
|
||||||
|
field public static final android.media.MediaTimestamp TIMESTAMP_UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final class MicrophoneInfo {
|
public final class MicrophoneInfo {
|
||||||
@@ -24683,6 +24700,13 @@ package android.media {
|
|||||||
method public abstract void onLoadComplete(android.media.SoundPool, int, int);
|
method public abstract void onLoadComplete(android.media.SoundPool, int, int);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final class SubtitleData {
|
||||||
|
method public byte[] getData();
|
||||||
|
method public long getDurationUs();
|
||||||
|
method public long getStartTimeUs();
|
||||||
|
method public int getTrackIndex();
|
||||||
|
}
|
||||||
|
|
||||||
public final class SyncParams {
|
public final class SyncParams {
|
||||||
ctor public SyncParams();
|
ctor public SyncParams();
|
||||||
method public android.media.SyncParams allowDefaults();
|
method public android.media.SyncParams allowDefaults();
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ public class ClosedCaptionRenderer extends SubtitleController.Renderer {
|
|||||||
public boolean supports(MediaFormat format) {
|
public boolean supports(MediaFormat format) {
|
||||||
if (format.containsKey(MediaFormat.KEY_MIME)) {
|
if (format.containsKey(MediaFormat.KEY_MIME)) {
|
||||||
String mimeType = format.getString(MediaFormat.KEY_MIME);
|
String mimeType = format.getString(MediaFormat.KEY_MIME);
|
||||||
return MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_608.equals(mimeType);
|
return MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType);
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -67,7 +67,7 @@ public class ClosedCaptionRenderer extends SubtitleController.Renderer {
|
|||||||
@Override
|
@Override
|
||||||
public SubtitleTrack createTrack(MediaFormat format) {
|
public SubtitleTrack createTrack(MediaFormat format) {
|
||||||
String mimeType = format.getString(MediaFormat.KEY_MIME);
|
String mimeType = format.getString(MediaFormat.KEY_MIME);
|
||||||
if (MediaPlayer.MEDIA_MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
|
if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mimeType)) {
|
||||||
if (mCCWidget == null) {
|
if (mCCWidget == null) {
|
||||||
mCCWidget = new Cea608CCWidget(mContext);
|
mCCWidget = new Cea608CCWidget(mContext);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -173,11 +173,21 @@ public final class MediaFormat {
|
|||||||
*/
|
*/
|
||||||
public static final String MIMETYPE_TEXT_VTT = "text/vtt";
|
public static final String MIMETYPE_TEXT_VTT = "text/vtt";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME type for SubRip (SRT) container.
|
||||||
|
*/
|
||||||
|
public static final String MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MIME type for CEA-608 closed caption data.
|
* MIME type for CEA-608 closed caption data.
|
||||||
*/
|
*/
|
||||||
public static final String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
|
public static final String MIMETYPE_TEXT_CEA_608 = "text/cea-608";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* MIME type for CEA-708 closed caption data.
|
||||||
|
*/
|
||||||
|
public static final String MIMETYPE_TEXT_CEA_708 = "text/cea-708";
|
||||||
|
|
||||||
private Map<String, Object> mMap;
|
private Map<String, Object> mMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -2416,7 +2416,7 @@ public class MediaPlayer extends PlayerBase
|
|||||||
* Gets the track type.
|
* Gets the track type.
|
||||||
* @return TrackType which indicates if the track is video, audio, timed text.
|
* @return TrackType which indicates if the track is video, audio, timed text.
|
||||||
*/
|
*/
|
||||||
public int getTrackType() {
|
public @TrackType int getTrackType() {
|
||||||
return mTrackType;
|
return mTrackType;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2450,6 +2450,19 @@ public class MediaPlayer extends PlayerBase
|
|||||||
public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
|
public static final int MEDIA_TRACK_TYPE_SUBTITLE = 4;
|
||||||
public static final int MEDIA_TRACK_TYPE_METADATA = 5;
|
public static final int MEDIA_TRACK_TYPE_METADATA = 5;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
|
@IntDef(flag = false, prefix = "MEDIA_TRACK_TYPE", value = {
|
||||||
|
MEDIA_TRACK_TYPE_UNKNOWN,
|
||||||
|
MEDIA_TRACK_TYPE_VIDEO,
|
||||||
|
MEDIA_TRACK_TYPE_AUDIO,
|
||||||
|
MEDIA_TRACK_TYPE_TIMEDTEXT,
|
||||||
|
MEDIA_TRACK_TYPE_SUBTITLE,
|
||||||
|
MEDIA_TRACK_TYPE_METADATA }
|
||||||
|
)
|
||||||
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
|
public @interface TrackType {}
|
||||||
|
|
||||||
|
|
||||||
final int mTrackType;
|
final int mTrackType;
|
||||||
final MediaFormat mFormat;
|
final MediaFormat mFormat;
|
||||||
|
|
||||||
@@ -2600,26 +2613,30 @@ public class MediaPlayer extends PlayerBase
|
|||||||
*/
|
*/
|
||||||
/**
|
/**
|
||||||
* MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs.
|
* MIME type for SubRip (SRT) container. Used in addTimedTextSource APIs.
|
||||||
|
* @deprecated use {@link MediaFormat#MIMETYPE_TEXT_SUBRIP}
|
||||||
*/
|
*/
|
||||||
public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = "application/x-subrip";
|
public static final String MEDIA_MIMETYPE_TEXT_SUBRIP = MediaFormat.MIMETYPE_TEXT_SUBRIP;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MIME type for WebVTT subtitle data.
|
* MIME type for WebVTT subtitle data.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static final String MEDIA_MIMETYPE_TEXT_VTT = "text/vtt";
|
public static final String MEDIA_MIMETYPE_TEXT_VTT = MediaFormat.MIMETYPE_TEXT_VTT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MIME type for CEA-608 closed caption data.
|
* MIME type for CEA-608 closed caption data.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static final String MEDIA_MIMETYPE_TEXT_CEA_608 = "text/cea-608";
|
public static final String MEDIA_MIMETYPE_TEXT_CEA_608 = MediaFormat.MIMETYPE_TEXT_CEA_608;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* MIME type for CEA-708 closed caption data.
|
* MIME type for CEA-708 closed caption data.
|
||||||
* @hide
|
* @hide
|
||||||
|
* @deprecated
|
||||||
*/
|
*/
|
||||||
public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = "text/cea-708";
|
public static final String MEDIA_MIMETYPE_TEXT_CEA_708 = MediaFormat.MIMETYPE_TEXT_CEA_708;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* A helper function to check if the mime type is supported by media framework.
|
* A helper function to check if the mime type is supported by media framework.
|
||||||
@@ -3108,7 +3125,7 @@ public class MediaPlayer extends PlayerBase
|
|||||||
* this function is called.
|
* this function is called.
|
||||||
* </p>
|
* </p>
|
||||||
* <p>
|
* <p>
|
||||||
* Currently, only timed text tracks or audio tracks can be selected via this method.
|
* Currently, only timed text, subtitle or audio tracks can be selected via this method.
|
||||||
* In addition, the support for selecting an audio track at runtime is pretty limited
|
* In addition, the support for selecting an audio track at runtime is pretty limited
|
||||||
* in that an audio track can only be selected in the <em>Prepared</em> state.
|
* in that an audio track can only be selected in the <em>Prepared</em> state.
|
||||||
* </p>
|
* </p>
|
||||||
@@ -3795,29 +3812,158 @@ public class MediaPlayer extends PlayerBase
|
|||||||
private OnTimedTextListener mOnTimedTextListener;
|
private OnTimedTextListener mOnTimedTextListener;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface definition of a callback to be invoked when a
|
* Interface definition of a callback to be invoked when a player subtitle track has new
|
||||||
* track has data available.
|
* subtitle data available.
|
||||||
*
|
* See the {@link MediaPlayer#setOnSubtitleDataListener(OnSubtitleDataListener, Handler)}
|
||||||
* @hide
|
* method for the description of which track will report data through this listener.
|
||||||
*/
|
*/
|
||||||
public interface OnSubtitleDataListener
|
public interface OnSubtitleDataListener {
|
||||||
{
|
/**
|
||||||
public void onSubtitleData(MediaPlayer mp, SubtitleData data);
|
* Method called when new subtitle data is available
|
||||||
|
* @param mp the player that reports the new subtitle data
|
||||||
|
* @param data the subtitle data
|
||||||
|
*/
|
||||||
|
public void onSubtitleData(@NonNull MediaPlayer mp, @NonNull SubtitleData data);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Register a callback to be invoked when a track has data available.
|
* Sets the listener to be invoked when a subtitle track has new data available.
|
||||||
*
|
* The subtitle data comes from a subtitle track previously selected with
|
||||||
* @param listener the callback that will be run
|
* {@link #selectTrack(int)}. Use {@link #getTrackInfo()} to determine which tracks are
|
||||||
*
|
* subtitles (of type {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}), Subtitle track encodings
|
||||||
* @hide
|
* can be determined by {@link TrackInfo#getFormat()}).<br>
|
||||||
|
* See {@link SubtitleData} for an example of querying subtitle encoding.
|
||||||
|
* @param listener the listener called when new data is available
|
||||||
|
* @param handler the {@link Handler} that receives the listener events
|
||||||
*/
|
*/
|
||||||
public void setOnSubtitleDataListener(OnSubtitleDataListener listener)
|
public void setOnSubtitleDataListener(@NonNull OnSubtitleDataListener listener,
|
||||||
|
@NonNull Handler handler) {
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null listener");
|
||||||
|
}
|
||||||
|
if (handler == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null handler");
|
||||||
|
}
|
||||||
|
setOnSubtitleDataListenerInt(listener, handler);
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Sets the listener to be invoked when a subtitle track has new data available.
|
||||||
|
* The subtitle data comes from a subtitle track previously selected with
|
||||||
|
* {@link #selectTrack(int)}. Use {@link #getTrackInfo()} to determine which tracks are
|
||||||
|
* subtitles (of type {@link TrackInfo#MEDIA_TRACK_TYPE_SUBTITLE}), Subtitle track encodings
|
||||||
|
* can be determined by {@link TrackInfo#getFormat()}).<br>
|
||||||
|
* See {@link SubtitleData} for an example of querying subtitle encoding.<br>
|
||||||
|
* The listener will be called on the same thread as the one in which the MediaPlayer was
|
||||||
|
* created.
|
||||||
|
* @param listener the listener called when new data is available
|
||||||
|
*/
|
||||||
|
public void setOnSubtitleDataListener(@NonNull OnSubtitleDataListener listener)
|
||||||
{
|
{
|
||||||
mOnSubtitleDataListener = listener;
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null listener");
|
||||||
|
}
|
||||||
|
setOnSubtitleDataListenerInt(listener, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the listener previously set with
|
||||||
|
* {@link #setOnSubtitleDataListener(OnSubtitleDataListener)} or
|
||||||
|
* {@link #setOnSubtitleDataListener(OnSubtitleDataListener, Handler)}.
|
||||||
|
*/
|
||||||
|
public void clearOnSubtitleDataListener() {
|
||||||
|
setOnSubtitleDataListenerInt(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOnSubtitleDataListenerInt(
|
||||||
|
@Nullable OnSubtitleDataListener listener, @Nullable Handler handler) {
|
||||||
|
synchronized (this) {
|
||||||
|
mOnSubtitleDataListener = listener;
|
||||||
|
mOnSubtitleDataHandler = handler;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private OnSubtitleDataListener mOnSubtitleDataListener;
|
private OnSubtitleDataListener mOnSubtitleDataListener;
|
||||||
|
private Handler mOnSubtitleDataHandler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Interface definition of a callback to be invoked when discontinuity in the normal progression
|
||||||
|
* of the media time is detected.
|
||||||
|
* The "normal progression" of media time is defined as the expected increase of the playback
|
||||||
|
* position when playing media, relative to the playback speed (for instance every second, media
|
||||||
|
* time increases by two seconds when playing at 2x).<br>
|
||||||
|
* Discontinuities are encountered in the following cases:
|
||||||
|
* <ul>
|
||||||
|
* <li>when the player is starved for data and cannot play anymore</li>
|
||||||
|
* <li>when the player encounters a playback error</li>
|
||||||
|
* <li>when the a seek operation starts, and when it's completed</li>
|
||||||
|
* <li>when the playback speed changes</li>
|
||||||
|
* <li>when the playback state changes</li>
|
||||||
|
* <li>when the player is reset</li>
|
||||||
|
* </ul>
|
||||||
|
* See the
|
||||||
|
* {@link MediaPlayer#setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener, Handler)}
|
||||||
|
* method to set a listener for these events.
|
||||||
|
*/
|
||||||
|
public interface OnMediaTimeDiscontinuityListener {
|
||||||
|
/**
|
||||||
|
* Called to indicate a time discontinuity has occured.
|
||||||
|
* @param mp the MediaPlayer for which the discontinuity has occured.
|
||||||
|
* @param mts the timestamp that correlates media time, system time and clock rate,
|
||||||
|
* or {@link MediaTimestamp#TIMESTAMP_UNKNOWN} in an error case.
|
||||||
|
*/
|
||||||
|
public void onMediaTimeDiscontinuity(@NonNull MediaPlayer mp, @NonNull MediaTimestamp mts);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the listener to be invoked when a media time discontinuity is encountered.
|
||||||
|
* @param listener the listener called after a discontinuity
|
||||||
|
* @param handler the {@link Handler} that receives the listener events
|
||||||
|
*/
|
||||||
|
public void setOnMediaTimeDiscontinuityListener(
|
||||||
|
@NonNull OnMediaTimeDiscontinuityListener listener, @NonNull Handler handler) {
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null listener");
|
||||||
|
}
|
||||||
|
if (handler == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null handler");
|
||||||
|
}
|
||||||
|
setOnMediaTimeDiscontinuityListenerInt(listener, handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the listener to be invoked when a media time discontinuity is encountered.
|
||||||
|
* The listener will be called on the same thread as the one in which the MediaPlayer was
|
||||||
|
* created.
|
||||||
|
* @param listener the listener called after a discontinuity
|
||||||
|
*/
|
||||||
|
public void setOnMediaTimeDiscontinuityListener(
|
||||||
|
@NonNull OnMediaTimeDiscontinuityListener listener)
|
||||||
|
{
|
||||||
|
if (listener == null) {
|
||||||
|
throw new IllegalArgumentException("Illegal null listener");
|
||||||
|
}
|
||||||
|
setOnMediaTimeDiscontinuityListenerInt(listener, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Clears the listener previously set with
|
||||||
|
* {@link #setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener)}
|
||||||
|
* or {@link #setOnMediaTimeDiscontinuityListener(OnMediaTimeDiscontinuityListener, Handler)}
|
||||||
|
*/
|
||||||
|
public void clearOnMediaTimeDiscontinuityListener() {
|
||||||
|
setOnMediaTimeDiscontinuityListenerInt(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void setOnMediaTimeDiscontinuityListenerInt(
|
||||||
|
@Nullable OnMediaTimeDiscontinuityListener listener, @Nullable Handler handler) {
|
||||||
|
synchronized (this) {
|
||||||
|
mOnMediaTimeDiscontinuityListener = listener;
|
||||||
|
mOnMediaTimeDiscontinuityHandler = handler;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private OnMediaTimeDiscontinuityListener mOnMediaTimeDiscontinuityListener;
|
||||||
|
private Handler mOnMediaTimeDiscontinuityHandler;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface definition of a callback to be invoked when a
|
* Interface definition of a callback to be invoked when a
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ package android.media;
|
|||||||
*/
|
*/
|
||||||
public final class MediaTimestamp
|
public final class MediaTimestamp
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* An unknown media timestamp value
|
||||||
|
*/
|
||||||
|
public static final MediaTimestamp TIMESTAMP_UNKNOWN = new MediaTimestamp(-1, -1, 0.0f);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the media time of the anchor in microseconds.
|
* Get the media time of the anchor in microseconds.
|
||||||
*/
|
*/
|
||||||
@@ -82,4 +87,15 @@ public final class MediaTimestamp
|
|||||||
nanoTime = 0;
|
nanoTime = 0;
|
||||||
clockRate = 1.0f;
|
clockRate = 1.0f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
if (this == obj) return true;
|
||||||
|
if (obj == null || getClass() != obj.getClass()) return false;
|
||||||
|
|
||||||
|
final MediaTimestamp that = (MediaTimestamp) obj;
|
||||||
|
return (this.mediaTimeUs == that.mediaTimeUs)
|
||||||
|
&& (this.nanoTime == that.nanoTime)
|
||||||
|
&& (this.clockRate == that.clockRate);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,26 +16,50 @@
|
|||||||
|
|
||||||
package android.media;
|
package android.media;
|
||||||
|
|
||||||
|
import android.annotation.NonNull;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @hide
|
* Class encapsulating subtitle data, as received through the
|
||||||
*
|
* {@link MediaPlayer.OnSubtitleDataListener} interface.
|
||||||
* Class to hold the subtitle track's data, including:
|
* The subtitle data includes:
|
||||||
* <ul>
|
* <ul>
|
||||||
* <li> Track index</li>
|
* <li> the track index</li>
|
||||||
* <li> Start time (in microseconds) of the data</li>
|
* <li> the start time (in microseconds) of the data</li>
|
||||||
* <li> Duration (in microseconds) of the data</li>
|
* <li> the duration (in microseconds) of the data</li>
|
||||||
* <li> A byte-array of the data</li>
|
* <li> the actual data.</li>
|
||||||
* </ul>
|
|
||||||
*
|
|
||||||
* <p> To receive the subtitle data, applications need to do the following:
|
|
||||||
*
|
|
||||||
* <ul>
|
|
||||||
* <li> Select a track of type MEDIA_TRACK_TYPE_SUBTITLE with {@link MediaPlayer.selectTrack(int)</li>
|
|
||||||
* <li> Implement the {@link MediaPlayer.OnSubtitleDataListener} interface</li>
|
|
||||||
* <li> Register the {@link MediaPlayer.OnSubtitleDataListener} callback on a MediaPlayer object</li>
|
|
||||||
* </ul>
|
* </ul>
|
||||||
|
* The data is stored in a byte-array, and is encoded in one of the supported in-band
|
||||||
|
* subtitle formats. The subtitle encoding is determined by the MIME type of the
|
||||||
|
* {@link MediaPlayer.TrackInfo} of the subtitle track, one of
|
||||||
|
* {@link MediaFormat#MIMETYPE_TEXT_CEA_608}, {@link MediaFormat#MIMETYPE_TEXT_CEA_708},
|
||||||
|
* {@link MediaFormat#MIMETYPE_TEXT_VTT}.
|
||||||
|
* <p>
|
||||||
|
* Here is an example of iterating over the tracks of a {@link MediaPlayer}, and checking which
|
||||||
|
* encoding is used for the subtitle tracks:
|
||||||
|
* <p>
|
||||||
|
* <pre class="prettyprint">
|
||||||
|
* MediaPlayer mp = new MediaPlayer();
|
||||||
|
* mp.setDataSource(myContentLocation);
|
||||||
|
* mp.prepare(); // synchronous prepare, ready to use when method returns
|
||||||
|
* final TrackInfo[] trackInfos = mp.getTrackInfo();
|
||||||
|
* for (TrackInfo info : trackInfo) {
|
||||||
|
* if (info.getTrackType() == TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) {
|
||||||
|
* final String mime = info.getFormat().getString(MediaFormat.KEY_MIME);
|
||||||
|
* if (MediaFormat.MIMETYPE_TEXT_CEA_608.equals(mime) {
|
||||||
|
* // subtitle encoding is CEA 608
|
||||||
|
* } else if (MediaFormat.MIMETYPE_TEXT_CEA_708.equals(mime) {
|
||||||
|
* // subtitle encoding is CEA 708
|
||||||
|
* } else if (MediaFormat.MIMETYPE_TEXT_VTT.equals(mime) {
|
||||||
|
* // subtitle encoding is WebVTT
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* }
|
||||||
|
* </pre>
|
||||||
|
* <p>
|
||||||
|
* See
|
||||||
|
* {@link MediaPlayer#setOnSubtitleDataListener(android.media.MediaPlayer.OnSubtitleDataListener, android.os.Handler)}
|
||||||
|
* to receive subtitle data from a MediaPlayer object.
|
||||||
*
|
*
|
||||||
* @see android.media.MediaPlayer
|
* @see android.media.MediaPlayer
|
||||||
*/
|
*/
|
||||||
@@ -48,25 +72,47 @@ public final class SubtitleData
|
|||||||
private long mDurationUs;
|
private long mDurationUs;
|
||||||
private byte[] mData;
|
private byte[] mData;
|
||||||
|
|
||||||
|
/** @hide */
|
||||||
public SubtitleData(Parcel parcel) {
|
public SubtitleData(Parcel parcel) {
|
||||||
if (!parseParcel(parcel)) {
|
if (!parseParcel(parcel)) {
|
||||||
throw new IllegalArgumentException("parseParcel() fails");
|
throw new IllegalArgumentException("parseParcel() fails");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the index of the MediaPlayer track which contains this subtitle data.
|
||||||
|
* @return an index in the array returned by {@link MediaPlayer#getTrackInfo()}.
|
||||||
|
*/
|
||||||
public int getTrackIndex() {
|
public int getTrackIndex() {
|
||||||
return mTrackIndex;
|
return mTrackIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the media time at which the subtitle should be displayed, expressed in microseconds.
|
||||||
|
* @return the display start time for the subtitle
|
||||||
|
*/
|
||||||
public long getStartTimeUs() {
|
public long getStartTimeUs() {
|
||||||
return mStartTimeUs;
|
return mStartTimeUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the duration in microsecond during which the subtitle should be displayed.
|
||||||
|
* @return the display duration for the subtitle
|
||||||
|
*/
|
||||||
public long getDurationUs() {
|
public long getDurationUs() {
|
||||||
return mDurationUs;
|
return mDurationUs;
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getData() {
|
/**
|
||||||
|
* Returns the encoded data for the subtitle content.
|
||||||
|
* Encoding format depends on the subtitle type, refer to
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/CEA-708">CEA 708</a>,
|
||||||
|
* <a href="https://en.wikipedia.org/wiki/EIA-608">CEA/EIA 608</a> and
|
||||||
|
* <a href="https://www.w3.org/TR/webvtt1/">WebVTT</a>, defined by the MIME type
|
||||||
|
* of the subtitle track.
|
||||||
|
* @return the encoded subtitle data
|
||||||
|
*/
|
||||||
|
public @NonNull byte[] getData() {
|
||||||
return mData;
|
return mData;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user