HTML5VideoView.java revision a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3
1661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 2661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhupackage android.webkit; 3661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 4661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.graphics.SurfaceTexture; 5661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.media.MediaPlayer; 6661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.util.Log; 710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport android.view.SurfaceView; 8661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport android.webkit.HTML5VideoViewProxy; 9661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.io.IOException; 1010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.HashMap; 11661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhuimport java.util.Map; 1210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.Timer; 1310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhuimport java.util.TimerTask; 14661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 15661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu/** 16661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu * @hide This is only used by the browser 17661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu */ 18a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhupublic class HTML5VideoView implements MediaPlayer.OnPreparedListener { 19661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 2010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String LOGTAG = "HTML5VideoView"; 2110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 2210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String COOKIE = "Cookie"; 2310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static final String HIDE_URL_LOGS = "x-hide-urls-from-log"; 24661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 25661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // For handling the seekTo before prepared, we need to know whether or not 26661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // the video is prepared. Therefore, we differentiate the state between 27661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // prepared and not prepared. 28661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // When the video is not prepared, we will have to save the seekTo time, 29661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // and use it when prepared to play. 30265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu // NOTE: these values are in sync with VideoLayerAndroid.h in webkit side. 31265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu // Please keep them in sync when changed. 32265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_INITIALIZED = 0; 33265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_NOTPREPARED = 1; 34265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_PREPARED = 2; 35265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu static final int STATE_PLAYING = 3; 3610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mCurrentState; 37661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 3810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected HTML5VideoViewProxy mProxy; 39661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 40661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Save the seek time when not prepared. This can happen when switching 41661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // video besides initial load. 4210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mSaveSeekTime; 43661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 44661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // This is used to find the VideoLayer on the native side. 4510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected int mVideoLayerId; 46661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 47661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Every video will have one MediaPlayer. Given the fact we only have one 48661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // SurfaceTexture, there is only one MediaPlayer in action. Every time we 49661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // switch videos, a new instance of MediaPlayer will be created in reset(). 5010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Switching between inline and full screen will also create a new instance. 5110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected MediaPlayer mPlayer; 5210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 5310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // This will be set up every time we create the Video View object. 5410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Set to true only when switching into full screen while playing 5510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected boolean mAutostart; 5610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 5710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // We need to save such info. 5810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected String mUri; 5910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected Map<String, String> mHeaders; 60661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 6110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // The timer for timeupate events. 6210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // See http://www.whatwg.org/specs/web-apps/current-work/#event-media-timeupdate 6310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static Timer mTimer; 64661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 6510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // The spec says the timer should fire every 250 ms or less. 6610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private static final int TIMEUPDATE_PERIOD = 250; // ms 6710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 68158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu protected boolean mPauseDuringPreparing; 6910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // common Video control FUNCTIONS: 70661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void start() { 71661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 72cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // When replaying the same video, there is no onPrepared call. 73cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // Therefore, the timer should be set up here. 74cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu if (mTimer == null) 75cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu { 76cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = new Timer(); 77cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer.schedule(new TimeupdateTask(mProxy), TIMEUPDATE_PERIOD, 78cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu TIMEUPDATE_PERIOD); 79cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu } 80661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.start(); 81661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 82661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 83661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 84661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void pause() { 8510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED && mPlayer.isPlaying()) { 8610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.pause(); 87158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } else if (mCurrentState == STATE_NOTPREPARED) { 88158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = true; 8910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 90cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu // Delete the Timer to stop it since there is no stop call. 9110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mTimer != null) { 9210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mTimer.purge(); 93cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer.cancel(); 94cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = null; 9510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 96661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 97661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 98661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getDuration() { 9910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 10010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mPlayer.getDuration(); 10110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } else { 10210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return -1; 10310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 104661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 105661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 106661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getCurrentPosition() { 10710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 10810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mPlayer.getCurrentPosition(); 10910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 11010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return 0; 111661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 112661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 113661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void seekTo(int pos) { 114661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) 115661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.seekTo(pos); 116661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu else 117661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mSaveSeekTime = pos; 118661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 119661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 120661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public boolean isPlaying() { 121661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu return mPlayer.isPlaying(); 122661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 123661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 124661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void release() { 125661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.release(); 126661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 127661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 128661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void stopPlayback() { 12910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (mCurrentState == STATE_PREPARED) { 13010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.stop(); 13110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 132661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 133661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 13410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean getAutostart() { 13510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return mAutostart; 13610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 13710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 138158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu public boolean getPauseDuringPreparing() { 139158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu return mPauseDuringPreparing; 140158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } 141158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu 14210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Every time we start a new Video, we create a VideoView and a MediaPlayer 14310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void init(int videoLayerId, int position, boolean autoStart) { 144661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer = new MediaPlayer(); 145265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu mCurrentState = STATE_INITIALIZED; 146661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy = null; 147661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mVideoLayerId = videoLayerId; 14810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mSaveSeekTime = position; 14910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mAutostart = autoStart; 150cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu mTimer = null; 151158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = false; 152661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 153661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 15410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected HTML5VideoView() { 155661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 156661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 15710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu protected static Map<String, String> generateHeaders(String url, 15810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu HTML5VideoViewProxy proxy) { 15910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu boolean isPrivate = proxy.getWebView().isPrivateBrowsingEnabled(); 16010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu String cookieValue = CookieManager.getInstance().getCookie(url, isPrivate); 16110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu Map<String, String> headers = new HashMap<String, String>(); 16210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (cookieValue != null) { 16310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu headers.put(COOKIE, cookieValue); 16410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 16510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu if (isPrivate) { 16610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu headers.put(HIDE_URL_LOGS, "true"); 16710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 168661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 16910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return headers; 170661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 171661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 17210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void setVideoURI(String uri, HTML5VideoViewProxy proxy) { 173661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // When switching players, surface texture will be reused. 17410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mUri = uri; 17510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mHeaders = generateHeaders(uri, proxy); 176661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 177661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 178661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Listeners setup FUNCTIONS: 179661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnCompletionListener(HTML5VideoViewProxy proxy) { 180661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnCompletionListener(proxy); 181661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 182661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 183661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnErrorListener(HTML5VideoViewProxy proxy) { 184661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnErrorListener(proxy); 185661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 186661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 187661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void setOnPreparedListener(HTML5VideoViewProxy proxy) { 188661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy = proxy; 189661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mPlayer.setOnPreparedListener(this); 190661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 191661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 192a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu public void setOnInfoListener(HTML5VideoViewProxy proxy) { 193a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu mPlayer.setOnInfoListener(proxy); 194a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu } 195a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu 19610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Normally called immediately after setVideoURI. But for full screen, 19710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // this should be after surface holder created 19810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void prepareDataAndDisplayMode(HTML5VideoViewProxy proxy) { 19910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // SurfaceTexture will be created lazily here for inline mode 20010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu decideDisplayMode(); 201661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 20210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnCompletionListener(proxy); 20310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnPreparedListener(proxy); 20410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu setOnErrorListener(proxy); 205a9cadefde4d5f79a0f3ed093bb96d9c919ce65c3Teng-Hui Zhu setOnInfoListener(proxy); 20610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // When there is exception, we could just bail out silently. 20710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // No Video will be played though. Write the stack for debug 20810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu try { 20910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.setDataSource(mUri, mHeaders); 21010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mPlayer.prepareAsync(); 21110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IllegalArgumentException e) { 21210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 21310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IllegalStateException e) { 21410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 21510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } catch (IOException e) { 21610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu e.printStackTrace(); 217661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 218265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu mCurrentState = STATE_NOTPREPARED; 219661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 220661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 221661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 22210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Common code 223661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public int getVideoLayerId() { 224661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu return mVideoLayerId; 225661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 226661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 227265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu 228265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu public int getCurrentState() { 229265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu if (mPlayer.isPlaying()) { 230265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu return STATE_PLAYING; 231265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } else { 232265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu return mCurrentState; 233265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } 234265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu } 235265db32f31a9db60d4a93d59befa07c825cbe4f2Teng-Hui Zhu 23610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private static final class TimeupdateTask extends TimerTask { 23710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu private HTML5VideoViewProxy mProxy; 238661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 23910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public TimeupdateTask(HTML5VideoViewProxy proxy) { 24010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mProxy = proxy; 24110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 24210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 24310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu @Override 24410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void run() { 24510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu mProxy.onTimeupdate(); 24610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 247661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 248661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 249661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu @Override 250661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void onPrepared(MediaPlayer mp) { 251661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mCurrentState = STATE_PREPARED; 252661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu seekTo(mSaveSeekTime); 253cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu if (mProxy != null) { 254661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu mProxy.onPrepared(mp); 255cd445624556d8bd83313fed56388d4e6939ac5e9Teng-Hui Zhu } 256158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu if (mPauseDuringPreparing) { 257158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu pauseAndDispatch(mProxy); 258158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu mPauseDuringPreparing = false; 259158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu } 260661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 261661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 262661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu // Pause the play and update the play/pause button 263661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu public void pauseAndDispatch(HTML5VideoViewProxy proxy) { 264158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu pause(); 265158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu if (proxy != null) { 266158fbdb29b8fdda57f942ec2056d908714c326beTeng-Hui Zhu proxy.dispatchOnPaused(); 267661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 26810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 26910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 27010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // Below are functions that are different implementation on inline and full- 27110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // screen mode. Some are specific to one type, but currently are called 27210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu // directly from the proxy. 27310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void enterFullScreenVideoState(int layerId, 27410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu HTML5VideoViewProxy proxy, WebView webView) { 27510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 27610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 27710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean isFullScreenMode() { 27810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return false; 27910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 28010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 28110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void decideDisplayMode() { 28210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 28310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 28410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public boolean getReadyToUseSurfTex() { 28510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return false; 28610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 28710ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 28810ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public SurfaceTexture getSurfaceTexture() { 28910ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return null; 29010ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 29110ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 29210ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public void deleteSurfaceTexture() { 29310ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu } 29410ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu 29510ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu public int getTextureName() { 29610ab654943b386c0816a33dbd639c3b8d6260b01Teng-Hui Zhu return 0; 297661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu } 298661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu 299661e8b1f21f03ea429ff34f8fdb58b68a5049092Teng-Hui Zhu} 300