diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java index 30ca1acb..8aeb0e84 100644 --- a/src/android/AudioPlayer.java +++ b/src/android/AudioPlayer.java @@ -23,6 +23,7 @@ Licensed to the Apache Software Foundation (ASF) under one import android.media.MediaPlayer.OnCompletionListener; import android.media.MediaPlayer.OnErrorListener; import android.media.MediaPlayer.OnPreparedListener; +import android.media.MediaPlayer.OnBufferingUpdateListener; import android.media.MediaRecorder; import android.os.Environment; import android.util.Log; @@ -40,7 +41,7 @@ Licensed to the Apache Software Foundation (ASF) under one * android_asset: file name must start with /android_asset/sound.mp3 * sdcard: file name is just sound.mp3 */ -public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener { +public class AudioPlayer implements OnCompletionListener, OnPreparedListener, OnErrorListener, OnBufferingUpdateListener { // AudioPlayer modes public enum MODE { NONE, PLAY, RECORD }; @@ -84,6 +85,8 @@ public enum STATE { MEDIA_NONE, private boolean prepareOnly = true; // playback after file prepare flag private int seekOnPrepared = 0; // seek to this location once media is prepared + private int buffered = 0; // Buffered percentage + /** * Constructor. * @@ -276,6 +279,16 @@ public void onCompletion(MediaPlayer player) { this.setState(STATE.MEDIA_STOPPED); } + /** + * Callback to be invoked when progress has been made on buffering media source + * + * @param player The MediaPlayer that has made progress + * @param percent Buffered percentage + */ + public void onBufferingUpdate(MediaPlayer player, int percent) { + this.setBuffered(percent); + } + /** * Get current position of playback. * @@ -347,6 +360,8 @@ public float getDuration(String file) { public void onPrepared(MediaPlayer player) { // Listen for playback completion this.player.setOnCompletionListener(this); + // Listen for download progress + this.player.setOnBufferingUpdateListener(this); // seek to any location received while not prepared this.seekToPlaying(this.seekOnPrepared); // If start playing after prepared @@ -407,6 +422,16 @@ private void setState(STATE state) { this.state = state; } + /** + * Set the buffered percentage + * + * @param buffered + */ + private void setBuffered(int buffered) { + this.handler.webView.sendJavascript("cordova.require('org.apache.cordova.media.Media').onBuffered('" + this.id + "', " + buffered + ");"); + this.buffered = buffered; + } + /** * Set the mode and send it to JavaScript. * diff --git a/www/Media.js b/www/Media.js index 083af362..dc021337 100644 --- a/www/Media.js +++ b/www/Media.js @@ -36,15 +36,18 @@ var mediaObjects = {}; * errorCallback(int errorCode) - OPTIONAL * @param statusCallback The callback to be called when media status has changed. * statusCallback(int statusCode) - OPTIONAL + * @param bufferedCallback The callback to be called when media has progressed buffering. + * bufferedCallback(int bufferedPercentage) - OPTIONAL */ -var Media = function(src, successCallback, errorCallback, statusCallback) { - argscheck.checkArgs('SFFF', 'Media', arguments); +var Media = function(src, successCallback, errorCallback, statusCallback, bufferedCallback) { + argscheck.checkArgs('SFFFF', 'Media', arguments); this.id = utils.createUUID(); mediaObjects[this.id] = this; this.src = src; this.successCallback = successCallback; this.errorCallback = errorCallback; this.statusCallback = statusCallback; + this.bufferedCallback = bufferedCallback; this._duration = -1; this._position = -1; exec(null, this.errorCallback, "Media", "create", [this.id, this.src]); @@ -192,4 +195,15 @@ Media.onStatus = function(id, msgType, value) { }; +Media.onBuffered = function(id, buffered) { + var media = mediaObjects[id]; + + if(media) { + media.bufferedCallback && media.bufferedCallback(buffered); + } else { + console.error && console.error("Received Media.onBuffered callback for unknown media :: " + id); + } + +}; + module.exports = Media;