From c1a63a39459c4066d05a54b06a0760dc1e4685bc Mon Sep 17 00:00:00 2001 From: fujunwei Date: Tue, 17 May 2016 09:18:27 +0800 Subject: [PATCH] [Android] Support third part media player on Crosswalk A requirement from an important customer who want to forward web resources with proxy on Crosswalk, but android system MediaPlayer can't set a proxy with a standard API. The ExoMediaPlayer is playing videos and music is a popular activity on Android devices, and it can be configured with proxy. https://developer.android.com/guide/topics/media/exoplayer.html BUG=XWALK-6770 --- .../src/org/chromium/media/ExMediaPlayer.java | 123 ++++++++++++++++++ .../org/chromium/media/MediaPlayerBridge.java | 72 +++++----- 2 files changed, 162 insertions(+), 33 deletions(-) create mode 100644 media/base/android/java/src/org/chromium/media/ExMediaPlayer.java diff --git a/media/base/android/java/src/org/chromium/media/ExMediaPlayer.java b/media/base/android/java/src/org/chromium/media/ExMediaPlayer.java new file mode 100644 index 0000000000000..cb01cf62d67f2 --- /dev/null +++ b/media/base/android/java/src/org/chromium/media/ExMediaPlayer.java @@ -0,0 +1,123 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +package org.chromium.media; + +import android.content.Context; +import android.media.MediaPlayer; +import android.media.MediaPlayer.TrackInfo; +import android.net.Uri; +import android.view.Surface; + +import org.chromium.base.Log; + +import java.io.FileDescriptor; +import java.io.IOException; +import java.util.Map; + +/** +* Use Android system MediaPlayer by default. +*/ +public class ExMediaPlayer { + private static final String TAG = "ExMediaPlayer"; + + private MediaPlayer mPlayer; + + protected MediaPlayer getLocalPlayer() { + if (mPlayer == null) { + mPlayer = new MediaPlayer(); + Log.d(TAG, "Create a Android System Media Player"); + } + return mPlayer; + } + + public void setSurface(Surface surface) { + getLocalPlayer().setSurface(surface); + } + + public void setDataSource(Context context, Uri uri, Map headers) + throws Exception { + getLocalPlayer().setDataSource(context, uri, headers); + } + + public void setDataSource(FileDescriptor fd, long offset, long length) throws IOException { + getLocalPlayer().setDataSource(fd, offset, length); + } + + public void setDataSource(Context context, Uri uri) throws IOException { + getLocalPlayer().setDataSource(context, uri); + } + + public void prepareAsync() throws IllegalStateException { + getLocalPlayer().prepareAsync(); + } + + public TrackInfo[] getTrackInfo() throws RuntimeException { + return getLocalPlayer().getTrackInfo(); + } + + public boolean isPlaying() { + return getLocalPlayer().isPlaying(); + } + + public int getVideoWidth() { + return getLocalPlayer().getVideoWidth(); + } + + public int getVideoHeight() { + return getLocalPlayer().getVideoHeight(); + } + + public int getCurrentPosition() { + return getLocalPlayer().getCurrentPosition(); + } + + public int getDuration() { + return getLocalPlayer().getDuration(); + } + + public void release() { + getLocalPlayer().release(); + } + + public void setVolume(float volume1, float volume2) { + getLocalPlayer().setVolume((float) volume1, (float) volume2); + } + + public void start() { + getLocalPlayer().start(); + } + + public void pause() { + getLocalPlayer().pause(); + } + + public void seekTo(int msec) { + getLocalPlayer().seekTo(msec); + } + + public void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) { + getLocalPlayer().setOnBufferingUpdateListener(listener); + } + + public void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) { + getLocalPlayer().setOnCompletionListener(listener); + } + + public void setOnErrorListener(MediaPlayer.OnErrorListener listener) { + getLocalPlayer().setOnErrorListener(listener); + } + + public void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) { + getLocalPlayer().setOnPreparedListener(listener); + } + + public void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener) { + getLocalPlayer().setOnSeekCompleteListener(listener); + } + + public void setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener) { + getLocalPlayer().setOnVideoSizeChangedListener(listener); + } +} diff --git a/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java b/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java index 830cc20049210..26e3a423e3f7b 100644 --- a/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java +++ b/media/base/android/java/src/org/chromium/media/MediaPlayerBridge.java @@ -35,12 +35,18 @@ */ @JNINamespace("media") public class MediaPlayerBridge { - + /** + * Give the host application a chance to take over MeidaPlayer. + */ public static class ResourceLoadingFilter { public boolean shouldOverrideResourceLoading( - MediaPlayer mediaPlayer, Context context, Uri uri) { + ExMediaPlayer mediaPlayer, Context context, Uri uri) { return false; } + + public ExMediaPlayer getExMediaPlayer() { + return null; + } } private static ResourceLoadingFilter sResourceLoadFilter = null; @@ -54,7 +60,7 @@ public static void setResourceLoadingFilter(ResourceLoadingFilter filter) { // Local player to forward this to. We don't initialize it here since the subclass might not // want it. private LoadDataUriTask mLoadDataUriTask; - private MediaPlayer mPlayer; + private ExMediaPlayer mExMediaPlayer; private long mNativeMediaPlayerBridge; @CalledByNative @@ -78,22 +84,22 @@ protected void destroy() { mNativeMediaPlayerBridge = 0; } - protected MediaPlayer getLocalPlayer() { - if (mPlayer == null) { - mPlayer = new MediaPlayer(); + protected ExMediaPlayer getExMediaPlayer() { + if (mExMediaPlayer == null) { + mExMediaPlayer = sResourceLoadFilter.getExMediaPlayer(); } - return mPlayer; + return mExMediaPlayer; } @CalledByNative protected void setSurface(Surface surface) { - getLocalPlayer().setSurface(surface); + getExMediaPlayer().setSurface(surface); } @CalledByNative protected boolean prepareAsync() { try { - getLocalPlayer().prepareAsync(); + getExMediaPlayer().prepareAsync(); } catch (IllegalStateException ise) { Log.e(TAG, "Unable to prepare MediaPlayer.", ise); return false; @@ -107,7 +113,7 @@ protected boolean prepareAsync() { @CalledByNative protected boolean isPlaying() { - return getLocalPlayer().isPlaying(); + return getExMediaPlayer().isPlaying(); } @CalledByNative @@ -122,7 +128,7 @@ protected boolean hasAudio() { private boolean hasTrack(int trackType) { try { - TrackInfo trackInfo[] = getLocalPlayer().getTrackInfo(); + TrackInfo trackInfo[] = getExMediaPlayer().getTrackInfo(); // HLS media does not have the track info, so we treat them conservatively. if (trackInfo.length == 0) return true; @@ -144,47 +150,47 @@ private boolean hasTrack(int trackType) { @CalledByNative protected int getVideoWidth() { - return getLocalPlayer().getVideoWidth(); + return getExMediaPlayer().getVideoWidth(); } @CalledByNative protected int getVideoHeight() { - return getLocalPlayer().getVideoHeight(); + return getExMediaPlayer().getVideoHeight(); } @CalledByNative protected int getCurrentPosition() { - return getLocalPlayer().getCurrentPosition(); + return getExMediaPlayer().getCurrentPosition(); } @CalledByNative protected int getDuration() { - return getLocalPlayer().getDuration(); + return getExMediaPlayer().getDuration(); } @CalledByNative protected void release() { - getLocalPlayer().release(); + getExMediaPlayer().release(); } @CalledByNative protected void setVolume(double volume) { - getLocalPlayer().setVolume((float) volume, (float) volume); + getExMediaPlayer().setVolume((float) volume, (float) volume); } @CalledByNative protected void start() { - getLocalPlayer().start(); + getExMediaPlayer().start(); } @CalledByNative protected void pause() { - getLocalPlayer().pause(); + getExMediaPlayer().pause(); } @CalledByNative protected void seekTo(int msec) throws IllegalStateException { - getLocalPlayer().seekTo(msec); + getExMediaPlayer().seekTo(msec); } @CalledByNative @@ -202,12 +208,12 @@ protected boolean setDataSource( headersMap.put("allow-cross-domain-redirect", "false"); } try { - if (sResourceLoadFilter != null && - sResourceLoadFilter.shouldOverrideResourceLoading( - getLocalPlayer(), context, uri)) { + if (sResourceLoadFilter != null + && sResourceLoadFilter.shouldOverrideResourceLoading( + getExMediaPlayer(), context, uri)) { return true; } - getLocalPlayer().setDataSource(context, uri, headersMap); + getExMediaPlayer().setDataSource(context, uri, headersMap); return true; } catch (Exception e) { return false; @@ -218,7 +224,7 @@ protected boolean setDataSource( protected boolean setDataSourceFromFd(int fd, long offset, long length) { try { ParcelFileDescriptor parcelFd = ParcelFileDescriptor.adoptFd(fd); - getLocalPlayer().setDataSource(parcelFd.getFileDescriptor(), offset, length); + getExMediaPlayer().setDataSource(parcelFd.getFileDescriptor(), offset, length); parcelFd.close(); return true; } catch (IOException e) { @@ -294,7 +300,7 @@ protected void onPostExecute(Boolean result) { } try { - getLocalPlayer().setDataSource(mContext, Uri.fromFile(mTempFile)); + getExMediaPlayer().setDataSource(mContext, Uri.fromFile(mTempFile)); } catch (IOException e) { result = false; } @@ -315,27 +321,27 @@ private void deleteFile() { } protected void setOnBufferingUpdateListener(MediaPlayer.OnBufferingUpdateListener listener) { - getLocalPlayer().setOnBufferingUpdateListener(listener); + getExMediaPlayer().setOnBufferingUpdateListener(listener); } protected void setOnCompletionListener(MediaPlayer.OnCompletionListener listener) { - getLocalPlayer().setOnCompletionListener(listener); + getExMediaPlayer().setOnCompletionListener(listener); } protected void setOnErrorListener(MediaPlayer.OnErrorListener listener) { - getLocalPlayer().setOnErrorListener(listener); + getExMediaPlayer().setOnErrorListener(listener); } protected void setOnPreparedListener(MediaPlayer.OnPreparedListener listener) { - getLocalPlayer().setOnPreparedListener(listener); + getExMediaPlayer().setOnPreparedListener(listener); } protected void setOnSeekCompleteListener(MediaPlayer.OnSeekCompleteListener listener) { - getLocalPlayer().setOnSeekCompleteListener(listener); + getExMediaPlayer().setOnSeekCompleteListener(listener); } protected void setOnVideoSizeChangedListener(MediaPlayer.OnVideoSizeChangedListener listener) { - getLocalPlayer().setOnVideoSizeChangedListener(listener); + getExMediaPlayer().setOnVideoSizeChangedListener(listener); } protected static class AllowedOperations { @@ -372,7 +378,7 @@ private boolean canSeekBackward() { */ @CalledByNative protected AllowedOperations getAllowedOperations() { - MediaPlayer player = getLocalPlayer(); + ExMediaPlayer player = getExMediaPlayer(); boolean canPause = true; boolean canSeekForward = true; boolean canSeekBackward = true;