diff --git a/README.md b/README.md index 31172ff15..92a690256 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ cordova plugin add cordova-plugin-media ## Media ```js -var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); +var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus], [options]); ``` ### Parameters @@ -75,6 +75,8 @@ var media = new Media(src, mediaSuccess, [mediaError], [mediaStatus]); - __mediaStatus__: (Optional) The callback that executes to indicate status changes. It takes a integer status code. _(Function)_ +- __options__: (Optional) The object to pass additional options to player instance. (Android) Supports only `usage` property atm. _(Object)_ + __NOTE__: `cdvfile` path is supported as `src` parameter: ```javascript var my_media = new Media('cdvfile://localhost/temporary/recording.mp3', ...); @@ -82,6 +84,12 @@ var my_media = new Media('cdvfile://localhost/temporary/recording.mp3', ...); ### Constants +(Android) Usage types: + +- `Media.ANDROID_USAGE_UNKNOWN` = 0; +- `Media.ANDROID_USAGE_MEDIA` = 1; +- `Media.ANDROID_USAGE_VOICE_COMMUNICATION` = 2; + The following constants are reported as the only parameter to the `mediaStatus` callback: diff --git a/src/android/AudioHandler.java b/src/android/AudioHandler.java index 9e734c440..497a51659 100644 --- a/src/android/AudioHandler.java +++ b/src/android/AudioHandler.java @@ -164,7 +164,14 @@ else if (action.equals("getDurationAudio")) { else if (action.equals("create")) { String id = args.getString(0); String src = FileHelper.stripFileProtocol(args.getString(1)); - getOrCreatePlayer(id, src); + AudioPlayer player = getOrCreatePlayer(id, src); + + JSONObject jsonOptions = args.optJSONObject(2); + if(jsonOptions != null) { + Options options = new Options(); + options.usage = jsonOptions.optInt("usage", options.usage); + player.setOptions(options); + } } else if (action.equals("release")) { boolean b = this.release(args.getString(0)); diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java index b40e281ed..7b60579eb 100644 --- a/src/android/AudioPlayer.java +++ b/src/android/AudioPlayer.java @@ -18,6 +18,7 @@ Licensed to the Apache Software Foundation (ASF) under one */ package org.apache.cordova.media; +import android.media.AudioAttributes; import android.media.AudioManager; import android.media.MediaPlayer; import android.media.MediaPlayer.OnCompletionListener; @@ -39,6 +40,10 @@ Licensed to the Apache Software Foundation (ASF) under one import java.io.IOException; import java.util.LinkedList; +final class Options { + Integer usage = AudioAttributes.USAGE_UNKNOWN; +} + /** * This class implements the audio playback and recording capabilities used by Cordova. * It is called by the AudioHandler Cordova class. @@ -77,6 +82,8 @@ public enum STATE { MEDIA_NONE, // private static int MEDIA_ERR_DECODE = 3; // private static int MEDIA_ERR_NONE_SUPPORTED = 4; + private Options options = new Options(); + private AudioHandler handler; // The AudioHandler object private String id; // The id of this player (used to identify Media object in JavaScript) private MODE mode = MODE.NONE; // Playback or Recording mode @@ -106,6 +113,10 @@ public AudioPlayer(AudioHandler handler, String id, String file) { this.tempFiles = new LinkedList(); } + public void setOptions(Options options) { + this.options = options; + } + private String generateTempFile() { String tempFileName = null; if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { @@ -609,6 +620,12 @@ private boolean readyPlayer(String file) { case MEDIA_NONE: if (this.player == null) { this.player = new MediaPlayer(); + if(this.options.usage != AudioAttributes.USAGE_UNKNOWN) { + this.player.setAudioAttributes( + new AudioAttributes.Builder() + .setUsage(options.usage) + .build()); + } this.player.setOnErrorListener(this); } try { @@ -632,6 +649,12 @@ private boolean readyPlayer(String file) { //maybe it was recording? if (player == null) { this.player = new MediaPlayer(); + if(this.options.usage != AudioAttributes.USAGE_UNKNOWN) { + this.player.setAudioAttributes( + new AudioAttributes.Builder() + .setUsage(options.usage) + .build()); + } this.player.setOnErrorListener(this); this.prepareOnly = false; diff --git a/www/Media.js b/www/Media.js index 80fbf47c2..823d039f2 100644 --- a/www/Media.js +++ b/www/Media.js @@ -38,18 +38,21 @@ var mediaObjects = {}; * errorCallback(int errorCode) - OPTIONAL * @param statusCallback The callback to be called when media status has changed. * statusCallback(int statusCode) - OPTIONAL + * @param options The options object. + * (android) { usage } - OPTIONAL */ -var Media = function (src, successCallback, errorCallback, statusCallback) { - argscheck.checkArgs('sFFF', 'Media', arguments); +var Media = function (src, successCallback, errorCallback, statusCallback, options) { + argscheck.checkArgs('sFFFO', 'Media', arguments); this.id = utils.createUUID(); mediaObjects[this.id] = this; this.src = src; this.successCallback = successCallback; this.errorCallback = errorCallback; this.statusCallback = statusCallback; + this.options = options; this._duration = -1; this._position = -1; - exec(null, this.errorCallback, 'Media', 'create', [this.id, this.src]); + exec(null, this.errorCallback, 'Media', 'create', [this.id, this.src, this.options]); }; // Media messages @@ -66,6 +69,11 @@ Media.MEDIA_PAUSED = 3; Media.MEDIA_STOPPED = 4; Media.MEDIA_MSG = ['None', 'Starting', 'Running', 'Paused', 'Stopped']; +// Usage types +Media.ANDROID_USAGE_UNKNOWN = 0; +Media.ANDROID_USAGE_MEDIA = 1; +Media.ANDROID_USAGE_VOICE_COMMUNICATION = 2; + // "static" function to return existing objs. Media.get = function (id) { return mediaObjects[id];