147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang/* 247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Copyright 2018 The Android Open Source Project 347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Licensed under the Apache License, Version 2.0 (the "License"); 547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * you may not use this file except in compliance with the License. 647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * You may obtain a copy of the License at 747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * http://www.apache.org/licenses/LICENSE-2.0 947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 1047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Unless required by applicable law or agreed to in writing, software 1147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * distributed under the License is distributed on an "AS IS" BASIS, 1247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * See the License for the specific language governing permissions and 1447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * limitations under the License. 1547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 1647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 1747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangpackage androidx.media.widget; 1847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 1947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 2047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 2147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.content.Context; 2247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.content.pm.ActivityInfo; 2347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.content.res.Resources; 2447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.graphics.Bitmap; 2547740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.graphics.BitmapFactory; 2647740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.graphics.Point; 2747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.graphics.drawable.BitmapDrawable; 2847740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.graphics.drawable.Drawable; 2947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.AudioAttributes; 3047740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.AudioFocusRequest; 3147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.AudioManager; 3247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.MediaMetadataRetriever; 3347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.MediaPlayer; 3447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.media.PlaybackParams; 3547740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.net.Uri; 3647740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.os.Bundle; 3747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.os.ResultReceiver; 3847740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.support.v4.media.MediaMetadataCompat; 3947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.support.v4.media.session.MediaControllerCompat; 4047740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.support.v4.media.session.MediaControllerCompat.PlaybackInfo; 4147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.support.v4.media.session.MediaSessionCompat; 4247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.support.v4.media.session.PlaybackStateCompat; 4347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.util.AttributeSet; 4447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.util.DisplayMetrics; 4547740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.util.Log; 4647740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.util.Pair; 4747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.LayoutInflater; 4847740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.MotionEvent; 4947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.View; 5047740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.ViewGroup.LayoutParams; 5147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.WindowManager; 5247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.view.accessibility.AccessibilityManager; 5347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.widget.ImageView; 5447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport android.widget.TextView; 5547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 5647740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.annotation.NonNull; 5747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.annotation.Nullable; 5847740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.annotation.RequiresApi; 5947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.annotation.RestrictTo; 601ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kangimport androidx.media.AudioAttributesCompat; 6147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.media.DataSourceDesc; 6247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.media.MediaItem2; 6347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.media.MediaMetadata2; 6447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.media.SessionToken2; 6547740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.mediarouter.media.MediaControlIntent; 6647740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.mediarouter.media.MediaItemStatus; 6747740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.mediarouter.media.MediaRouteSelector; 6847740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.mediarouter.media.MediaRouter; 6947740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport androidx.palette.graphics.Palette; 7047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 7147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport java.io.IOException; 7247740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport java.util.ArrayList; 7347740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport java.util.List; 7447740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport java.util.Map; 7547740510281e2d2c5a535c31d52ac970d32951c6Insun Kangimport java.util.concurrent.Executor; 7647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 7747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang/** 7847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Base implementation of VideoView2. 7947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 8047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang@RequiresApi(21) // TODO correct minSdk API use incompatibilities and remove before release. 8147740510281e2d2c5a535c31d52ac970d32951c6Insun Kangclass VideoView2ImplBaseWithMp1 8247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang implements VideoView2Impl, VideoViewInterfaceWithMp1.SurfaceListener { 8347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final String TAG = "VideoView2ImplBase_1"; 8447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 8547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final long DEFAULT_SHOW_CONTROLLER_INTERVAL_MS = 2000; 8647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 8747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_ERROR = -1; 8847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_IDLE = 0; 8947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_PREPARING = 1; 9047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_PREPARED = 2; 9147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_PLAYING = 3; 9247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_PAUSED = 4; 9347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int STATE_PLAYBACK_COMPLETED = 5; 9447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 9547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int INVALID_TRACK_INDEX = -1; 9647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final float INVALID_SPEED = 0f; 9747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 9847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int SIZE_TYPE_EMBEDDED = 0; 9947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int SIZE_TYPE_FULL = 1; 10047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private static final int SIZE_TYPE_MINIMAL = 2; 10147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 10247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private AccessibilityManager mAccessibilityManager; 10347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private AudioManager mAudioManager; 10447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private AudioAttributes mAudioAttributes; 10547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mAudioFocusType = AudioManager.AUDIOFOCUS_GAIN; // legacy focus gain 10647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean mAudioFocused = false; 10747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 10847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Pair<Executor, VideoView2.OnCustomActionListener> mCustomActionListenerRecord; 10947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private VideoView2.OnViewTypeChangedListener mViewTypeChangedListener; 11047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 11147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private VideoViewInterfaceWithMp1 mCurrentView; 11247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private VideoTextureViewWithMp1 mTextureView; 11347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private VideoSurfaceViewWithMp1 mSurfaceView; 11447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 11547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected MediaPlayer mMediaPlayer; 11647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private DataSourceDesc mDsd; 11747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Uri mUri; 11847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Map<String, String> mHeaders; 11947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaControlView2 mMediaControlView; 12047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected MediaSessionCompat mMediaSession; 12147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaControllerCompat mMediaController; 12247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaMetadata2 mMediaMetadata; 12347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaMetadataRetriever mRetriever; 12447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean mNeedUpdateMediaType; 12547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Bundle mMediaTypeData; 12647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private String mTitle; 12747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 12847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private WindowManager mManager; 12947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Resources mResources; 13047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private View mMusicView; 13147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private Drawable mMusicAlbumDrawable; 13247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private String mMusicTitleText; 13347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private String mMusicArtistText; 13447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mPrevWidth; 13547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mPrevHeight; 13647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mDominantColor; 13747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mSizeType; 13847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 13947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private PlaybackStateCompat.Builder mStateBuilder; 14047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private List<PlaybackStateCompat.CustomAction> mCustomActionList; 14147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 14247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mTargetState = STATE_IDLE; 14347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mCurrentState = STATE_IDLE; 14447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mCurrentBufferPercentage; 14547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private long mSeekWhenPrepared; // recording the seek position while preparing 14647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 14747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mVideoWidth; 14847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mVideoHeight; 14947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 15047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected ArrayList<Integer> mVideoTrackIndices; 15147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected ArrayList<Integer> mAudioTrackIndices; 15247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 15347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // selected video/audio/subtitle track index as MediaPlayer returns 15447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected int mSelectedVideoTrackIndex; 15547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected int mSelectedAudioTrackIndex; 15647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 15747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private float mSpeed; 15847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private float mFallbackSpeed; // keep the original speed before 'pause' is called. 15947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private float mVolumeLevelFloat; 16047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int mVolumeLevel; 16147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected VideoView2 mInstance; 16247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 16347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private long mShowControllerIntervalMs; 16447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 16547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaRouter mMediaRouter; 16647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaRouteSelector mRouteSelector; 16747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaRouter.RouteInfo mRoute; 16847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private RoutePlayer mRoutePlayer; 16947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 17047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private final MediaRouter.Callback mRouterCallback = new MediaRouter.Callback() { 17147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 17247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onRouteSelected(MediaRouter router, MediaRouter.RouteInfo route) { 17347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (route.supportsControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK)) { 17447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Stop local playback (if necessary) 17547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang resetPlayer(); 17647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoute = route; 17747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer = new RoutePlayer(mInstance.getContext(), route); 17847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.setPlayerEventCallback(new RoutePlayer.PlayerEventCallback() { 17947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 18047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onPlayerStateChanged(MediaItemStatus itemStatus) { 18147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackStateCompat.Builder psBuilder = new PlaybackStateCompat.Builder(); 18247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setActions(RoutePlayer.PLAYBACK_ACTIONS); 18347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang long position = itemStatus.getContentPosition(); 18447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang switch (itemStatus.getPlaybackState()) { 18547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaItemStatus.PLAYBACK_STATE_PENDING: 18647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_NONE, position, 0); 18747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_IDLE; 18847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 18947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaItemStatus.PLAYBACK_STATE_PLAYING: 19047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_PLAYING, position, 1); 19147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PLAYING; 19247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 19347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaItemStatus.PLAYBACK_STATE_PAUSED: 19447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_PAUSED, position, 0); 19547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PAUSED; 19647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 19747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaItemStatus.PLAYBACK_STATE_BUFFERING: 19847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setState( 19947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackStateCompat.STATE_BUFFERING, position, 0); 20047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PAUSED; 20147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 20247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaItemStatus.PLAYBACK_STATE_FINISHED: 20347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang psBuilder.setState(PlaybackStateCompat.STATE_STOPPED, position, 0); 20447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PLAYBACK_COMPLETED; 20547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 20647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 20747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 20847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackStateCompat pbState = psBuilder.build(); 20947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setPlaybackState(pbState); 21047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 21147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaMetadataCompat.Builder mmBuilder = new MediaMetadataCompat.Builder(); 21247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mmBuilder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, 21347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang itemStatus.getContentDuration()); 21447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setMetadata(mmBuilder.build()); 21547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 21647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }); 21747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Start remote playback (if necessary) 21847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // TODO: b/77556429 21947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.openVideo(mUri); 22047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 22147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 22247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 22347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 22447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onRouteUnselected(MediaRouter router, MediaRouter.RouteInfo route, int reason) { 22547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mRoute != null && mRoutePlayer != null) { 22647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.release(); 22747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer = null; 22847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 22947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mRoute == route) { 23047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoute = null; 23147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 23247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (reason != MediaRouter.UNSELECT_REASON_ROUTE_CHANGED) { 23347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // TODO: Resume local playback (if necessary) 23447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // TODO: b/77556429 23547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang openVideo(mUri, mHeaders); 23647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 23747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 23847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 23947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 24047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 24147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void initialize( 24247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang VideoView2 instance, Context context, 24347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Nullable AttributeSet attrs, int defStyleAttr) { 24447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance = instance; 24547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 24647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoWidth = 0; 24747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoHeight = 0; 24847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSpeed = 1.0f; 24947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mFallbackSpeed = mSpeed; 25047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mShowControllerIntervalMs = DEFAULT_SHOW_CONTROLLER_INTERVAL_MS; 25147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 25247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAccessibilityManager = (AccessibilityManager) context.getSystemService( 25347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Context.ACCESSIBILITY_SERVICE); 25447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 25547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE); 2561ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioAttributes = new AudioAttributes.Builder() 2571ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang .setUsage(AudioAttributes.USAGE_MEDIA) 25847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .setContentType(AudioAttributes.CONTENT_TYPE_MOVIE).build(); 25947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 26047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.setFocusable(true); 26147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.setFocusableInTouchMode(true); 26247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.requestFocus(); 26347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 26447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView = new VideoTextureViewWithMp1(context); 26547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView = new VideoSurfaceViewWithMp1(context); 26647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang LayoutParams params = new LayoutParams(LayoutParams.MATCH_PARENT, 26747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang LayoutParams.MATCH_PARENT); 26847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setLayoutParams(params); 26947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setLayoutParams(params); 27047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setSurfaceListener(this); 27147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setSurfaceListener(this); 27247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 27347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.addView(mTextureView); 27447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.addView(mSurfaceView); 27547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 27647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang boolean enableControlView = (attrs == null) || attrs.getAttributeBooleanValue( 27747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang "http://schemas.android.com/apk/res/android", 27847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang "enableControlView", true); 27947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (enableControlView) { 28047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView = new MediaControlView2(context); 28147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 28247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 28347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Choose surface view by default 28447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int viewType = (attrs == null) ? VideoView2.VIEW_TYPE_SURFACEVIEW 28547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang : attrs.getAttributeIntValue( 28647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang "http://schemas.android.com/apk/res/android", 28747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang "viewType", VideoView2.VIEW_TYPE_SURFACEVIEW); 28847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) { 28947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "viewType attribute is surfaceView."); 29047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setVisibility(View.GONE); 29147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setVisibility(View.VISIBLE); 29247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentView = mSurfaceView; 29347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) { 29447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "viewType attribute is textureView."); 29547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setVisibility(View.VISIBLE); 29647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setVisibility(View.GONE); 29747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentView = mTextureView; 29847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 29947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 30047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaRouteSelector.Builder builder = new MediaRouteSelector.Builder(); 30147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_REMOTE_PLAYBACK); 30247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_AUDIO); 30347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.addControlCategory(MediaControlIntent.CATEGORY_LIVE_VIDEO); 30447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRouteSelector = builder.build(); 30547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 30647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 30747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 30847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets MediaControlView2 instance. It will replace the previously assigned MediaControlView2 30947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * instance if any. 31047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 31147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param mediaControlView a media control view2 instance. 31247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param intervalMs a time interval in milliseconds until VideoView2 hides MediaControlView2. 31347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 31447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 31547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setMediaControlView2(MediaControlView2 mediaControlView, long intervalMs) { 31647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView = mediaControlView; 31747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mShowControllerIntervalMs = intervalMs; 31847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setRouteSelector(mRouteSelector); 31947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 32047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mInstance.isAttachedToWindow()) { 32147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang attachMediaControlView(); 32247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 32347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 32447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 32547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 32647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns MediaControlView2 instance which is currently attached to VideoView2 by default or by 32747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link #setMediaControlView2} method. 32847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 32947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 33047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public MediaControlView2 getMediaControlView2() { 33147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mMediaControlView; 33247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 33347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 33447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 33547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets MediaMetadata2 instance. It will replace the previously assigned MediaMetadata2 instance 33647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * if any. 33747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 33847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param metadata a MediaMetadata2 instance. 33947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 34047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 34147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 34247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 34347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setMediaMetadata(MediaMetadata2 metadata) { 34447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang //mProvider.setMediaMetadata_impl(metadata); 34547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 34647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 34747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 34847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns MediaMetadata2 instance which is retrieved from MediaPlayer inside VideoView2 by 34947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * default or by {@link #setMediaMetadata} method. 35047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 35147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 35247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 35347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 35447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public MediaMetadata2 getMediaMetadata() { 35547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mMediaMetadata; 35647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 35747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 35847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 35947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns MediaController instance which is connected with MediaSession that VideoView2 is 36047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * using. This method should be called when VideoView2 is attached to window, or it throws 36147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * IllegalStateException, since internal MediaSession instance is not available until 36247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * this view is attached to window. Please check {@link View#isAttachedToWindow} 36347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * before calling this method. 36447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 36547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @throws IllegalStateException if interal MediaSession is not created yet. 36647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide TODO: remove 36747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 36847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 36947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 37047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public MediaControllerCompat getMediaController() { 37147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaSession == null) { 37247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang throw new IllegalStateException("MediaSession instance is not available."); 37347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 37447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mMediaController; 37547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 37647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 37747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 37847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns {@link SessionToken2} so that developers create their own 37947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link androidx.media.MediaController2} instance. This method should be called when 38047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * VideoView2 is attached to window, or it throws IllegalStateException. 38147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 38247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @throws IllegalStateException if interal MediaSession is not created yet. 38347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 38447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 38547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 38647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 38747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public SessionToken2 getMediaSessionToken() { 38847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang //return mProvider.getMediaSessionToken_impl(); 38947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return null; 39047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 39147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 39247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 39347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Shows or hides closed caption or subtitles if there is any. 39447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * The first subtitle track will be chosen if there multiple subtitle tracks exist. 39547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Default behavior of VideoView2 is not showing subtitle. 39647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param enable shows closed caption or subtitles if this value is true, or hides. 39747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 39847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 39947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setSubtitleEnabled(boolean enable) { 40047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // No-op on API < 28 40147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 40247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 40347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 40447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns true if showing subtitle feature is enabled or returns false. 40547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Although there is no subtitle track or closed caption, it can return true, if the feature 40647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * has been enabled by {@link #setSubtitleEnabled}. 40747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 40847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 40947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public boolean isSubtitleEnabled() { 41047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Not supported on API < 28 41147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return false; 41247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 41347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 41447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 41547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets playback speed. 41647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 41747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * It is expressed as a multiplicative factor, where normal speed is 1.0f. If it is less than 41847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * or equal to zero, it will be just ignored and nothing will be changed. If it exceeds the 41947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * maximum speed that internal engine supports, system will determine best handling or it will 42047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * be reset to the normal speed 1.0f. 42147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param speed the playback speed. It should be positive. 42247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 42347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 42447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setSpeed(float speed) { 42547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (speed <= 0.0f) { 42647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.e(TAG, "Unsupported speed (" + speed + ") is ignored."); 42747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 42847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 42947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSpeed = speed; 43047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaPlayer != null && mMediaPlayer.isPlaying()) { 43147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang applySpeed(); 43247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 43347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 43447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 43547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 43647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 43747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns playback speed. 43847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 43947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * It returns the same value that has been set by {@link #setSpeed}, if it was available value. 44047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * If {@link #setSpeed} has not been called before, then the normal speed 1.0f will be returned. 44147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 44247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 44347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public float getSpeed() { 44447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mSpeed; 44547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 44647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 44747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 44847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets which type of audio focus will be requested during the playback, or configures playback 44947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * to not request audio focus. Valid values for focus requests are 45047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN}, {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT}, 45147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK}, and 45247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link AudioManager#AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE}. Or use 45347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link AudioManager#AUDIOFOCUS_NONE} to express that audio focus should not be 45447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * requested when playback starts. You can for instance use this when playing a silent animation 45547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * through this class, and you don't want to affect other audio applications playing in the 45647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * background. 45747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 45847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param focusGain the type of audio focus gain that will be requested, or 45947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link AudioManager#AUDIOFOCUS_NONE} to disable the use audio focus during 46047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * playback. 46147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 46247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 46347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setAudioFocusRequest(int focusGain) { 46447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (focusGain != AudioManager.AUDIOFOCUS_NONE 46547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN 46647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT 46747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK 46847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && focusGain != AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_EXCLUSIVE) { 46947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang throw new IllegalArgumentException("Illegal audio focus type " + focusGain); 47047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 47147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocusType = focusGain; 47247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 47347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 47447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 4751ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * Sets the {@link AudioAttributesCompat} to be used during the playback of the video. 47647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 4771ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang * @param attributes non-null <code>AudioAttributesCompat</code>. 47847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 47947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 4801ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang public void setAudioAttributes(@NonNull AudioAttributesCompat attributes) { 48147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (attributes == null) { 4821ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang throw new IllegalArgumentException("Illegal null AudioAttributesCompat"); 48347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 4841ed376b73eeaea2ba6211cde50575bf9734ff705Insun Kang mAudioAttributes = (AudioAttributes) attributes.unwrap(); 48547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 48647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 48747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 48847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets video path. 48947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 49047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param path the path of the video. 49147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 49247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 49347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 49447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 49547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 49647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setVideoPath(String path) { 49747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang setVideoUri(Uri.parse(path)); 49847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 49947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 50047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 50147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets video URI. 50247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 50347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param uri the URI of the video. 50447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 50547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 50647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 50747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 50847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 50947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setVideoUri(Uri uri) { 51047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang setVideoUri(uri, null); 51147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 51247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 51347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 51447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets video URI using specific headers. 51547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 51647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param uri the URI of the video. 51747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param headers the headers for the URI request. 51847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Note that the cross domain redirection is allowed by default, but that can be 51947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * changed with key/value pairs through the headers parameter with 52047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * "android-allow-cross-domain-redirect" as the key and "0" or "1" as the value 52147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * to disallow or allow cross domain redirection. 52247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 52347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 52447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setVideoUri(Uri uri, @Nullable Map<String, String> headers) { 52547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSeekWhenPrepared = 0; 52647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang openVideo(uri, headers); 52747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 52847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 52947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 53047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets {@link MediaItem2} object to render using VideoView2. Alternative way to set media 53147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * object to VideoView2 is {@link #setDataSource}. 53247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param mediaItem the MediaItem2 to play 53347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @see #setDataSource 53447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 53547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 53647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 53747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 53847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 53947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setMediaItem(@NonNull MediaItem2 mediaItem) { 54047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 54147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 54247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 54347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets {@link DataSourceDesc} object to render using VideoView2. 54447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param dataSource the {@link DataSourceDesc} object to play. 54547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @see #setMediaItem 54647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 54747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 54847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 54947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 55047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setDataSource(@NonNull DataSourceDesc dataSource) { 55147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 55247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 55347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 55447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Selects which view will be used to render video between SurfacView and TextureView. 55547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 55647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param viewType the view type to render video 55747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * <ul> 55847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * <li>{@link #VideoView2.VIEW_TYPE_SURFACEVIEW} 55947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * <li>{@link #VideoView2.VIEW_TYPE_TEXTUREVIEW} 56047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * </ul> 56147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 56247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 56347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setViewType(@VideoView2.ViewType int viewType) { 56447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (viewType == mCurrentView.getViewType()) { 56547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 56647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 56747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang VideoViewInterfaceWithMp1 targetView; 56847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (viewType == VideoView2.VIEW_TYPE_TEXTUREVIEW) { 56947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "switching to TextureView"); 57047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang targetView = mTextureView; 57147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (viewType == VideoView2.VIEW_TYPE_SURFACEVIEW) { 57247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "switching to SurfaceView"); 57347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang targetView = mSurfaceView; 57447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 57547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang throw new IllegalArgumentException("Unknown view type: " + viewType); 57647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 57747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang ((View) targetView).setVisibility(View.VISIBLE); 57847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang targetView.takeOver(mCurrentView); 57947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.requestLayout(); 58047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 58147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 58247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 58347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Returns view type. 58447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 58547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @return view type. See {@see setViewType}. 58647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 58747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 58847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @VideoView2.ViewType 58947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public int getViewType() { 59047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mCurrentView.getViewType(); 59147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 59247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 59347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 59447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Sets custom actions which will be shown as custom buttons in {@link MediaControlView2}. 59547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * 59647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param actionList A list of {@link PlaybackStateCompat.CustomAction}. The return value of 59747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@link PlaybackStateCompat.CustomAction#getIcon()} will be used to draw 59847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * buttons in {@link MediaControlView2}. 59947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param executor executor to run callbacks on. 60047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param listener A listener to be called when a custom button is clicked. 60147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 60247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 60347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 60447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 60547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setCustomActions(List<PlaybackStateCompat.CustomAction> actionList, 60647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Executor executor, VideoView2.OnCustomActionListener listener) { 60747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCustomActionList = actionList; 60847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCustomActionListenerRecord = new Pair<>(executor, listener); 60947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 61047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Create a new playback builder in order to clear existing the custom actions. 61147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder = null; 61247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 61347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 61447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 61547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 61647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Registers a callback to be invoked when a view type change is done. 61747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * {@see #setViewType(int)} 61847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @param l The callback that will be run 61947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * @hide 62047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 62147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @RestrictTo(LIBRARY_GROUP) 62247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 62347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void setOnViewTypeChangedListener(VideoView2.OnViewTypeChangedListener l) { 62447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mViewTypeChangedListener = l; 62547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 62647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 62747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 62847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onAttachedToWindowImpl() { 62947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Create MediaSession 63047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession = new MediaSessionCompat(mInstance.getContext(), "VideoView2MediaSession"); 63147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setCallback(new MediaSessionCallback()); 63247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setActive(true); 63347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController = mMediaSession.getController(); 63447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang attachMediaControlView(); 63547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mCurrentState == STATE_PREPARED) { 63647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractTracks(); 63747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractMetadata(); 63847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractAudioMetadata(); 63947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mNeedUpdateMediaType) { 64047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.sendSessionEvent( 64147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, 64247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaTypeData); 64347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mNeedUpdateMediaType = false; 64447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 64547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 64647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 64747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaRouter = MediaRouter.getInstance(mInstance.getContext()); 64847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaRouter.setMediaSessionCompat(mMediaSession); 64947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaRouter.addCallback(mRouteSelector, mRouterCallback, 65047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaRouter.CALLBACK_FLAG_PERFORM_ACTIVE_SCAN); 65147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 65247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 65347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 65447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onDetachedFromWindowImpl() { 65547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.release(); 65647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession = null; 65747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController = null; 65847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 65947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 66047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 66147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onTouchEventImpl(MotionEvent ev) { 66247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 66347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onTouchEvent(). mCurrentState=" + mCurrentState 66447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState); 66547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 66647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) { 66747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (!isMusicMediaType() || mSizeType != SIZE_TYPE_FULL) { 66847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang toggleMediaControlViewVisibility(); 66947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 67047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 67147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 67247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 67347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 67447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onTrackballEventImpl(MotionEvent ev) { 67547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (ev.getAction() == MotionEvent.ACTION_UP && mMediaControlView != null) { 67647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (!isMusicMediaType() || mSizeType != SIZE_TYPE_FULL) { 67747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang toggleMediaControlViewVisibility(); 67847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 67947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 68047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 68147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 68247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 68347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onMeasureImpl(int widthMeasureSpec, int heightMeasureSpec) { 68447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isMusicMediaType()) { 68547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int currWidth = mInstance.getMeasuredWidth(); 68647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int currHeight = mInstance.getMeasuredHeight(); 68747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mPrevWidth != currWidth || mPrevHeight != currHeight) { 68847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Point screenSize = new Point(); 68947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mManager.getDefaultDisplay().getSize(screenSize); 69047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int screenWidth = screenSize.x; 69147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int screenHeight = screenSize.y; 69247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 69347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (currWidth == screenWidth && currHeight == screenHeight) { 69447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int orientation = retrieveOrientation(); 69547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (orientation == ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) { 69647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang inflateMusicView(R.layout.full_landscape_music); 69747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 69847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang inflateMusicView(R.layout.full_portrait_music); 69947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 70047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 70147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mSizeType != SIZE_TYPE_FULL) { 70247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSizeType = SIZE_TYPE_FULL; 70347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Remove existing mFadeOut callback 70447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 70547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setVisibility(View.VISIBLE); 70647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 70747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 70847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mSizeType != SIZE_TYPE_EMBEDDED) { 70947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSizeType = SIZE_TYPE_EMBEDDED; 71047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang inflateMusicView(R.layout.embedded_music); 71147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Add new mFadeOut callback 71247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs); 71347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 71447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 71547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mPrevWidth = currWidth; 71647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mPrevHeight = currHeight; 71747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 71847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 71947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 72047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 72147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /////////////////////////////////////////////////// 72247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Implements VideoViewInterfaceWithMp1.SurfaceListener 72347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /////////////////////////////////////////////////// 72447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 72547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 72647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSurfaceCreated(View view, int width, int height) { 72747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 72847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onSurfaceCreated(). mCurrentState=" + mCurrentState 72947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState + ", width/height: " + width + "/" + height 73047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", " + view.toString()); 73147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 73247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (needToStart()) { 73347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().play(); 73447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 73547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 73647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 73747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 73847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSurfaceDestroyed(View view) { 73947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 74047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onSurfaceDestroyed(). mCurrentState=" + mCurrentState 74147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState + ", " + view.toString()); 74247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 74347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 74447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 74547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 74647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSurfaceChanged(View view, int width, int height) { 74747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 74847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onSurfaceChanged(). width/height: " + width + "/" + height 74947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", " + view.toString()); 75047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 75147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 75247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 75347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 75447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSurfaceTakeOverDone(VideoViewInterfaceWithMp1 view) { 75547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 75647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onSurfaceTakeOverDone(). Now current view is: " + view); 75747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 75847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentView = view; 75947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mViewTypeChangedListener != null) { 76047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mViewTypeChangedListener.onViewTypeChanged(mInstance, view.getViewType()); 76147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 76247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (needToStart()) { 76347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().play(); 76447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 76547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 76647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 76747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /////////////////////////////////////////////////// 76847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Protected or private methods 76947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /////////////////////////////////////////////////// 77047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 77147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void attachMediaControlView() { 77247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Get MediaController from MediaSession and set it inside MediaControlView 77347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setController(mMediaSession.getController()); 77447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 77547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang LayoutParams params = 77647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new LayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT); 77747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.addView(mMediaControlView, params); 77847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 77947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 78047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected boolean isInPlaybackState() { 78147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return (mMediaPlayer != null || mRoutePlayer != null) 78247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && mCurrentState != STATE_ERROR 78347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && mCurrentState != STATE_IDLE 78447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && mCurrentState != STATE_PREPARING; 78547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 78647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 78747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean needToStart() { 78847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return (mMediaPlayer != null || mRoutePlayer != null) 78947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && isAudioGranted() 79047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && isWaitingPlayback(); 79147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 79247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 79347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean isMusicMediaType() { 79447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mVideoTrackIndices != null && mVideoTrackIndices.size() == 0; 79547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 79647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 79747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean isWaitingPlayback() { 79847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mCurrentState != STATE_PLAYING && mTargetState == STATE_PLAYING; 79947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 80047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 80147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean isAudioGranted() { 80247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return mAudioFocused || mAudioFocusType == AudioManager.AUDIOFOCUS_NONE; 80347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 80447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 80547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private AudioManager.OnAudioFocusChangeListener mAudioFocusListener = 80647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new AudioManager.OnAudioFocusChangeListener() { 80747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 80847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onAudioFocusChange(int focusChange) { 80947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang switch (focusChange) { 81047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case AudioManager.AUDIOFOCUS_GAIN: 81147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocused = true; 81247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (needToStart()) { 81347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().play(); 81447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 81547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 81647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case AudioManager.AUDIOFOCUS_LOSS: 81747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT: 81847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case AudioManager.AUDIOFOCUS_LOSS_TRANSIENT_CAN_DUCK: 81947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocused = false; 82047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isInPlaybackState() && mMediaPlayer.isPlaying()) { 82147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().pause(); 82247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 82347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_PAUSED; 82447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 82547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 82647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 82747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 82847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 82947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @SuppressWarnings("deprecation") 83047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void requestAudioFocus(int focusType) { 83147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int result; 83247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (android.os.Build.VERSION.SDK_INT >= 26) { 83347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang AudioFocusRequest focusRequest; 83447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang focusRequest = new AudioFocusRequest.Builder(focusType) 83547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .setAudioAttributes(mAudioAttributes) 83647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .setOnAudioFocusChangeListener(mAudioFocusListener) 83747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .build(); 83847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang result = mAudioManager.requestAudioFocus(focusRequest); 83947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 84047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang result = mAudioManager.requestAudioFocus(mAudioFocusListener, 84147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang AudioManager.STREAM_MUSIC, 84247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang focusType); 84347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 84447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (result == AudioManager.AUDIOFOCUS_REQUEST_FAILED) { 84547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocused = false; 84647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (result == AudioManager.AUDIOFOCUS_REQUEST_GRANTED) { 84747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocused = true; 84847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (result == AudioManager.AUDIOFOCUS_REQUEST_DELAYED) { 84947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioFocused = false; 85047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 85147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 85247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 85347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Creates a MediaPlayer instance and prepare playback. 85447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void openVideo(Uri uri, Map<String, String> headers) { 85547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang resetPlayer(); 85647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mUri = uri; 85747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 85847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // TODO: b/77556429 85947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.openVideo(uri); 86047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 86147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 86247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 86347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang try { 86447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "openVideo(): creating new MediaPlayer instance."); 86547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer = new MediaPlayer(); 86647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang final Context context = mInstance.getContext(); 86747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang setupMediaPlayer(context, uri, headers); 86847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 86947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // we don't set the target state here either, but preserve the 87047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // target state that was there before. 87147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PREPARING; 87247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.prepareAsync(); 87347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 87447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Save file name as title since the file may not have a title Metadata. 87547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTitle = uri.getPath(); 87647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang String scheme = uri.getScheme(); 87747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (scheme != null && scheme.equals("file")) { 87847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTitle = uri.getLastPathSegment(); 87947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRetriever = new MediaMetadataRetriever(); 88047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRetriever.setDataSource(context, uri); 88147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 88247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 88347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 88447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "openVideo(). mCurrentState=" + mCurrentState 88547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState); 88647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 88747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } catch (IOException | IllegalArgumentException ex) { 88847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.w(TAG, "Unable to open content: " + uri, ex); 88947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_ERROR; 89047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_ERROR; 89147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mErrorListener.onError(mMediaPlayer, 89247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaPlayer.MEDIA_ERROR_UNKNOWN, MediaPlayer.MEDIA_ERROR_IO); 89347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 89447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 89547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 89647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /** 89747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Used in openVideo(). Setup MediaPlayer and related objects before calling prepare. 89847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 89947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected void setupMediaPlayer(Context context, Uri uri, Map<String, String> headers) 90047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang throws IOException { 90147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setMediaPlayer(mMediaPlayer); 90247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setMediaPlayer(mMediaPlayer); 90347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentView.assignSurfaceToMediaPlayer(mMediaPlayer); 90447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 90547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnPreparedListener(mPreparedListener); 90647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnVideoSizeChangedListener(mSizeChangedListener); 90747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnCompletionListener(mCompletionListener); 90847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnSeekCompleteListener(mSeekCompleteListener); 90947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnErrorListener(mErrorListener); 91047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnInfoListener(mInfoListener); 91147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setOnBufferingUpdateListener(mBufferingUpdateListener); 91247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 91347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentBufferPercentage = -1; 91447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setDataSource(context, uri, headers); 91547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setAudioAttributes(mAudioAttributes); 91647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 91747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 91847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang /* 91947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang * Reset the media player in any state 92047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang */ 92147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @SuppressWarnings("deprecation") 92247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void resetPlayer() { 92347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaPlayer != null) { 92447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.reset(); 92547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.release(); 92647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer = null; 92747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTextureView.setMediaPlayer(null); 92847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSurfaceView.setMediaPlayer(null); 92947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_IDLE; 93047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_IDLE; 93147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) { 93247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioManager.abandonAudioFocus(null); 93347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 93447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 93547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoWidth = 0; 93647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoHeight = 0; 93747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 93847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 93947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void updatePlaybackState() { 94047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mStateBuilder == null) { 94147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang long playbackActions = PlaybackStateCompat.ACTION_PLAY 94247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang | PlaybackStateCompat.ACTION_PAUSE 94347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang | PlaybackStateCompat.ACTION_REWIND | PlaybackStateCompat.ACTION_FAST_FORWARD 94447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang | PlaybackStateCompat.ACTION_SEEK_TO; 94547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder = new PlaybackStateCompat.Builder(); 94647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder.setActions(playbackActions); 94747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 94847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mCustomActionList != null) { 94947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang for (PlaybackStateCompat.CustomAction action : mCustomActionList) { 95047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder.addCustomAction(action); 95147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 95247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 95347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 95447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder.setState(getCorrespondingPlaybackState(), 95547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.getCurrentPosition(), mSpeed); 95647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mCurrentState != STATE_ERROR 95747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && mCurrentState != STATE_IDLE 95847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && mCurrentState != STATE_PREPARING) { 95947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mCurrentBufferPercentage == -1) { 96047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder.setBufferedPosition(-1); 96147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 96247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mStateBuilder.setBufferedPosition( 96347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang (long) (mCurrentBufferPercentage / 100.0 * mMediaPlayer.getDuration())); 96447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 96547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 96647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 96747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Set PlaybackState for MediaSession 96847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaSession != null) { 96947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackStateCompat state = mStateBuilder.build(); 97047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setPlaybackState(state); 97147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 97247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 97347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 97447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int getCorrespondingPlaybackState() { 97547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang switch (mCurrentState) { 97647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_ERROR: 97747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_ERROR; 97847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_IDLE: 97947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_NONE; 98047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_PREPARING: 98147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_CONNECTING; 98247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_PREPARED: 98347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_PAUSED; 98447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_PLAYING: 98547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_PLAYING; 98647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_PAUSED: 98747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_PAUSED; 98847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case STATE_PLAYBACK_COMPLETED: 98947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return PlaybackStateCompat.STATE_STOPPED; 99047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang default: 99147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return -1; 99247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 99347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 99447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 99547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private final Runnable mFadeOut = new Runnable() { 99647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 99747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void run() { 99847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mCurrentState == STATE_PLAYING) { 99947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setVisibility(View.GONE); 100047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 100147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 100247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 100347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 100447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void showController() { 100547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaControlView == null || !isInPlaybackState() 100647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang || (isMusicMediaType() && mSizeType == SIZE_TYPE_FULL)) { 100747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 100847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 100947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 101047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setVisibility(View.VISIBLE); 101147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mShowControllerIntervalMs != 0 101247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && !mAccessibilityManager.isTouchExplorationEnabled()) { 101347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.postDelayed(mFadeOut, mShowControllerIntervalMs); 101447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 101547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 101647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 101747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void toggleMediaControlViewVisibility() { 101847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaControlView.getVisibility() == View.VISIBLE) { 101947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.removeCallbacks(mFadeOut); 102047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setVisibility(View.GONE); 102147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 102247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 102347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 102447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 102547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 102647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void applySpeed() { 102747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (android.os.Build.VERSION.SDK_INT < 23) { 102847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 102947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 103047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackParams params = mMediaPlayer.getPlaybackParams().allowDefaults(); 103147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mSpeed != params.getSpeed()) { 103247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang try { 103347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang params.setSpeed(mSpeed); 103447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.setPlaybackParams(params); 103547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mFallbackSpeed = mSpeed; 103647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } catch (IllegalArgumentException e) { 103747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.e(TAG, "PlaybackParams has unsupported value: " + e); 103847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang float fallbackSpeed = mMediaPlayer.getPlaybackParams().allowDefaults().getSpeed(); 103947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (fallbackSpeed > 0.0f) { 104047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mFallbackSpeed = fallbackSpeed; 104147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 104247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSpeed = mFallbackSpeed; 104347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 104447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 104547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 104647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 104747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private boolean isRemotePlayback() { 104847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaController == null) { 104947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return false; 105047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 105147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang PlaybackInfo playbackInfo = mMediaController.getPlaybackInfo(); 105247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return playbackInfo != null 105347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang && playbackInfo.getPlaybackType() == PlaybackInfo.PLAYBACK_TYPE_REMOTE; 105447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 105547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 105647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected void extractTracks() { 105747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaPlayer.TrackInfo[] trackInfos = mMediaPlayer.getTrackInfo(); 105847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoTrackIndices = new ArrayList<>(); 105947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioTrackIndices = new ArrayList<>(); 106047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang for (int i = 0; i < trackInfos.length; ++i) { 106147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int trackType = trackInfos[i].getTrackType(); 106247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_VIDEO) { 106347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoTrackIndices.add(i); 106447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (trackType == MediaPlayer.TrackInfo.MEDIA_TRACK_TYPE_AUDIO) { 106547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioTrackIndices.add(i); 106647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 106747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 106847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Select first tracks as default 106947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mVideoTrackIndices.size() > 0) { 107047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSelectedVideoTrackIndex = 0; 107147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 107247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mAudioTrackIndices.size() > 0) { 107347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSelectedAudioTrackIndex = 0; 107447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 107547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 107647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Bundle data = new Bundle(); 107747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang data.putInt(MediaControlView2.KEY_VIDEO_TRACK_COUNT, mVideoTrackIndices.size()); 107847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang data.putInt(MediaControlView2.KEY_AUDIO_TRACK_COUNT, mAudioTrackIndices.size()); 107947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.sendSessionEvent(MediaControlView2.EVENT_UPDATE_TRACK_STATUS, data); 108047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 108147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 108247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected void doShowSubtitleCommand(Bundle args) { 108347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // No-op 108447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 108547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 108647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang protected void doHideSubtitleCommand() { 108747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // No-op 108847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 108947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 109047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void extractMetadata() { 109147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mRetriever == null) { 109247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 109347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 109447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Get and set duration and title values as MediaMetadata for MediaControlView2 109547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 109647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE); 109747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (title != null) { 109847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTitle = title; 109947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 110047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle); 110147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putLong( 110247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration()); 110347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 110447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaSession != null) { 110547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setMetadata(builder.build()); 110647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 110747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 110847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 110947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @SuppressWarnings("deprecation") 111047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void extractAudioMetadata() { 111147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mRetriever == null || !isMusicMediaType()) { 111247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return; 111347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 111447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 111547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mResources = mInstance.getResources(); 111647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mManager = (WindowManager) mInstance.getContext().getApplicationContext() 111747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .getSystemService(Context.WINDOW_SERVICE); 111847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 111947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang byte[] album = mRetriever.getEmbeddedPicture(); 112047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (album != null) { 112147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Bitmap bitmap = BitmapFactory.decodeByteArray(album, 0, album.length); 112247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicAlbumDrawable = new BitmapDrawable(bitmap); 112347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 112447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Palette.Builder builder = Palette.from(bitmap); 112547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.generate(new Palette.PaletteAsyncListener() { 112647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 112747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onGenerated(Palette palette) { 112847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mDominantColor = palette.getDominantColor(0); 112947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMusicView != null) { 113047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicView.setBackgroundColor(mDominantColor); 113147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 113247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 113347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }); 113447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 113547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicAlbumDrawable = mResources.getDrawable(R.drawable.ic_default_album_image); 113647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 113747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 113847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang String title = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_TITLE); 113947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (title != null) { 114047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicTitleText = title; 114147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 114247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicTitleText = mResources.getString(R.string.mcv2_music_title_unknown_text); 114347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 114447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 114547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang String artist = mRetriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_ARTIST); 114647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (artist != null) { 114747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicArtistText = artist; 114847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 114947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicArtistText = mResources.getString(R.string.mcv2_music_artist_unknown_text); 115047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 115147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 115247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Send title and artist string to MediaControlView2 115347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 115447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mMusicTitleText); 115547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_ARTIST, mMusicArtistText); 115647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setMetadata(builder.build()); 115747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 115847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Display Embedded mode as default 115947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.removeView(mSurfaceView); 116047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.removeView(mTextureView); 116147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang inflateMusicView(R.layout.embedded_music); 116247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 116347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 116447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private int retrieveOrientation() { 116547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang DisplayMetrics dm = Resources.getSystem().getDisplayMetrics(); 116647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int width = dm.widthPixels; 116747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int height = dm.heightPixels; 116847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 116947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return (height > width) 117047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang ? ActivityInfo.SCREEN_ORIENTATION_PORTRAIT 117147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang : ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE; 117247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 117347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 117447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private void inflateMusicView(int layoutId) { 117547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.removeView(mMusicView); 117647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 117747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang LayoutInflater inflater = (LayoutInflater) mInstance.getContext() 117847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang .getSystemService(Context.LAYOUT_INFLATER_SERVICE); 117947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang View v = inflater.inflate(layoutId, null); 118047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang v.setBackgroundColor(mDominantColor); 118147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 118247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang ImageView albumView = v.findViewById(R.id.album); 118347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (albumView != null) { 118447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang albumView.setImageDrawable(mMusicAlbumDrawable); 118547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 118647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 118747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang TextView titleView = v.findViewById(R.id.title); 118847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (titleView != null) { 118947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang titleView.setText(mMusicTitleText); 119047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 119147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 119247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang TextView artistView = v.findViewById(R.id.artist); 119347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (artistView != null) { 119447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang artistView.setText(mMusicArtistText); 119547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 119647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 119747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMusicView = v; 119847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.addView(mMusicView, 0); 119947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 120047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 120147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnVideoSizeChangedListener mSizeChangedListener = 120247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new MediaPlayer.OnVideoSizeChangedListener() { 120347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 120447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onVideoSizeChanged( 120547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaPlayer mp, int width, int height) { 120647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 120747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onVideoSizeChanged(): size: " + width + "/" + height); 120847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 120947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoWidth = mp.getVideoWidth(); 121047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoHeight = mp.getVideoHeight(); 121147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 121247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onVideoSizeChanged(): mVideoSize:" + mVideoWidth + "/" 121347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + mVideoHeight); 121447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 121547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mVideoWidth != 0 && mVideoHeight != 0) { 121647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.requestLayout(); 121747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 121847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 121947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 122047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 122147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnPreparedListener mPreparedListener = 122247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new MediaPlayer.OnPreparedListener() { 122347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 122447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onPrepared(MediaPlayer mp) { 122547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 122647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "OnPreparedListener(). mCurrentState=" + mCurrentState 122747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState); 122847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 122947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PREPARED; 123047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Create and set playback state for MediaControlView2 123147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 123247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 123347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaSession != null) { 123447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractTracks(); 123547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractMetadata(); 123647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractAudioMetadata(); 123747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 123847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 123947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaControlView != null) { 124047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setEnabled(true); 124147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 124247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int videoWidth = mp.getVideoWidth(); 124347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int videoHeight = mp.getVideoHeight(); 124447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 124547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // mSeekWhenPrepared may be changed after seekTo() call 124647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang long seekToPosition = mSeekWhenPrepared; 124747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (seekToPosition != 0) { 124847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().seekTo(seekToPosition); 124947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 125047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 125147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (videoWidth != 0 && videoHeight != 0) { 125247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (videoWidth != mVideoWidth || videoHeight != mVideoHeight) { 125347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoWidth = videoWidth; 125447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVideoHeight = videoHeight; 125547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mInstance.requestLayout(); 125647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 125747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 125847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (needToStart()) { 125947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().play(); 126047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 126147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 126247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // We don't know the video size yet, but should start anyway. 126347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // The video size might be reported to us later. 126447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (needToStart()) { 126547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaController.getTransportControls().play(); 126647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 126747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 126847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang // Get and set duration and title values as MediaMetadata for MediaControlView2 126947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaMetadataCompat.Builder builder = new MediaMetadataCompat.Builder(); 127047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 127147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putString(MediaMetadataCompat.METADATA_KEY_TITLE, mTitle); 127247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang builder.putLong(MediaMetadataCompat.METADATA_KEY_DURATION, mMediaPlayer.getDuration()); 127347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 127447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaSession != null) { 127547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.setMetadata(builder.build()); 127647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 127747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mNeedUpdateMediaType) { 127847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaSession.sendSessionEvent( 127947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaControlView2.EVENT_UPDATE_MEDIA_TYPE_STATUS, mMediaTypeData); 128047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mNeedUpdateMediaType = false; 128147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 128247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 128347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 128447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 128547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 128647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnSeekCompleteListener mSeekCompleteListener = 128747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new MediaPlayer.OnSeekCompleteListener() { 128847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 128947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSeekComplete(MediaPlayer mp) { 129047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 129147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 129247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 129347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 129447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnCompletionListener mCompletionListener = 129547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new MediaPlayer.OnCompletionListener() { 129647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 129747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @SuppressWarnings("deprecation") 129847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onCompletion(MediaPlayer mp) { 129947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PLAYBACK_COMPLETED; 130047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_PLAYBACK_COMPLETED; 130147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 130247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mAudioFocusType != AudioManager.AUDIOFOCUS_NONE) { 130347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioManager.abandonAudioFocus(null); 130447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 130547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 130647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 130747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 130847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnInfoListener mInfoListener = new MediaPlayer.OnInfoListener() { 130947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 131047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public boolean onInfo(MediaPlayer mp, int what, int extra) { 131147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (what == MediaPlayer.MEDIA_INFO_METADATA_UPDATE) { 131247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang extractTracks(); 131347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 131447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return true; 131547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 131647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 131747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 131847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnErrorListener mErrorListener = new MediaPlayer.OnErrorListener() { 131947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 132047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public boolean onError(MediaPlayer mp, int frameworkErr, int implErr) { 132147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 132247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "Error: " + frameworkErr + "," + implErr); 132347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 132447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_ERROR; 132547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_ERROR; 132647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 132747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 132847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (mMediaControlView != null) { 132947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaControlView.setVisibility(View.GONE); 133047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 133147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang return true; 133247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 133347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 133447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 133547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private MediaPlayer.OnBufferingUpdateListener mBufferingUpdateListener = 133647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang new MediaPlayer.OnBufferingUpdateListener() { 133747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 133847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onBufferingUpdate(MediaPlayer mp, int percent) { 133947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentBufferPercentage = percent; 134047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 134147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 134247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }; 134347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 134447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang private class MediaSessionCallback extends MediaSessionCompat.Callback { 134547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 134647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onCommand(String command, Bundle args, ResultReceiver receiver) { 134747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 134847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.onCommand(command, args, receiver); 134947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 135047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang switch (command) { 135147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_SHOW_SUBTITLE: 135247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang doShowSubtitleCommand(args); 135347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 135447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_HIDE_SUBTITLE: 135547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang doHideSubtitleCommand(); 135647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 135747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_SELECT_AUDIO_TRACK: 135847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int audioIndex = args.getInt(MediaControlView2.KEY_SELECTED_AUDIO_INDEX, 135947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang INVALID_TRACK_INDEX); 136047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (audioIndex != INVALID_TRACK_INDEX) { 136147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang int audioTrackIndex = mAudioTrackIndices.get(audioIndex); 136247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (audioTrackIndex != mSelectedAudioTrackIndex) { 136347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSelectedAudioTrackIndex = audioTrackIndex; 136447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.selectTrack(mSelectedAudioTrackIndex); 136547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 136647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 136747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 136847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_SET_PLAYBACK_SPEED: 136947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang float speed = args.getFloat( 137047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang MediaControlView2.KEY_PLAYBACK_SPEED, INVALID_SPEED); 137147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (speed != INVALID_SPEED && speed != mSpeed) { 137247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang setSpeed(speed); 137347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSpeed = speed; 137447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 137547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 137647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_MUTE: 137747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mVolumeLevel = mAudioManager.getStreamVolume(AudioManager.STREAM_MUSIC); 137847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, 0, 0); 137947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 138047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang case MediaControlView2.COMMAND_UNMUTE: 138147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mAudioManager.setStreamVolume(AudioManager.STREAM_MUSIC, mVolumeLevel, 0); 138247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang break; 138347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 138447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 138547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 138647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 138747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 138847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 138947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onCustomAction(final String action, final Bundle extras) { 139047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCustomActionListenerRecord.first.execute(new Runnable() { 139147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 139247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void run() { 139347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCustomActionListenerRecord.second.onCustomAction(action, extras); 139447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 139547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang }); 139647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 139747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 139847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 139947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 140047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onPlay() { 140147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (!isAudioGranted()) { 140247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang requestAudioFocus(mAudioFocusType); 140347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 140447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 140547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if ((isInPlaybackState() && mCurrentView.hasAvailableSurface()) || isMusicMediaType()) { 140647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 140747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.onPlay(); 140847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 140947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang applySpeed(); 141047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.start(); 141147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PLAYING; 141247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 141347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 141447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PLAYING; 141547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 141647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_PLAYING; 141747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 141847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onPlay(). mCurrentState=" + mCurrentState 141947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState); 142047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 142147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 142247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 142347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 142447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 142547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onPause() { 142647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isInPlaybackState()) { 142747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 142847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.onPlay(); 142947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PAUSED; 143047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else if (mMediaPlayer.isPlaying()) { 143147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.pause(); 143247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mCurrentState = STATE_PAUSED; 143347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang updatePlaybackState(); 143447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 143547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 143647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mTargetState = STATE_PAUSED; 143747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (DEBUG) { 143847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang Log.d(TAG, "onPause(). mCurrentState=" + mCurrentState 143947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang + ", mTargetState=" + mTargetState); 144047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 144147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 144247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 144347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 144447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 144547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onSeekTo(long pos) { 144647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isInPlaybackState()) { 144747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 144847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.onPlay(); 144947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 145047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (android.os.Build.VERSION.SDK_INT < 26) { 145147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.seekTo((int) pos); 145247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 145347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mMediaPlayer.seekTo(pos, MediaPlayer.SEEK_PREVIOUS_SYNC); 145447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 145547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSeekWhenPrepared = 0; 145647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 145747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 145847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mSeekWhenPrepared = pos; 145947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 146047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 146147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 146247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang 146347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang @Override 146447740510281e2d2c5a535c31d52ac970d32951c6Insun Kang public void onStop() { 146547740510281e2d2c5a535c31d52ac970d32951c6Insun Kang if (isRemotePlayback()) { 146647740510281e2d2c5a535c31d52ac970d32951c6Insun Kang mRoutePlayer.onPlay(); 146747740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } else { 146847740510281e2d2c5a535c31d52ac970d32951c6Insun Kang resetPlayer(); 146947740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 147047740510281e2d2c5a535c31d52ac970d32951c6Insun Kang showController(); 147147740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 147247740510281e2d2c5a535c31d52ac970d32951c6Insun Kang } 147347740510281e2d2c5a535c31d52ac970d32951c6Insun Kang} 1474