1661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 2661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhupackage android.webkit; 3661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 4661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.graphics.SurfaceTexture; 5661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.media.MediaPlayer; 664855da755e74676af49b3c7ece338acd72b2f3cTeng-Hui Zhuimport android.net.Uri; 7661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.util.Log; 810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.SurfaceView; 9661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.webkit.HTML5VideoViewProxy; 10661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.io.IOException; 1110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.HashMap; 12661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.util.Map; 1310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.Timer; 1410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.TimerTask; 15661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 16661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu/** 17661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu * @hide This is only used by the browser 18661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu */ 19a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhupublic class HTML5VideoView implements MediaPlayer.OnPreparedListener { 20661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 2110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String LOGTAG = "HTML5VideoView"; 2210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 2310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String COOKIE = "Cookie"; 2410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String HIDE_URL_LOGS = "x-hide-urls-from-log"; 25661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 26661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // For handling the seekTo before prepared, we need to know whether or not 27661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // the video is prepared. Therefore, we differentiate the state between 28661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // prepared and not prepared. 29661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // When the video is not prepared, we will have to save the seekTo time, 30661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // and use it when prepared to play. 31265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu // NOTE: these values are in sync with VideoLayerAndroid.h in webkit side. 32265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu // Please keep them in sync when changed. 33265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_INITIALIZED = 0; 34265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_NOTPREPARED = 1; 35265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_PREPARED = 2; 36265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_PLAYING = 3; 37b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu static final int STATE_RELEASED = 4; 3810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mCurrentState; 39661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 4010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected HTML5VideoViewProxy mProxy; 41661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 42661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Save the seek time when not prepared. This can happen when switching 43661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // video besides initial load. 4410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mSaveSeekTime; 45661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 46661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // This is used to find the VideoLayer on the native side. 4710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mVideoLayerId; 48661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 49661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Every video will have one MediaPlayer. Given the fact we only have one 50661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // SurfaceTexture, there is only one MediaPlayer in action. Every time we 51661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // switch videos, a new instance of MediaPlayer will be created in reset(). 5210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Switching between inline and full screen will also create a new instance. 5310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected MediaPlayer mPlayer; 5410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 5510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // This will be set up every time we create the Video View object. 5610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Set to true only when switching into full screen while playing 5710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected boolean mAutostart; 5810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 5910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // We need to save such info. 6064855da755e74676af49b3c7ece338acd72b2f3cTeng-Hui Zhu protected Uri mUri; 6110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected Map<String, String> mHeaders; 62661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 6310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // The timer for timeupate events. 6410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate 6510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static Timer mTimer; 66661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 6710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // The spec says the timer should fire every 250 ms or less. 6810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private static final int TIMEUPDATE_PERIOD = 250; // ms 6910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 70158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu protected boolean mPauseDuringPreparing; 7110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // common Video control FUNCTIONS: 72661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void start() { 73661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 74cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // When replaying the same video, there is no onPrepared call. 75cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // Therefore, the timer should be set up here. 76cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu if (mTimer == null) 77cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu { 78cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = new Timer(); 79cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer.schedule(new TimeupdateTask(mProxy), TIMEUPDATE_PERIOD, 80cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu TIMEUPDATE_PERIOD); 81cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu } 82661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.start(); 832fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu setPlayerBuffering(false); 84661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 85661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 86661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 87661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void pause() { 88b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu if (isPlaying()) { 8910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.pause(); 90158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } else if (mCurrentState == STATE_NOTPREPARED) { 91158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = true; 9210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 93cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // Delete the Timer to stop it since there is no stop call. 9410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mTimer != null) { 9510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mTimer.purge(); 96cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer.cancel(); 97cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = null; 9810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 99661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 100661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 101661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getDuration() { 10210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 10310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mPlayer.getDuration(); 10410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } else { 10510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return -1; 10610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 107661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 108661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 109661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getCurrentPosition() { 11010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 11110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mPlayer.getCurrentPosition(); 11210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 11310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return 0; 114661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 115661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 116661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void seekTo(int pos) { 117661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) 118661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.seekTo(pos); 119661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu else 120661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mSaveSeekTime = pos; 121661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 122661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 123661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public boolean isPlaying() { 124b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 125b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu return mPlayer.isPlaying(); 126b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu } else { 127b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu return false; 128b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu } 129661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 130661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 131661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void release() { 132b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu if (mCurrentState != STATE_RELEASED) { 133b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu mPlayer.release(); 134b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu } 135b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu mCurrentState = STATE_RELEASED; 136661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 137661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 138661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void stopPlayback() { 13910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 14010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.stop(); 14110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 142661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 143661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 14410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean getAutostart() { 14510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mAutostart; 14610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 14710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 148158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu public boolean getPauseDuringPreparing() { 149158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu return mPauseDuringPreparing; 150158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } 151158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu 15210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Every time we start a new Video, we create a VideoView and a MediaPlayer 15310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void init(int videoLayerId, int position, boolean autoStart) { 154661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer = new MediaPlayer(); 155265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu mCurrentState = STATE_INITIALIZED; 156661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy = null; 157661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mVideoLayerId = videoLayerId; 15810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mSaveSeekTime = position; 15910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mAutostart = autoStart; 160cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = null; 161158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = false; 162661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 163661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 16410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected HTML5VideoView() { 165661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 166661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 16710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static Map<String, String> generateHeaders(String url, 16810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu HTML5VideoViewProxy proxy) { 16910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu boolean isPrivate = proxy.getWebView().isPrivateBrowsingEnabled(); 17010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate); 17110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu Map<String, String> headers = new HashMap<String, String>(); 17210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (cookieValue != null) { 17310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu headers.put(COOKIE, cookieValue); 17410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 17510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (isPrivate) { 17610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu headers.put(HIDE_URL_LOGS, "true"); 17710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 178661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 17910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return headers; 180661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 181661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 18210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void setVideoURI(String uri, HTML5VideoViewProxy proxy) { 183661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // When switching players, surface texture will be reused. 18464855da755e74676af49b3c7ece338acd72b2f3cTeng-Hui Zhu mUri = Uri.parse(uri); 18510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mHeaders = generateHeaders(uri, proxy); 186661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 187661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 188661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Listeners setup FUNCTIONS: 189661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnCompletionListener(HTML5VideoViewProxy proxy) { 190661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnCompletionListener(proxy); 191661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 192661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 193661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnErrorListener(HTML5VideoViewProxy proxy) { 194661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnErrorListener(proxy); 195661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 196661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 197661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnPreparedListener(HTML5VideoViewProxy proxy) { 198661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy = proxy; 199661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnPreparedListener(this); 200661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 201661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 202a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu public void setOnInfoListener(HTML5VideoViewProxy proxy) { 203a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu mPlayer.setOnInfoListener(proxy); 204a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu } 205a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu 20610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Normally called immediately after setVideoURI. But for full screen, 20710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // this should be after surface holder created 20810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void prepareDataAndDisplayMode(HTML5VideoViewProxy proxy) { 20910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // SurfaceTexture will be created lazily here for inline mode 21010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu decideDisplayMode(); 211661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 21210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnCompletionListener(proxy); 21310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnPreparedListener(proxy); 21410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnErrorListener(proxy); 215a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu setOnInfoListener(proxy); 21610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // When there is exception, we could just bail out silently. 21710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // No Video will be played though. Write the stack for debug 21810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu try { 21964855da755e74676af49b3c7ece338acd72b2f3cTeng-Hui Zhu mPlayer.setDataSource(mProxy.getContext(), mUri, mHeaders); 22010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.prepareAsync(); 22110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IllegalArgumentException e) { 22210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 22310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IllegalStateException e) { 22410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 22510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IOException e) { 22610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 227661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 228265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu mCurrentState = STATE_NOTPREPARED; 229661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 230661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 231661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 23210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Common code 233661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getVideoLayerId() { 234661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu return mVideoLayerId; 235661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 236661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 237265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu 238265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu public int getCurrentState() { 239b1c2c1e3c7bde3c40d7510fbda4ef8112396dd22Teng-Hui Zhu if (isPlaying()) { 240265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu return STATE_PLAYING; 241265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } else { 242265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu return mCurrentState; 243265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } 244265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } 245265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu 24610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private static final class TimeupdateTask extends TimerTask { 24710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private HTML5VideoViewProxy mProxy; 248661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 24910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public TimeupdateTask(HTML5VideoViewProxy proxy) { 25010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mProxy = proxy; 25110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 25210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 25310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu @Override 25410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void run() { 25510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mProxy.onTimeupdate(); 25610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 257661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 258661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 259661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu @Override 260661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void onPrepared(MediaPlayer mp) { 261661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mCurrentState = STATE_PREPARED; 262661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu seekTo(mSaveSeekTime); 263cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu if (mProxy != null) { 264661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy.onPrepared(mp); 265cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu } 266158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu if (mPauseDuringPreparing) { 267158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu pauseAndDispatch(mProxy); 268158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = false; 269158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } 270661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 271661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 272661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Pause the play and update the play/pause button 273661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void pauseAndDispatch(HTML5VideoViewProxy proxy) { 274158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu pause(); 275158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu if (proxy != null) { 276158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu proxy.dispatchOnPaused(); 277661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 27810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 27910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 28010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Below are functions that are different implementation on inline and full- 28110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // screen mode. Some are specific to one type, but currently are called 28210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // directly from the proxy. 28310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void enterFullScreenVideoState(int layerId, 28410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu HTML5VideoViewProxy proxy, WebView webView) { 28510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 28610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 28710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean isFullScreenMode() { 28810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return false; 28910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 29010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 29110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void decideDisplayMode() { 29210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 29310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 29410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean getReadyToUseSurfTex() { 29510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return false; 29610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 29710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 2983fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu public SurfaceTexture getSurfaceTexture(int videoLayerId) { 29910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return null; 30010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 30110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 30210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void deleteSurfaceTexture() { 30310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 30410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 30510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public int getTextureName() { 30610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return 0; 307661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 308661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 3092fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu // This is true only when the player is buffering and paused 3102fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu public boolean mPlayerBuffering = false; 3112fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu 3122fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu public boolean getPlayerBuffering() { 3132fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu return mPlayerBuffering; 3142fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu } 3152fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu 3162fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu public void setPlayerBuffering(boolean playerBuffering) { 3172fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu mPlayerBuffering = playerBuffering; 3182fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu switchProgressView(playerBuffering); 3192fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu } 3202fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu 3212fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu 3222fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu protected void switchProgressView(boolean playerBuffering) { 3232fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu // Only used in HTML5VideoFullScreen 3242fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu } 3252fcf82aee30da977849adaaadf89d81c17afbac2Teng-Hui Zhu 3263fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu public boolean surfaceTextureDeleted() { 3273fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu // Only meaningful for HTML5VideoInline 3283fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu return false; 3293fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu } 3303fafd39d0776a15c3613795183043a2c28277691Teng-Hui Zhu 3311a88acbed9cd04d7c8ddd0c33a15926238157a07Teng-Hui Zhu public boolean fullScreenExited() { 3321a88acbed9cd04d7c8ddd0c33a15926238157a07Teng-Hui Zhu // Only meaningful for HTML5VideoFullScreen 3331a88acbed9cd04d7c8ddd0c33a15926238157a07Teng-Hui Zhu return false; 3341a88acbed9cd04d7c8ddd0c33a15926238157a07Teng-Hui Zhu } 3351a88acbed9cd04d7c8ddd0c33a15926238157a07Teng-Hui Zhu 336661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu} 337