11ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang/* 21ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Copyright 2018 The Android Open Source Project 31ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 41ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Licensed under the Apache License, Version 2.0 (the "License"); 51ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * you may not use this file except in compliance with the License. 61ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * You may obtain a copy of the License at 71ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 81ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * http://www.apache.org/licenses/LICENSE-2.0 91ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Unless required by applicable law or agreed to in writing, software 111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * distributed under the License is distributed on an "AS IS" BASIS, 121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * See the License for the specific language governing permissions and 141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * limitations under the License. 151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangpackage androidx.media.widget; 181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.Context; 221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.pm.ActivityInfo; 231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.content.res.Resources; 241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.Bitmap; 251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.BitmapFactory; 261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.Point; 271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.drawable.BitmapDrawable; 281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.graphics.drawable.Drawable; 291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioAttributes; 301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioFocusRequest; 311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.AudioManager; 321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.MediaMetadataRetriever; 331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.PlaybackParams; 341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.media.SubtitleData; 351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.net.Uri; 361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.AsyncTask; 371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.Bundle; 381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.os.ResultReceiver; 391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.MediaMetadataCompat; 401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaControllerCompat; 411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaControllerCompat.PlaybackInfo; 421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.MediaSessionCompat; 431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.support.v4.media.session.PlaybackStateCompat; 441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.AttributeSet; 451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.DisplayMetrics; 461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.Log; 471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.util.Pair; 481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.LayoutInflater; 491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.MotionEvent; 501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.View; 511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.ViewGroup.LayoutParams; 521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.WindowManager; 531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.view.accessibility.AccessibilityManager; 541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.widget.ImageView; 551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport android.widget.TextView; 561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.NonNull; 581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.Nullable; 591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.RequiresApi; 601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.annotation.RestrictTo; 611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.AudioAttributesCompat; 621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.DataSourceDesc; 631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaItem2; 641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaMetadata2; 651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaPlayer2; 661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.MediaPlayer2.MediaPlayer2EventCallback; 671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.SessionToken2; 681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.ClosedCaptionRenderer; 691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.SubtitleController; 701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.subtitle.SubtitleTrack; 711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaControlIntent; 721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaItemStatus; 731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaRouteSelector; 741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.mediarouter.media.MediaRouter; 751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.palette.graphics.Palette; 761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.ArrayList; 781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.List; 791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.Map; 801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport java.util.concurrent.Executor; 811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang/** 831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Base implementation of VideoView2. 841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang@RequiresApi(28) // TODO correct minSdk API use incompatibilities and remove before release. 861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangclass VideoView2ImplBase implements VideoView2Impl, VideoViewInterface.SurfaceListener { 871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final String TAG = "VideoView2ImplBase"; 881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000; 901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_ERROR = -1; 921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_IDLE = 0; 931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_PREPARING = 1; 941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_PREPARED = 2; 951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_PLAYING = 3; 961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_PAUSED = 4; 971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int STATE_PLAYBACK_COMPLETED = 5; 981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int INVALID_TRACK_INDEX = -1; 1001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final float INVALID_SPEED = 0f; 1011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int SIZE_TYPE_EMBEDDED = 0; 1031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int SIZE_TYPE_FULL = 1; 1041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private static final int SIZE_TYPE_MINIMAL = 2; 1051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private AccessibilityManager mAccessibilityManager; 1071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private AudioManager mAudioManager; 1081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private AudioAttributesCompat mAudioAttributes; 1091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain 1101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean mAudioFocused = false; 1111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord; 1131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener; 1141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private VideoViewInterface mCurrentView; 1161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private VideoTextureView mTextureView; 1171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private VideoSurfaceView mSurfaceView; 1181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaPlayer2 mMediaPlayer; 1201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private DataSourceDesc mDsd; 1211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Uri mUri; 1221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Map<String, String> mHeaders; 1231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaControlView2 mMediaControlView; 1241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaSessionCompat mMediaSession; 1251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaControllerCompat mMediaController; 1261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaMetadata2 mMediaMetadata; 1271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaMetadataRetriever mRetriever; 1281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean mNeedUpdateMediaType; 1291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Bundle mMediaTypeData; 1301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private String mTitle; 1311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private WindowManager mManager; 1331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Resources mResources; 1341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private View mMusicView; 1351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private Drawable mMusicAlbumDrawable; 1361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private String mMusicTitleText; 1371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private String mMusicArtistText; 1381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean mIsMusicMediaType; 1391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mPrevWidth; 1401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mPrevHeight; 1411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mDominantColor; 1421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mSizeType; 1431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private PlaybackStateCompat.Builder mStateBuilder; 1451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private List<PlaybackStateCompat.CustomAction> mCustomActionList; 1461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mTargetState = STATE_IDLE; 1481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mCurrentState = STATE_IDLE; 1491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mCurrentBufferPercentage; 1501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private long mSeekWhenPrepared; // recording the seek position while preparing 1511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mVideoWidth; 1531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mVideoHeight; 1541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private ArrayList<Integer> mVideoTrackIndices; 1561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private ArrayList<Integer> mAudioTrackIndices; 1571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private ArrayList<Pair<Integer, SubtitleTrack>> mSubtitleTrackIndices; 1581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private SubtitleController mSubtitleController; 1591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // selected video/audio/subtitle track index as MediaPlayer returns 1611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mSelectedVideoTrackIndex; 1621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mSelectedAudioTrackIndex; 1631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mSelectedSubtitleTrackIndex; 1641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private SubtitleView mSubtitleView; 1661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean mSubtitleEnabled; 1671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private float mSpeed; 1691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private float mFallbackSpeed; // keep the original speed before 'pause' is called. 1701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private float mVolumeLevelFloat; 1711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int mVolumeLevel; 1721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private VideoView2 mInstance; 1731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private long mShowControllerIntervalMs; 1751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaRouter mMediaRouter; 1771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaRouteSelector mRouteSelector; 1781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private MediaRouter.RouteInfo mRoute; 1791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private RoutePlayer mRoutePlayer; 1801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 1811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() { 1821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 1831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) { 1841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { 1851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Stop local playback (if necessary) 1861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang resetPlayer(); 1871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoute = route; 1881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer = new RoutePlayer(mInstance.getContext(), route); 1891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() { 1901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 1911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onPlayerStateChanged(MediaItemStatus itemStatus) { 1921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackStateCompat.Builder psBuilder = new PlaybackStateCompat.Builder(); 1931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS); 1941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang long position = itemStatus.getContentPosition(); 1951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang switch (itemStatus.getPlaybackState()) { 1961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaItemStatus.PLAYBACK_STATE_PENDING: 1971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_NONE, position, 0); 1981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_IDLE; 1991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 2001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaItemStatus.PLAYBACK_STATE_PLAYING: 2011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_PLAYING, position, 1); 2021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PLAYING; 2031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 2041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaItemStatus.PLAYBACK_STATE_PAUSED: 2051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_PAUSED, position, 0); 2061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PAUSED; 2071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 2081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaItemStatus.PLAYBACK_STATE_BUFFERING: 2091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setState( 2101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackStateCompat.STATE_BUFFERING, position, 0); 2111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PAUSED; 2121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 2131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaItemStatus.PLAYBACK_STATE_FINISHED: 2141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_STOPPED, position, 0); 2151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PLAYBACK_COMPLETED; 2161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 2171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackStateCompat pbState = psBuilder.build(); 2201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setPlaybackState(pbState); 2211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.Builder mmBuilder = new MediaMetadataCompat.Builder(); 2231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mmBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 2241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang itemStatus.getContentDuration()); 2251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setMetadata(mmBuilder.build()); 2261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }); 2281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Start remote playback (if necessary) 2291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // TODO: b/77556429 2301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.openVideo(mUri); 2311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 2351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) { 2361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mRoute != null && mRoutePlayer != null) { 2371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.release(); 2381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer = null; 2391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mRoute == route) { 2411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoute = null; 2421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) { 2441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // TODO: Resume local playback (if necessary) 2451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // TODO: b/77556429 2461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang openVideo(mDsd); 2471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }; 2501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 2521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void initialize( 2531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang VideoView2 instance, Context context, 2541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Nullable AttributeSet attrs, int defStyleAttr) { 2551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance = instance; 2561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoWidth = 0; 2581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoHeight = 0; 2591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSpeed = 1.0f; 2601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mFallbackSpeed = mSpeed; 2611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX; 2621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS; 2631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAccessibilityManager = (AccessibilityManager) context.getSystemService( 2651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Context.ACCESSIBILITY_SERVICE); 2661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 2681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioAttributes = new AudioAttributesCompat.Builder() 2691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .setUsage(AudioAttributesCompat.USAGE_MEDIA) 2701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .setContentType(AudioAttributesCompat.CONTENT_TYPE_MOVIE).build(); 2711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.setFocusable(true); 2731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.setFocusableInTouchMode(true); 2741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.requestFocus(); 2751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView = new VideoTextureView(context); 2771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView = new VideoSurfaceView(context); 2781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 2791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang LayoutParams.MATCH_PARENT); 2801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setLayoutParams(params); 2811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setLayoutParams(params); 2821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setSurfaceListener(this); 2831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setSurfaceListener(this); 2841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.addView(mTextureView); 2861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.addView(mSurfaceView); 2871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleView = new SubtitleView(context); 2891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleView.setLayoutParams(params); 2901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleView.setBackgroundColor(0); 2911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.addView(mSubtitleView); 2921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 2931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue( 2941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "http://schemas.android.com/apk/res/android", 2951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "enableControlView", true); 2961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (enableControlView) { 2971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView = new MediaControlView2(context); 2981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 2991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleEnabled = (attrs == null) || attrs.getAttributeBooleanValue( 3011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "http://schemas.android.com/apk/res/android", 3021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "enableSubtitle", false); 3031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Choose surface view by default 3051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW 3061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang : attrs.getAttributeIntValue( 3071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "http://schemas.android.com/apk/res/android", 3081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW); 3091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) { 3101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "viewType attribute is surfaceView."); 3111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setVisibility(View.GONE); 3121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setVisibility(View.VISIBLE); 3131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentView = mSurfaceView; 3141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) { 3151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "viewType attribute is textureView."); 3161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setVisibility(View.VISIBLE); 3171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setVisibility(View.GONE); 3181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentView = mTextureView; 3191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder(); 3221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 3231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO); 3241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO); 3251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRouteSelector = builder.build(); 3261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2 3301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * instance if any. 3311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 3321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param mediaControlView a media control view2 instance. 3331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2. 3341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 3351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 3361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) { 3371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView = mediaControlView; 3381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mShowControllerIntervalMs = intervalMs; 3391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setRouteSelector(mRouteSelector); 3401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mInstance.isAttachedToWindow()) { 3421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang attachMediaControlView(); 3431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by 3481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link #setMediaControlView2} method. 3491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 3501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 3511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public MediaControlView2 getMediaControlView2() { 3521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mMediaControlView; 3531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance 3571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * if any. 3581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 3591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param metadata a MediaMetadata2 instance. 3601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 3611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 3621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 3631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 3641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setMediaMetadata(MediaMetadata2 metadata) { 3651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang //mProvider.setMediaMetadata_impl(metadata); 3661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by 3701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * default or by {@link #setMediaMetadata} method. 3711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 3721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 3731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 3741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 3751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public MediaMetadata2 getMediaMetadata() { 3761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mMediaMetadata; 3771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns MediaController instance which is connected with MediaSession that VideoView2 is 3811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * using. This method should be called when VideoView2 is attached to window, or it throws 3821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * IllegalStateException, since internal MediaSession instance is not available until 3831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * this view is attached to window. Please check {@link View#isAttachedToWindow} 3841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * before calling this method. 3851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 3861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @throws IllegalStateException if interal MediaSession is not created yet. 3871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide TODO: remove 3881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 3891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 3901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 3911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public MediaControllerCompat getMediaController() { 3921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaSession == null) { 3931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang throw new IllegalStateException("MediaSession instance is not available."); 3941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mMediaController; 3961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 3971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 3981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 3991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns {@link SessionToken2} so that developers create their own 4001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link androidx.media.MediaController2} instance. This method should be called when 4011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * VideoView2 is attached to window, or it throws IllegalStateException. 4021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 4031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @throws IllegalStateException if interal MediaSession is not created yet. 4041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 4051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 4071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public SessionToken2 getMediaSessionToken() { 4091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang //return mProvider.getMediaSessionToken_impl(); 4101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return null; 4111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Shows or hides closed caption or subtitles if there is any. 4151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * The first subtitle track will be chosen if there multiple subtitle tracks exist. 4161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Default behavior of VideoView2 is not showing subtitle. 4171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param enable shows closed caption or subtitles if this value is true, or hides. 4181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setSubtitleEnabled(boolean enable) { 4211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // No-op on API < 28 4221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns true if showing subtitle feature is enabled or returns false. 4261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Although there is no subtitle track or closed caption, it can return true, if the feature 4271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * has been enabled by {@link #setSubtitleEnabled}. 4281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public boolean isSubtitleEnabled() { 4311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Not supported on API < 28 4321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return false; 4331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets playback speed. 4371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 4381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than 4391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the 4401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * maximum speed that internal engine supports, system will determine best handling or it will 4411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * be reset to the normal speed 1.0f. 4421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param speed the playback speed. It should be positive. 4431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setSpeed(float speed) { 4461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (speed <= 0.0f) { 4471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.e(TAG, "Unsupported speed (" + speed + ") is ignored."); 4481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 4491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSpeed = speed; 4511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isPlaying()) { 4521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang applySpeed(); 4531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 4551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns playback speed. 4591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 4601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * It returns the same value that has been set by {@link #setSpeed}, if it was available value. 4611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * If {@link #setSpeed} has not been called before, then the normal speed 1.0f will be returned. 4621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public float getSpeed() { 4651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mSpeed; 4661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets which type of audio focus will be requested during the playback, or configures playback 4701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * to not request audio focus. Valid values for focus requests are 4711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT}, 4721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and 4731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use 4741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be 4751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * requested when playback starts. You can for instance use this when playing a silent animation 4761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * through this class, and you don't want to affect other audio applications playing in the 4771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * background. 4781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 4791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param focusGain the type of audio focus gain that will be requested, or 4801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during 4811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * playback. 4821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 4831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 4841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setAudioFocusRequest(int focusGain) { 4851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (focusGain != AudioManager.AUDIOFOCUS_NONE 4861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN 4871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT 4881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 4891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) { 4901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang throw new IllegalArgumentException("Illegal audio focus type " + focusGain); 4911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocusType = focusGain; 4931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 4941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 4951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 4961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets the {@link AudioAttributesCompat} to be used during the playback of the video. 4971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 4981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param attributes non-null <code>AudioAttributesCompat</code>. 4991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) { 5021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (attributes == null) { 5031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang throw new IllegalArgumentException("Illegal null AudioAttributes"); 5041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioAttributes = attributes; 5061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets video path. 5101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param path the path of the video. 5121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 5141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 5161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setVideoPath(String path) { 5181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang setVideoUri(Uri.parse(path)); 5191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets video URI. 5231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param uri the URI of the video. 5251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 5271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 5291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setVideoUri(Uri uri) { 5311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang setVideoUri(uri, null); 5321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets video URI using specific headers. 5361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param uri the URI of the video. 5381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param headers the headers for the URI request. 5391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Note that the cross domain redirection is allowed by default, but that can be 5401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * changed with key/value pairs through the headers parameter with 5411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value 5421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * to disallow or allow cross domain redirection. 5431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) { 5461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang DataSourceDesc.Builder builder = new DataSourceDesc.Builder(); 5471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.setDataSource(mInstance.getContext(), uri, headers, null); 5481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang setDataSource(builder.build()); 5491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media 5531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * object to VideoView2 is {@link #setDataSource}. 5541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param mediaItem the MediaItem2 to play 5551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @see #setDataSource 5561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 5581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 5601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setMediaItem(@NonNull MediaItem2 mediaItem) { 5621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets {@link DataSourceDesc} object to render using VideoView2. 5661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param dataSource the {@link DataSourceDesc} object to play. 5671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @see #setMediaItem 5681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 5691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 5711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setDataSource(@NonNull DataSourceDesc dataSource) { 5731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mDsd = dataSource; 5741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSeekWhenPrepared = 0; 5751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang openVideo(dataSource); 5761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 5781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 5791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Selects which view will be used to render video between SurfacView and TextureView. 5801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 5811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param viewType the view type to render video 5821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * <ul> 5831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW} 5841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW} 5851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * </ul> 5861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 5871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 5881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setViewType(@VideoView2.ViewType int viewType) { 5891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (viewType == mCurrentView.getViewType()) { 5901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 5911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 5921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang VideoViewInterface targetView; 5931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) { 5941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "switching to TextureView"); 5951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang targetView = mTextureView; 5961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) { 5971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "switching to SurfaceView"); 5981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang targetView = mSurfaceView; 5991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 6001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang throw new IllegalArgumentException("Unknown view type: " + viewType); 6011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang ((View) targetView).setVisibility(View.VISIBLE); 6031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang targetView.takeOver(mCurrentView); 6041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.requestLayout(); 6051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 6081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Returns view type. 6091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 6101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @return view type. See {@see setViewType}. 6111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 6121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @VideoView2.ViewType 6131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public int getViewType() { 6151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mCurrentView.getViewType(); 6161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 6191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}. 6201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * 6211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of 6221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw 6231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * buttons in {@link MediaControlView2}. 6241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param executor executor to run callbacks on. 6251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param listener A listener to be called when a custom button is clicked. 6261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 6271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 6281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 6291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList, 6311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Executor executor, VideoView2.OnCustomActionListener listener) { 6321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCustomActionList = actionList; 6331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCustomActionListenerRecord = new Pair<>(executor, listener); 6341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Create a new playback builder in order to clear existing the custom actions. 6361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder = null; 6371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 6381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 6411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Registers a callback to be invoked when a view type change is done. 6421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * {@see #setViewType(int)} 6431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param l The callback that will be run 6441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 6451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 6461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 6471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l) { 6491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mViewTypeChangedListener = l; 6501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onAttachedToWindowImpl() { 6541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Create MediaSession 6551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession = new MediaSessionCompat(mInstance.getContext(), "VideoView2MediaSession"); 6561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setCallback(new MediaSessionCallback()); 6571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setActive(true); 6581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController = mMediaSession.getController(); 6591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang attachMediaControlView(); 6601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mCurrentState == STATE_PREPARED) { 6611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractTracks(); 6621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractMetadata(); 6631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractAudioMetadata(); 6641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mNeedUpdateMediaType) { 6651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.sendSessionEvent( 6661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, 6671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaTypeData); 6681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mNeedUpdateMediaType = false; 6691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaRouter = MediaRouter.getInstance(mInstance.getContext()); 6731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaRouter.setMediaSessionCompat(mMediaSession); 6741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaRouter.addCallback(mRouteSelector, mRouterCallback, 6751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); 6761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onDetachedFromWindowImpl() { 6801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.release(); 6811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession = null; 6821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController = null; 6831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onTouchEventImpl(MotionEvent ev) { 6871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 6881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState 6891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState); 6901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) { 6921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) { 6931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang toggleMediaControlViewVisibility(); 6941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 6971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 6981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 6991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onTrackballEventImpl(MotionEvent ev) { 7001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) { 7011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (!mIsMusicMediaType || mSizeType != SIZE_TYPE_FULL) { 7021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang toggleMediaControlViewVisibility(); 7031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 7081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec) { 7091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mIsMusicMediaType) { 7101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int currWidth = mInstance.getMeasuredWidth(); 7111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int currHeight = mInstance.getMeasuredHeight(); 7121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mPrevWidth != currWidth || mPrevHeight != currHeight) { 7131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Point screenSize = new Point(); 7141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mManager.getDefaultDisplay().getSize(screenSize); 7151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int screenWidth = screenSize.x; 7161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int screenHeight = screenSize.y; 7171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (currWidth == screenWidth && currHeight == screenHeight) { 7191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int orientation = retrieveOrientation(); 7201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { 7211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang inflateMusicView(R.layout.full_landscape_music); 7221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 7231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang inflateMusicView(R.layout.full_portrait_music); 7241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSizeType != SIZE_TYPE_FULL) { 7271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSizeType = SIZE_TYPE_FULL; 7281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Remove existing mFadeOut callback 7291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 7301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setVisibility(View.VISIBLE); 7311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 7331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSizeType != SIZE_TYPE_EMBEDDED) { 7341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSizeType = SIZE_TYPE_EMBEDDED; 7351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang inflateMusicView(R.layout.embedded_music); 7361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Add new mFadeOut callback 7371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs); 7381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mPrevWidth = currWidth; 7411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mPrevHeight = currHeight; 7421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /////////////////////////////////////////////////// 7471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Implements VideoViewInterface.SurfaceListener 7481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /////////////////////////////////////////////////// 7491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 7511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 7521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 7531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 7541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 7551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSurfaceCreated(View view, int width, int height) { 7561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 7571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState 7581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height 7591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", " + view.toString()); 7601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (needToStart()) { 7621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().play(); 7631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 7671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 7681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 7691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 7701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 7711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSurfaceDestroyed(View view) { 7721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 7731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState 7741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState + ", " + view.toString()); 7751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 7791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 7801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 7811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 7821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 7831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSurfaceChanged(View view, int width, int height) { 7841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 7851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height 7861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", " + view.toString()); 7871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 7901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /** 7911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @hide 7921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 7931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 7941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @RestrictTo(LIBRARY_GROUP) 7951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSurfaceTakeOverDone(VideoViewInterface view) { 7961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 7971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view); 7981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 7991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentView = view; 8001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mViewTypeChangedListener != null) { 8011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType()); 8021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (needToStart()) { 8041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().play(); 8051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /////////////////////////////////////////////////// 8091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Protected or private methods 8101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /////////////////////////////////////////////////// 8111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void attachMediaControlView() { 8131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Get MediaController from MediaSession and set it inside MediaControlView 8141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setController(mMediaSession.getController()); 8151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang LayoutParams params = 8171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 8181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.addView(mMediaControlView, params); 8191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean isInPlaybackState() { 8221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return (mMediaPlayer != null || mRoutePlayer != null) 8231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mCurrentState != STATE_ERROR 8241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mCurrentState != STATE_IDLE 8251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mCurrentState != STATE_PREPARING; 8261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean needToStart() { 8291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return (mMediaPlayer != null || mRoutePlayer != null) 8301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && isAudioGranted() 8311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && isWaitingPlayback(); 8321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean isPlaying() { 8351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mMediaPlayer != null 8361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mMediaPlayer.getMediaPlayer2State() == MediaPlayer2.MEDIAPLAYER2_STATE_PLAYING; 8371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean isWaitingPlayback() { 8401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING; 8411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean isAudioGranted() { 8441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE; 8451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private AudioManager.OnAudioFocusChangeListener mAudioFocusListener = 8481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang new AudioManager.OnAudioFocusChangeListener() { 8491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 8501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onAudioFocusChange(int focusChange) { 8511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang switch (focusChange) { 8521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case AudioManager.AUDIOFOCUS_GAIN: 8531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocused = true; 8541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (needToStart()) { 8551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().play(); 8561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 8581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case AudioManager.AUDIOFOCUS_LOSS: 8591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 8601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 8611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocused = false; 8621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isInPlaybackState() && isPlaying()) { 8631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().pause(); 8641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 8651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_PAUSED; 8661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }; 8701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @SuppressWarnings("deprecation") 8721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void requestAudioFocus(int focusType) { 8731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int result; 8741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (android.os.Build.VERSION.SDK_INT >= 26) { 8751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang AudioFocusRequest focusRequest; 8761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang focusRequest = new AudioFocusRequest.Builder(focusType) 8771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .setAudioAttributes((AudioAttributes) mAudioAttributes.unwrap()) 8781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .setOnAudioFocusChangeListener(mAudioFocusListener) 8791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .build(); 8801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang result = mAudioManager.requestAudioFocus(focusRequest); 8811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 8821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang result = mAudioManager.requestAudioFocus(mAudioFocusListener, 8831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang AudioManager.STREAM_MUSIC, 8841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang focusType); 8851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { 8871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocused = false; 8881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 8891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocused = true; 8901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { 8911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioFocused = false; 8921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 8941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 8951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Creates a MediaPlayer instance and prepare playback. 8961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void openVideo(DataSourceDesc dsd) { 8971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Uri uri = dsd.getUri(); 8981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Map<String, String> headers = dsd.getUriHeaders(); 8991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang resetPlayer(); 9001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 9011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // TODO: b/77556429 9021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.openVideo(uri); 9031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 9041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang try { 9071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "openVideo(): creating new MediaPlayer instance."); 9081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer = MediaPlayer2.create(); 9091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setMediaPlayer(mMediaPlayer); 9101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setMediaPlayer(mMediaPlayer); 9111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer); 9121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang final Context context = mInstance.getContext(); 9141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleController = new SubtitleController(context); 9151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleController.registerRenderer(new ClosedCaptionRenderer(context)); 9161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleController.setAnchor((SubtitleController.Anchor) mSubtitleView); 9171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Executor executor = new Executor() { 9181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 9191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void execute(Runnable runnable) { 9201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang runnable.run(); 9211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }; 9231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.setMediaPlayer2EventCallback(executor, mMediaPlayer2Callback); 9241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentBufferPercentage = -1; 9261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.setDataSource(dsd); 9271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.setAudioAttributes(mAudioAttributes); 9281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // we don't set the target state here either, but preserve the 9291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // target state that was there before. 9301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PREPARING; 9311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.prepare(); 9321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Save file name as title since the file may not have a title Metadata. 9341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTitle = uri.getPath(); 9351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang String scheme = uri.getScheme(); 9361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (scheme != null && scheme.equals("file")) { 9371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTitle = uri.getLastPathSegment(); 9381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRetriever = new MediaMetadataRetriever(); 9391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRetriever.setDataSource(context, uri); 9401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 9431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState 9441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState); 9451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } catch (IllegalArgumentException ex) { 9471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.w(TAG, "Unable to open content: " + uri, ex); 9481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_ERROR; 9491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_ERROR; 9501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer2Callback.onError(mMediaPlayer, dsd, 9511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2.MEDIA_ERROR_UNKNOWN, MediaPlayer2.MEDIA_ERROR_IO); 9521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang /* 9561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Reset the media player in any state 9571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang */ 9581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @SuppressWarnings("deprecation") 9591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void resetPlayer() { 9601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaPlayer != null) { 9611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang final MediaPlayer2 player = mMediaPlayer; 9621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang new AsyncTask<MediaPlayer2, Void, Void>() { 9631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 9641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang protected Void doInBackground(MediaPlayer2... players) { 9651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // TODO: Fix NPE while MediaPlayer2.close() 9661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang //players[0].close(); 9671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return null; 9681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }.executeOnExecutor(AsyncTask.SERIAL_EXECUTOR, player); 9701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer = null; 9711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTextureView.setMediaPlayer(null); 9721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSurfaceView.setMediaPlayer(null); 9731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_IDLE; 9741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_IDLE; 9751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) { 9761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioManager.abandonAudioFocus(null); 9771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoWidth = 0; 9801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoHeight = 0; 9811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void updatePlaybackState() { 9841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mStateBuilder == null) { 9851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang long playbackActions = PlaybackStateCompat.ACTION_PLAY 9861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang | PlaybackStateCompat.ACTION_PAUSE 9871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD 9881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang | PlaybackStateCompat.ACTION_SEEK_TO; 9891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder = new PlaybackStateCompat.Builder(); 9901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder.setActions(playbackActions); 9911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 9921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mCustomActionList != null) { 9931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang for (PlaybackStateCompat.CustomAction action : mCustomActionList) { 9941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder.addCustomAction(action); 9951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 9981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder.setState(getCorrespondingPlaybackState(), 9991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.getCurrentPosition(), mSpeed); 10001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mCurrentState != STATE_ERROR 10011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mCurrentState != STATE_IDLE 10021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && mCurrentState != STATE_PREPARING) { 10031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mCurrentBufferPercentage == -1) { 10041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder.setBufferedPosition(-1); 10051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 10061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mStateBuilder.setBufferedPosition( 10071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration())); 10081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Set PlaybackState for MediaSession 10121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaSession != null) { 10131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackStateCompat state = mStateBuilder.build(); 10141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setPlaybackState(state); 10151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int getCorrespondingPlaybackState() { 10191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang switch (mCurrentState) { 10201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_ERROR: 10211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_ERROR; 10221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_IDLE: 10231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_NONE; 10241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_PREPARING: 10251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_CONNECTING; 10261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_PREPARED: 10271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_PAUSED; 10281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_PLAYING: 10291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_PLAYING; 10301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_PAUSED: 10311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_PAUSED; 10321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case STATE_PLAYBACK_COMPLETED: 10331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return PlaybackStateCompat.STATE_STOPPED; 10341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang default: 10351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return -1; 10361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private final Runnable mFadeOut = new Runnable() { 10401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 10411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void run() { 10421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mCurrentState == STATE_PLAYING) { 10431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setVisibility(View.GONE); 10441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }; 10471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void showController() { 10491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaControlView == null || !isInPlaybackState() 10501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang || (mIsMusicMediaType && mSizeType == SIZE_TYPE_FULL)) { 10511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 10521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 10541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setVisibility(View.VISIBLE); 10551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mShowControllerIntervalMs != 0 10561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && !mAccessibilityManager.isTouchExplorationEnabled()) { 10571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs); 10581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void toggleMediaControlViewVisibility() { 10621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaControlView.getVisibility() == View.VISIBLE) { 10631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 10641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setVisibility(View.GONE); 10651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 10661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 10671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void applySpeed() { 10711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (android.os.Build.VERSION.SDK_INT < 23) { 10721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 10731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults(); 10751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSpeed != params.getSpeed()) { 10761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang try { 10771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang params.setSpeed(mSpeed); 10781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.setPlaybackParams(params); 10791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mFallbackSpeed = mSpeed; 10801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } catch (IllegalArgumentException e) { 10811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.e(TAG, "PlaybackParams has unsupported value: " + e); 10821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed(); 10831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (fallbackSpeed > 0.0f) { 10841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mFallbackSpeed = fallbackSpeed; 10851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSpeed = mFallbackSpeed; 10871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 10911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private boolean isRemotePlayback() { 10921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaController == null) { 10931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return false; 10941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo(); 10961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return playbackInfo != null 10971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; 10981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 10991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void selectOrDeselectSubtitle(boolean select) { 11011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (!isInPlaybackState()) { 11021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 11031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (select) { 11051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSubtitleTrackIndices.size() > 0) { 11061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedSubtitleTrackIndex = mSubtitleTrackIndices.get(0).first; 11071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleController.selectTrack(mSubtitleTrackIndices.get(0).second); 11081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.selectTrack(mSelectedSubtitleTrackIndex); 11091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleView.setVisibility(View.VISIBLE); 11101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 11121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSelectedSubtitleTrackIndex != INVALID_TRACK_INDEX) { 11131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.deselectTrack(mSelectedSubtitleTrackIndex); 11141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedSubtitleTrackIndex = INVALID_TRACK_INDEX; 11151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleView.setVisibility(View.GONE); 11161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void extractTracks() { 11211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang List<MediaPlayer2.TrackInfo> trackInfos = mMediaPlayer.getTrackInfo(); 11221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoTrackIndices = new ArrayList<>(); 11231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioTrackIndices = new ArrayList<>(); 11241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleTrackIndices = new ArrayList<>(); 11251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleController.reset(); 11261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang for (int i = 0; i < trackInfos.size(); ++i) { 11271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int trackType = trackInfos.get(i).getTrackType(); 11281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) { 11291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoTrackIndices.add(i); 11301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) { 11311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioTrackIndices.add(i); 11321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (trackType == MediaPlayer2.TrackInfo.MEDIA_TRACK_TYPE_SUBTITLE) { 11331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang SubtitleTrack track = mSubtitleController.addTrack(trackInfos.get(i).getFormat()); 11341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (track != null) { 11351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSubtitleTrackIndices.add(new Pair<>(i, track)); 11361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Select first tracks as default 11401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mVideoTrackIndices.size() > 0) { 11411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedVideoTrackIndex = 0; 11421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mAudioTrackIndices.size() > 0) { 11441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedAudioTrackIndex = 0; 11451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mVideoTrackIndices.size() == 0 && mAudioTrackIndices.size() > 0) { 11471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mIsMusicMediaType = true; 11481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Bundle data = new Bundle(); 11511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang data.putInt(MediaControlView2.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size()); 11521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang data.putInt(MediaControlView2.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size()); 11531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang data.putInt(MediaControlView2.KEY_SUBTITLE_TRACK_COUNT, mSubtitleTrackIndices.size()); 11541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mSubtitleTrackIndices.size() > 0) { 11551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang selectOrDeselectSubtitle(mSubtitleEnabled); 11561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.sendSessionEvent(MediaControlView2.EVENT_UPDATE_TRACK_STATUS, data); 11581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void extractMetadata() { 11611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mRetriever == null) { 11621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 11631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Get and set duration and title values as MediaMetadata for MediaControlView2 11651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 11661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE); 11671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (title != null) { 11681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTitle = title; 11691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle); 11711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putLong( 11721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration()); 11731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaSession != null) { 11751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setMetadata(builder.build()); 11761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @SuppressWarnings("deprecation") 11801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void extractAudioMetadata() { 11811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mRetriever == null || !mIsMusicMediaType) { 11821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 11831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 11841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mResources = mInstance.getResources(); 11861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mManager = (WindowManager) mInstance.getContext().getApplicationContext() 11871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .getSystemService(Context.WINDOW_SERVICE); 11881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang byte[] album = mRetriever.getEmbeddedPicture(); 11901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (album != null) { 11911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length); 11921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicAlbumDrawable = new BitmapDrawable(bitmap); 11931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 11941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Palette.Builder builder = Palette.from(bitmap); 11951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.generate(new Palette.PaletteAsyncListener() { 11961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 11971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onGenerated(Palette palette) { 11981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mDominantColor = palette.getDominantColor(0); 11991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMusicView != null) { 12001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicView.setBackgroundColor(mDominantColor); 12011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }); 12041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 12051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image); 12061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE); 12091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (title != null) { 12101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicTitleText = title; 12111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 12121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text); 12131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); 12161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (artist != null) { 12171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicArtistText = artist; 12181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 12191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text); 12201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Send title and artist string to MediaControlView2 12231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 12241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText); 12251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText); 12261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setMetadata(builder.build()); 12271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Display Embedded mode as default 12291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.removeView(mSurfaceView); 12301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.removeView(mTextureView); 12311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang inflateMusicView(R.layout.embedded_music); 12321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private int retrieveOrientation() { 12351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang DisplayMetrics dm = Resources.getSystem().getDisplayMetrics(); 12361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int width = dm.widthPixels; 12371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int height = dm.heightPixels; 12381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return (height > width) 12401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 12411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 12421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void inflateMusicView(int layoutId) { 12451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.removeView(mMusicView); 12461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang LayoutInflater inflater = (LayoutInflater) mInstance.getContext() 12481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 12491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang View v = inflater.inflate(layoutId, null); 12501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang v.setBackgroundColor(mDominantColor); 12511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang ImageView albumView = v.findViewById(R.id.album); 12531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (albumView != null) { 12541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang albumView.setImageDrawable(mMusicAlbumDrawable); 12551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang TextView titleView = v.findViewById(R.id.title); 12581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (titleView != null) { 12591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang titleView.setText(mMusicTitleText); 12601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang TextView artistView = v.findViewById(R.id.artist); 12631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (artistView != null) { 12641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang artistView.setText(mMusicArtistText); 12651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMusicView = v; 12681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.addView(mMusicView, 0); 12691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2EventCallback mMediaPlayer2Callback = 12721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang new MediaPlayer2EventCallback() { 12731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 12741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onVideoSizeChanged( 12751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2 mp, DataSourceDesc dsd, int width, int height) { 12761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 12771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height); 12781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoWidth = mp.getVideoWidth(); 12801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoHeight = mp.getVideoHeight(); 12811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 12821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/" 12831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + mVideoHeight); 12841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mVideoWidth != 0 && mVideoHeight != 0) { 12861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.requestLayout(); 12871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 12891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 12901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 12911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onInfo( 12921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2 mp, DataSourceDesc dsd, int what, int extra) { 12931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (what == MediaPlayer2.MEDIA_INFO_METADATA_UPDATE) { 12941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractTracks(); 12951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (what == MediaPlayer2.MEDIA_INFO_PREPARED) { 12961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang this.onPrepared(mp, dsd); 12971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (what == MediaPlayer2.MEDIA_INFO_PLAYBACK_COMPLETE) { 12981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang this.onCompletion(mp, dsd); 12991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (what == MediaPlayer2.MEDIA_INFO_BUFFERING_UPDATE) { 13001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang this.onBufferingUpdate(mp, dsd, extra); 13011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 13051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onError( 13061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2 mp, DataSourceDesc dsd, int frameworkErr, int implErr) { 13071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 13081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "Error: " + frameworkErr + "," + implErr); 13091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_ERROR; 13111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_ERROR; 13121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 13131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaControlView != null) { 13151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setVisibility(View.GONE); 13161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 13201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onCallCompleted( 13211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaPlayer2 mp, DataSourceDesc dsd, int what, int status) { 13221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (what == MediaPlayer2.CALL_COMPLETED_SEEK_TO) { 13231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 13241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 13281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSubtitleData(MediaPlayer2 mp, DataSourceDesc dsd, SubtitleData data) { 13291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 13301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex() 13311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", getCurrentPosition: " + mp.getCurrentPosition() 13321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", getStartTimeUs(): " + data.getStartTimeUs() 13331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", diff: " 13341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + (data.getStartTimeUs() / 1000 - mp.getCurrentPosition()) 13351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + "ms, getDurationUs(): " + data.getDurationUs()); 13361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang final int index = data.getTrackIndex(); 13391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (index != mSelectedSubtitleTrackIndex) { 13401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onSubtitleData(): getTrackIndex: " + data.getTrackIndex() 13411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", selected track index: " + mSelectedSubtitleTrackIndex); 13421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang return; 13431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang for (Pair<Integer, SubtitleTrack> p : mSubtitleTrackIndices) { 13451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (p.first == index) { 13461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang SubtitleTrack track = p.second; 13471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang track.onData(data); 13481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void onPrepared(MediaPlayer2 mp, DataSourceDesc dsd) { 13531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 13541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState 13551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState); 13561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PREPARED; 13581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Create and set playback state for MediaControlView2 13591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 13601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaSession != null) { 13621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractTracks(); 13631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractMetadata(); 13641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang extractAudioMetadata(); 13651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaControlView != null) { 13681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaControlView.setEnabled(true); 13691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int videoWidth = mp.getVideoWidth(); 13711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int videoHeight = mp.getVideoHeight(); 13721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // mSeekWhenPrepared may be changed after seekTo() call 13741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang long seekToPosition = mSeekWhenPrepared; 13751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (seekToPosition != 0) { 13761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().seekTo(seekToPosition); 13771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (videoWidth != 0 && videoHeight != 0) { 13801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) { 13811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoWidth = videoWidth; 13821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVideoHeight = videoHeight; 13831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.requestLayout(); 13841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (needToStart()) { 13871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().play(); 13881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 13901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 13911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // We don't know the video size yet, but should start anyway. 13921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // The video size might be reported to us later. 13931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (needToStart()) { 13941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaController.getTransportControls().play(); 13951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 13971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang // Get and set duration and title values as MediaMetadata for MediaControlView2 13981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 13991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle); 14011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang builder.putLong( 14021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration()); 14031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mMediaSession != null) { 14051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.setMetadata(builder.build()); 14061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mNeedUpdateMediaType) { 14081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaSession.sendSessionEvent( 14091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, 14101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaTypeData); 14111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mNeedUpdateMediaType = false; 14121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @SuppressWarnings("deprecation") 14171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void onCompletion(MediaPlayer2 mp, DataSourceDesc dsd) { 14181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PLAYBACK_COMPLETED; 14191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_PLAYBACK_COMPLETED; 14201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 14211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) { 14221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioManager.abandonAudioFocus(null); 14231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private void onBufferingUpdate(MediaPlayer2 mp, DataSourceDesc dsd, int percent) { 14271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentBufferPercentage = percent; 14281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 14291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }; 14311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang private class MediaSessionCallback extends MediaSessionCompat.Callback { 14331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 14341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onCommand(String command, Bundle args, ResultReceiver receiver) { 14351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 14361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.onCommand(command, args, receiver); 14371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 14381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang switch (command) { 14391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_SHOW_SUBTITLE: 14401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int subtitleIndex = args.getInt( 14411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaControlView2.KEY_SELECTED_SUBTITLE_INDEX, 14421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang INVALID_TRACK_INDEX); 14431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (subtitleIndex != INVALID_TRACK_INDEX) { 14441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int subtitleTrackIndex = mSubtitleTrackIndices.get(subtitleIndex).first; 14451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (subtitleTrackIndex != mSelectedSubtitleTrackIndex) { 14461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedSubtitleTrackIndex = subtitleTrackIndex; 14471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.setSubtitleEnabled(true); 14481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_HIDE_SUBTITLE: 14521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mInstance.setSubtitleEnabled(false); 14531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK: 14551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX, 14561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang INVALID_TRACK_INDEX); 14571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (audioIndex != INVALID_TRACK_INDEX) { 14581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang int audioTrackIndex = mAudioTrackIndices.get(audioIndex); 14591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (audioTrackIndex != mSelectedAudioTrackIndex) { 14601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSelectedAudioTrackIndex = audioTrackIndex; 14611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.selectTrack(mSelectedAudioTrackIndex); 14621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED: 14661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang float speed = args.getFloat( 14671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED); 14681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (speed != INVALID_SPEED && speed != mSpeed) { 14691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang setSpeed(speed); 14701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSpeed = speed; 14711ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14721ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14731ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_MUTE: 14741ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 14751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0); 14761ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang case MediaControlView2.COMMAND_UNMUTE: 14781ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0); 14791ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang break; 14801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14811ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 14831ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14851ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 14861ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onCustomAction(final String action, final Bundle extras) { 14871ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCustomActionListenerRecord.first.execute(new Runnable() { 14881ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 14891ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void run() { 14901ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCustomActionListenerRecord.second.onCustomAction(action, extras); 14911ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14921ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang }); 14931ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 14941ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 14951ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 14961ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 14971ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onPlay() { 14981ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (!isAudioGranted()) { 14991ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang requestAudioFocus(mAudioFocusType); 15001ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15011ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 15021ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || mIsMusicMediaType) { 15031ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 15041ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.onPlay(); 15051ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 15061ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang applySpeed(); 15071ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.play(); 15081ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PLAYING; 15091ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 15101ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15111ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PLAYING; 15121ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15131ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_PLAYING; 15141ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 15151ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState 15161ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState); 15171ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15181ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 15191ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15201ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 15211ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 15221ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onPause() { 15231ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isInPlaybackState()) { 15241ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 15251ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.onPlay(); 15261ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PAUSED; 15271ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else if (isPlaying()) { 15281ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.pause(); 15291ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mCurrentState = STATE_PAUSED; 15301ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang updatePlaybackState(); 15311ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15321ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15331ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mTargetState = STATE_PAUSED; 15341ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (DEBUG) { 15351ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState 15361ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang + ", mTargetState=" + mTargetState); 15371ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15381ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 15391ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15401ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 15411ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 15421ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onSeekTo(long pos) { 15431ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isInPlaybackState()) { 15441ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 15451ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.onPlay(); 15461ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 15471ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (android.os.Build.VERSION.SDK_INT < 26) { 15481ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.seekTo((int) pos); 15491ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 15501ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mMediaPlayer.seekTo(pos, MediaPlayer2.SEEK_PREVIOUS_SYNC); 15511ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15521ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSeekWhenPrepared = 0; 15531ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15541ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 15551ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mSeekWhenPrepared = pos; 15561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 15581ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15591ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang 15601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang @Override 15611ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void onStop() { 15621ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang if (isRemotePlayback()) { 15631ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mRoutePlayer.onPlay(); 15641ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } else { 15651ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang resetPlayer(); 15661ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15671ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang showController(); 15681ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15691ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang } 15701ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang} 1571