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 Jun 27, 2016
1 parent d5ea4e0 commit 0160e92
Show file tree
Hide file tree
Showing 2 changed files with 138 additions and 9 deletions.
Original file line number Diff line number Diff line change
@@ -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 ExternalMediaPlayer {
private static final String TAG = "ExternalMediaPlayer";

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 @@ -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) {
ExternalMediaPlayer mediaPlayer, Context context, Uri uri) {
return false;
}

public ExternalMediaPlayer getExternalMediaPlayer() {
return null;
}
}

private static ResourceLoadingFilter sResourceLoadFilter = null;
Expand All @@ -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 ExternalMediaPlayer mPlayer;
private long mNativeMediaPlayerBridge;

@CalledByNative
Expand All @@ -78,9 +84,9 @@ protected void destroy() {
mNativeMediaPlayerBridge = 0;
}

protected MediaPlayer getLocalPlayer() {
protected ExternalMediaPlayer getLocalPlayer() {
if (mPlayer == null) {
mPlayer = new MediaPlayer();
mPlayer = sResourceLoadFilter.getExternalMediaPlayer();
}
return mPlayer;
}
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -372,7 +378,7 @@ private boolean canSeekBackward() {
*/
@CalledByNative
protected AllowedOperations getAllowedOperations() {
MediaPlayer player = getLocalPlayer();
ExternalMediaPlayer player = getLocalPlayer();
boolean canPause = true;
boolean canSeekForward = true;
boolean canSeekBackward = true;
Expand Down

0 comments on commit 0160e92

Please sign in to comment.