MediaPlayerAdapter.java revision ac5fe7c617c66850fff75a9fce9979c6e5674b0f
13bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu/* 23bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Copyright (C) 2017 The Android Open Source Project 33bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 43bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Licensed under the Apache License, Version 2.0 (the "License"); 53bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * you may not use this file except in compliance with the License. 63bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * You may obtain a copy of the License at 73bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 83bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * http://www.apache.org/licenses/LICENSE-2.0 93bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 103bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Unless required by applicable law or agreed to in writing, software 113bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * distributed under the License is distributed on an "AS IS" BASIS, 123bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * See the License for the specific language governing permissions and 143bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * limitations under the License. 153bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 163bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.leanback.media; 183bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 193bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.content.Context; 203bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.media.AudioManager; 213bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.media.MediaPlayer; 223bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.net.Uri; 233bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.os.Handler; 24ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.leanback.R; 253bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport android.view.SurfaceHolder; 263bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 273bcad88cbf4488e747d84893c35f2351b8f84afeDake Guimport java.io.IOException; 283bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 293bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu/** 303bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * This implementation extends the {@link PlayerAdapter} with a {@link MediaPlayer}. 313bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 323bcad88cbf4488e747d84893c35f2351b8f84afeDake Gupublic class MediaPlayerAdapter extends PlayerAdapter { 333bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 343bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu Context mContext; 353bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer mPlayer = new MediaPlayer(); 363bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu SurfaceHolderGlueHost mSurfaceHolderGlueHost; 373bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final Runnable mRunnable = new Runnable() { 383bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 393bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void run() { 403bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onCurrentPositionChanged(MediaPlayerAdapter.this); 413bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mHandler.postDelayed(this, getUpdatePeriod()); 423bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 433bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu };; 443bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final Handler mHandler = new Handler(); 453bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean mInitialized = false; // true when the MediaPlayer is prepared/initialized 463bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu Uri mMediaSourceUri = null; 473bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean mHasDisplay; 483bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu long mBufferedProgress; 493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 503bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu MediaPlayer.OnPreparedListener mOnPreparedListener = new MediaPlayer.OnPreparedListener() { 513bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 523bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onPrepared(MediaPlayer mp) { 533bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mInitialized = true; 543bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu notifyBufferingStartEnd(); 553bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mSurfaceHolderGlueHost == null || mHasDisplay) { 563bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPreparedStateChanged(MediaPlayerAdapter.this); 573bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 583bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 593bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 603bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 613bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnCompletionListener mOnCompletionListener = 623bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu new MediaPlayer.OnCompletionListener() { 633bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 643bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onCompletion(MediaPlayer mediaPlayer) { 653bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPlayStateChanged(MediaPlayerAdapter.this); 663bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPlayCompleted(MediaPlayerAdapter.this); 673bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 683bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 693bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 703bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnBufferingUpdateListener mOnBufferingUpdateListener = 713bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu new MediaPlayer.OnBufferingUpdateListener() { 723bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 733bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onBufferingUpdate(MediaPlayer mp, int percent) { 743bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mBufferedProgress = getDuration() * percent / 100; 753bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onBufferedPositionChanged(MediaPlayerAdapter.this); 763bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 773bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 783bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 793bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnVideoSizeChangedListener mOnVideoSizeChangedListener = 803bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu new MediaPlayer.OnVideoSizeChangedListener() { 813bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 823bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onVideoSizeChanged(MediaPlayer mediaPlayer, int width, int height) { 833bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onVideoSizeChanged(MediaPlayerAdapter.this, width, height); 843bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 853bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 863bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnErrorListener mOnErrorListener = 883bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu new MediaPlayer.OnErrorListener() { 893bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 903bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean onError(MediaPlayer mp, int what, int extra) { 913bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onError(MediaPlayerAdapter.this, what, 923bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mContext.getString(R.string.lb_media_player_error, what, extra)); 933bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return MediaPlayerAdapter.this.onError(what, extra); 943bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 953bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 963bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 973bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnSeekCompleteListener mOnSeekCompleteListener = 983bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu new MediaPlayer.OnSeekCompleteListener() { 993bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 1003bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onSeekComplete(MediaPlayer mp) { 1013bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu MediaPlayerAdapter.this.onSeekComplete(); 1023bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1033bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 1043bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1053bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu final MediaPlayer.OnInfoListener mOnInfoListener = new MediaPlayer.OnInfoListener() { 1063bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 1073bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean onInfo(MediaPlayer mp, int what, int extra) { 1083bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean handled = false; 1093bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu switch (what) { 1103bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu case MediaPlayer.MEDIA_INFO_BUFFERING_START: 1113bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mBufferingStart = true; 1123bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu notifyBufferingStartEnd(); 1133bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu handled = true; 1143bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu break; 1153bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu case MediaPlayer.MEDIA_INFO_BUFFERING_END: 1163bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mBufferingStart = false; 1173bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu notifyBufferingStartEnd(); 1183bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu handled = true; 1193bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu break; 1203bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1213bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean thisHandled = MediaPlayerAdapter.this.onInfo(what, extra); 1223bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return handled || thisHandled; 1233bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1243bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu }; 1253bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1263bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean mBufferingStart; 1273bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1283bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu void notifyBufferingStartEnd() { 1293bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onBufferingStateChanged(MediaPlayerAdapter.this, 1303bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mBufferingStart || !mInitialized); 1313bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1323bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1333bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 1343bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Constructor. 1353bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 1363bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public MediaPlayerAdapter(Context context) { 1373bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mContext = context; 1383bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1393bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1403bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 1413bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onAttachedToHost(PlaybackGlueHost host) { 1423bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (host instanceof SurfaceHolderGlueHost) { 1433bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mSurfaceHolderGlueHost = ((SurfaceHolderGlueHost) host); 1443bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mSurfaceHolderGlueHost.setSurfaceHolderCallback(new VideoPlayerSurfaceHolderCallback()); 1453bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1463bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1473bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1483bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 1493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Will reset the {@link MediaPlayer} and the glue such that a new file can be played. You are 1503bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * not required to call this method before playing the first file. However you have to call it 1513bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * before playing a second one. 1523bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 1533bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void reset() { 1543bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu changeToUnitialized(); 1553bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.reset(); 1563bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1573bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1583bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu void changeToUnitialized() { 1593bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mInitialized) { 1603bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mInitialized = false; 1613bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu notifyBufferingStartEnd(); 1623bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mHasDisplay) { 1633bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPreparedStateChanged(MediaPlayerAdapter.this); 1643bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1653bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1663bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1673bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1683bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 1693bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Release internal MediaPlayer. Should not use the object after call release(). 1703bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 1713bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void release() { 1723bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu changeToUnitialized(); 1733bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mHasDisplay = false; 1743bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.release(); 1753bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1763bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1773bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 1783bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void onDetachedFromHost() { 1793bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mSurfaceHolderGlueHost != null) { 1803bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mSurfaceHolderGlueHost.setSurfaceHolderCallback(null); 1813bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mSurfaceHolderGlueHost = null; 1823bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1833bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu reset(); 1843bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu release(); 1853bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 1863bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 1873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 1883bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Called to indicate an error. 1893bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 1903bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @param what the type of error that has occurred: 1913bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <ul> 1923bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_UNKNOWN} 1933bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_SERVER_DIED} 1943bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * </ul> 1953bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @param extra an extra code, specific to the error. Typically 1963bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * implementation dependent. 1973bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <ul> 1983bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_IO} 1993bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_MALFORMED} 2003bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_UNSUPPORTED} 2013bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_ERROR_TIMED_OUT} 2023bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li><code>MEDIA_ERROR_SYSTEM (-2147483648)</code> - low-level system error. 2033bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * </ul> 2043bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @return True if the method handled the error, false if it didn't. 2053bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Returning false, will cause the {@link PlayerAdapter.Callback#onPlayCompleted(PlayerAdapter)} 2063bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * being called. 2073bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 2083bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu protected boolean onError(int what, int extra) { 2093bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return false; 2103bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2113bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2123bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 2133bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Called to indicate the completion of a seek operation. 2143bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 2153bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu protected void onSeekComplete() { 2163bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2173bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2183bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 2193bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Called to indicate an info or a warning. 2203bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 2213bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @param what the type of info or warning. 2223bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <ul> 2233bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_UNKNOWN} 2243bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_VIDEO_TRACK_LAGGING} 2253bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_VIDEO_RENDERING_START} 2263bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_BUFFERING_START} 2273bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_BUFFERING_END} 2283bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li><code>MEDIA_INFO_NETWORK_BANDWIDTH (703)</code> - 2293bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * bandwidth information is available (as <code>extra</code> kbps) 2303bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_BAD_INTERLEAVING} 2313bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_NOT_SEEKABLE} 2323bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_METADATA_UPDATE} 2333bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_UNSUPPORTED_SUBTITLE} 2343bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * <li>{@link MediaPlayer#MEDIA_INFO_SUBTITLE_TIMED_OUT} 2353bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * </ul> 2363bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @param extra an extra code, specific to the info. Typically 2373bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * implementation dependent. 2383bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @return True if the method handled the info, false if it didn't. 2393bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Returning false, will cause the info to be discarded. 2403bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 2413bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu protected boolean onInfo(int what, int extra) { 2423bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return false; 2433bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2443bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2453bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 2463bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @see MediaPlayer#setDisplay(SurfaceHolder) 2473bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 2483bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu void setDisplay(SurfaceHolder surfaceHolder) { 2493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu boolean hadDisplay = mHasDisplay; 2503bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mHasDisplay = surfaceHolder != null; 2513bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (hadDisplay == mHasDisplay) { 2523bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return; 2533bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2543bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setDisplay(surfaceHolder); 2553bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mHasDisplay) { 2563bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mInitialized) { 2573bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPreparedStateChanged(MediaPlayerAdapter.this); 2583bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2593bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } else { 2603bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mInitialized) { 2613bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPreparedStateChanged(MediaPlayerAdapter.this); 2623bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2633bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2643bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2653bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2663bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2673bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2683bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void setProgressUpdatingEnabled(final boolean enabled) { 2693bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mHandler.removeCallbacks(mRunnable); 2703bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (!enabled) { 2713bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return; 2723bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2733bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mHandler.postDelayed(mRunnable, getUpdatePeriod()); 2743bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2753bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2763bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu int getUpdatePeriod() { 2773bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return 16; 2783bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2793bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2803bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2813bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean isPlaying() { 2823bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mInitialized && mPlayer.isPlaying(); 2833bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2843bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2853bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2863bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public long getDuration() { 2873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mInitialized ? mPlayer.getDuration() : -1; 2883bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2893bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2903bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2913bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public long getCurrentPosition() { 2923bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mInitialized ? mPlayer.getCurrentPosition() : -1; 2933bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 2943bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 2953bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 2963bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void play() { 2973bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (!mInitialized || mPlayer.isPlaying()) { 2983bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return; 2993bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3003bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.start(); 3013bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPlayStateChanged(MediaPlayerAdapter.this); 3023bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onCurrentPositionChanged(MediaPlayerAdapter.this); 3033bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3043bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3053bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3063bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void pause() { 3073bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (isPlaying()) { 3083bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.pause(); 3093bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPlayStateChanged(MediaPlayerAdapter.this); 3103bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3113bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3123bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3133bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3143bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void seekTo(long newPosition) { 3153bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (!mInitialized) { 3163bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return; 3173bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3183bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.seekTo((int) newPosition); 3193bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3203bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3213bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3223bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public long getBufferedPosition() { 3233bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mBufferedProgress; 3243bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3253bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3263bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 3273bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Sets the media source of the player witha given URI. 3283bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * 3293bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @return Returns <code>true</code> if uri represents a new media; <code>false</code> 3303bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * otherwise. 3313bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @see MediaPlayer#setDataSource(String) 3323bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 3333bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean setDataSource(Uri uri) { 3343bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mMediaSourceUri != null ? mMediaSourceUri.equals(uri) : uri == null) { 3353bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return false; 3363bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3373bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mMediaSourceUri = uri; 3383bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu prepareMediaForPlaying(); 3393bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return true; 3403bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3413bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3423bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu private void prepareMediaForPlaying() { 3433bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu reset(); 3443bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu try { 3453bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu if (mMediaSourceUri != null) { 3463bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setDataSource(mContext, mMediaSourceUri); 3473bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } else { 3483bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return; 3493bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3503bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } catch (IOException e) { 3513bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu e.printStackTrace(); 3523bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu throw new RuntimeException(e); 3533bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3543bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC); 3553bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnPreparedListener(mOnPreparedListener); 3563bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnVideoSizeChangedListener(mOnVideoSizeChangedListener); 3573bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnErrorListener(mOnErrorListener); 3583bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnSeekCompleteListener(mOnSeekCompleteListener); 3593bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnCompletionListener(mOnCompletionListener); 3603bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnInfoListener(mOnInfoListener); 3613bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.setOnBufferingUpdateListener(mOnBufferingUpdateListener); 3623bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu notifyBufferingStartEnd(); 3633bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu mPlayer.prepareAsync(); 3643bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu getCallback().onPlayStateChanged(MediaPlayerAdapter.this); 3653bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3663bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3673bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 3683bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * @return True if MediaPlayer OnPreparedListener is invoked and got a SurfaceHolder if 3693bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * {@link PlaybackGlueHost} provides SurfaceHolder. 3703bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 3713bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3723bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public boolean isPrepared() { 3733bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu return mInitialized && (mSurfaceHolderGlueHost == null || mHasDisplay); 3743bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3753bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3763bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu /** 3773bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * Implements {@link SurfaceHolder.Callback} that can then be set on the 3783bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu * {@link PlaybackGlueHost}. 3793bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu */ 3803bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu class VideoPlayerSurfaceHolderCallback implements SurfaceHolder.Callback { 3813bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3823bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void surfaceCreated(SurfaceHolder surfaceHolder) { 3833bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu setDisplay(surfaceHolder); 3843bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3853bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3863bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3873bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) { 3883bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3893bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu 3903bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu @Override 3913bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu public void surfaceDestroyed(SurfaceHolder surfaceHolder) { 3923bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu setDisplay(null); 3933bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3943bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu } 3953bcad88cbf4488e747d84893c35f2351b8f84afeDake Gu} 396