summaryrefslogtreecommitdiff
path: root/core/java/android/webkit/HTML5VideoView.java
diff options
context:
space:
mode:
Diffstat (limited to 'core/java/android/webkit/HTML5VideoView.java')
-rw-r--r--core/java/android/webkit/HTML5VideoView.java211
1 files changed, 211 insertions, 0 deletions
diff --git a/core/java/android/webkit/HTML5VideoView.java b/core/java/android/webkit/HTML5VideoView.java
new file mode 100644
index 000000000000..2312160f5c66
--- /dev/null
+++ b/core/java/android/webkit/HTML5VideoView.java
@@ -0,0 +1,211 @@
+
+package android.webkit;
+
+import android.graphics.SurfaceTexture;
+import android.media.MediaPlayer;
+import android.util.Log;
+import android.webkit.HTML5VideoViewProxy;
+import android.widget.MediaController;
+import android.opengl.GLES20;
+import java.io.IOException;
+import java.util.Map;
+
+/**
+ * @hide This is only used by the browser
+ */
+public class HTML5VideoView implements MediaPlayer.OnPreparedListener{
+ // Due to the fact that SurfaceTexture consume a lot of memory, we make it
+ // as static. m_textureNames is the texture bound with this SurfaceTexture.
+ private static SurfaceTexture mSurfaceTexture = null;
+ private static int[] mTextureNames;
+
+ // Only when the video is prepared, we render using SurfaceTexture.
+ // This in fact is used to avoid showing the obsolete content when
+ // switching videos.
+ private static boolean mReadyToUseSurfTex = false;
+
+ // For handling the seekTo before prepared, we need to know whether or not
+ // the video is prepared. Therefore, we differentiate the state between
+ // prepared and not prepared.
+ // When the video is not prepared, we will have to save the seekTo time,
+ // and use it when prepared to play.
+ private static final int STATE_NOTPREPARED = 0;
+ private static final int STATE_PREPARED = 1;
+
+ // We only need state for handling seekTo
+ private int mCurrentState;
+
+ // Basically for calling back the OnPrepared in the proxy
+ private HTML5VideoViewProxy mProxy;
+
+ // Save the seek time when not prepared. This can happen when switching
+ // video besides initial load.
+ private int mSaveSeekTime;
+
+ // This is used to find the VideoLayer on the native side.
+ private int mVideoLayerId;
+
+ // Every video will have one MediaPlayer. Given the fact we only have one
+ // SurfaceTexture, there is only one MediaPlayer in action. Every time we
+ // switch videos, a new instance of MediaPlayer will be created in reset().
+ private MediaPlayer mPlayer;
+
+ private static HTML5VideoView mInstance = new HTML5VideoView();
+
+ // Video control FUNCTIONS:
+ public void start() {
+ if (mCurrentState == STATE_PREPARED) {
+ mPlayer.start();
+ mReadyToUseSurfTex = true;
+ }
+ }
+
+ public void pause() {
+ mPlayer.pause();
+ }
+
+ public int getDuration() {
+ return mPlayer.getDuration();
+ }
+
+ public int getCurrentPosition() {
+ return mPlayer.getCurrentPosition();
+ }
+
+ public void seekTo(int pos) {
+ if (mCurrentState == STATE_PREPARED)
+ mPlayer.seekTo(pos);
+ else
+ mSaveSeekTime = pos;
+ }
+
+ public boolean isPlaying() {
+ return mPlayer.isPlaying();
+ }
+
+ public void release() {
+ mPlayer.release();
+ }
+
+ public void stopPlayback() {
+ mPlayer.stop();
+ }
+
+ private void reset(int videoLayerId) {
+ mPlayer = new MediaPlayer();
+ mCurrentState = STATE_NOTPREPARED;
+ mProxy = null;
+ mVideoLayerId = videoLayerId;
+ mReadyToUseSurfTex = false;
+ }
+
+ public static HTML5VideoView getInstance(int videoLayerId) {
+ // Every time we switch between the videos, a new MediaPlayer will be
+ // created. Make sure we call the m_player.release() when it is done.
+ mInstance.reset(videoLayerId);
+ return mInstance;
+ }
+
+ private HTML5VideoView() {
+ // This is a singleton across WebViews (i.e. Tabs).
+ // HTML5VideoViewProxy will reset the internal state every time a new
+ // video start.
+ }
+
+ public void setMediaController(MediaController m) {
+ this.setMediaController(m);
+ }
+
+ public void setVideoURI(String uri, Map<String, String> headers) {
+ // When switching players, surface texture will be reused.
+ mPlayer.setTexture(getSurfaceTextureInstance());
+
+ // When there is exception, we could just bail out silently.
+ // No Video will be played though. Write the stack for debug
+ try {
+ mPlayer.setDataSource(uri, headers);
+ mPlayer.prepareAsync();
+ } catch (IllegalArgumentException e) {
+ e.printStackTrace();
+ } catch (IllegalStateException e) {
+ e.printStackTrace();
+ } catch (IOException e) {
+ e.printStackTrace();
+ }
+ }
+
+ // TODO [FULL SCREEN SUPPORT]
+
+ // Listeners setup FUNCTIONS:
+ public void setOnCompletionListener(HTML5VideoViewProxy proxy) {
+ mPlayer.setOnCompletionListener(proxy);
+ }
+
+ public void setOnErrorListener(HTML5VideoViewProxy proxy) {
+ mPlayer.setOnErrorListener(proxy);
+ }
+
+ public void setOnPreparedListener(HTML5VideoViewProxy proxy) {
+ mProxy = proxy;
+ mPlayer.setOnPreparedListener(this);
+ }
+
+ // Inline Video specific FUNCTIONS:
+
+ public SurfaceTexture getSurfaceTexture() {
+ return mSurfaceTexture;
+ }
+
+ public void deleteSurfaceTexture() {
+ mSurfaceTexture = null;
+ return;
+ }
+
+ // SurfaceTexture is a singleton here , too
+ private SurfaceTexture getSurfaceTextureInstance() {
+ // Create the surface texture.
+ if (mSurfaceTexture == null)
+ {
+ mTextureNames = new int[1];
+ GLES20.glGenTextures(1, mTextureNames, 0);
+ mSurfaceTexture = new SurfaceTexture(mTextureNames[0]);
+ }
+ return mSurfaceTexture;
+ }
+
+ public int getTextureName() {
+ return mTextureNames[0];
+ }
+
+ public int getVideoLayerId() {
+ return mVideoLayerId;
+ }
+
+ public boolean getReadyToUseSurfTex() {
+ return mReadyToUseSurfTex;
+ }
+
+ public void setFrameAvailableListener(SurfaceTexture.OnFrameAvailableListener l) {
+ mSurfaceTexture.setOnFrameAvailableListener(l);
+ }
+
+ @Override
+ public void onPrepared(MediaPlayer mp) {
+ mCurrentState = STATE_PREPARED;
+ seekTo(mSaveSeekTime);
+ if (mProxy != null)
+ mProxy.onPrepared(mp);
+ }
+
+ // Pause the play and update the play/pause button
+ public void pauseAndDispatch(HTML5VideoViewProxy proxy) {
+ if (isPlaying()) {
+ pause();
+ if (proxy != null) {
+ proxy.dispatchOnPaused();
+ }
+ }
+ mReadyToUseSurfTex = false;
+ }
+
+}