Skip to content
This repository has been archived by the owner on Apr 3, 2020. It is now read-only.

Commit

Permalink
[Android] Support third part media player on Crosswalk
Browse files Browse the repository at this point in the history
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
  • Loading branch information
fujunwei committed May 18, 2016
1 parent 0732335 commit b3b820f
Show file tree
Hide file tree
Showing 2 changed files with 162 additions and 32 deletions.
123 changes: 123 additions & 0 deletions media/base/android/java/src/org/chromium/media/ExMediaPlayer.java
Original file line number Diff line number Diff line change
@@ -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<String, String> 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);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -36,11 +36,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;
Expand All @@ -54,7 +61,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
Expand All @@ -78,22 +85,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;
Expand All @@ -107,7 +114,7 @@ protected boolean prepareAsync() {

@CalledByNative
protected boolean isPlaying() {
return getLocalPlayer().isPlaying();
return getExMediaPlayer().isPlaying();
}

@CalledByNative
Expand All @@ -122,7 +129,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;
Expand All @@ -144,47 +151,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
Expand All @@ -202,12 +209,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;
Expand All @@ -218,7 +225,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) {
Expand Down Expand Up @@ -294,7 +301,7 @@ protected void onPostExecute(Boolean result) {
}

try {
getLocalPlayer().setDataSource(mContext, Uri.fromFile(mTempFile));
getExMediaPlayer().setDataSource(mContext, Uri.fromFile(mTempFile));
} catch (IOException e) {
result = false;
}
Expand All @@ -315,27 +322,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 {
Expand Down Expand Up @@ -372,7 +379,7 @@ private boolean canSeekBackward() {
*/
@CalledByNative
protected AllowedOperations getAllowedOperations() {
MediaPlayer player = getLocalPlayer();
ExMediaPlayer player = getExMediaPlayer();
boolean canPause = true;
boolean canSeekForward = true;
boolean canSeekBackward = true;
Expand Down

0 comments on commit b3b820f

Please sign in to comment.