From 05d75eb372465f0a5b0af8bcd3924a36f4230cea 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 | 24 ++-- 2 files changed, 138 insertions(+), 9 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..72c4789581434 --- /dev/null +++ b/media/base/android/java/src/org/chromium/media/ExMediaPlayer.java @@ -0,0 +1,123 @@ +// Copyright 2016 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..5c89b8c06c976 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 mPlayer; private long mNativeMediaPlayerBridge; @CalledByNative @@ -78,9 +84,9 @@ protected void destroy() { mNativeMediaPlayerBridge = 0; } - protected MediaPlayer getLocalPlayer() { + protected ExMediaPlayer getLocalPlayer() { if (mPlayer == null) { - mPlayer = new MediaPlayer(); + mPlayer = sResourceLoadFilter.getExMediaPlayer(); } return mPlayer; } @@ -202,9 +208,9 @@ protected boolean setDataSource( headersMap.put("allow-cross-domain-redirect", "false"); } try { - if (sResourceLoadFilter != null && - sResourceLoadFilter.shouldOverrideResourceLoading( - getLocalPlayer(), context, uri)) { + if (sResourceLoadFilter != null + && sResourceLoadFilter.shouldOverrideResourceLoading( + getLocalPlayer(), context, uri)) { return true; } getLocalPlayer().setDataSource(context, uri, headersMap); @@ -372,7 +378,7 @@ private boolean canSeekBackward() { */ @CalledByNative protected AllowedOperations getAllowedOperations() { - MediaPlayer player = getLocalPlayer(); + ExMediaPlayer player = getLocalPlayer(); boolean canPause = true; boolean canSeekForward = true; boolean canSeekBackward = true;