[ 
https://issues.apache.org/jira/browse/CB-13502?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=16637223#comment-16637223
 ] 

ASF GitHub Bot commented on CB-13502:
-------------------------------------

janpio closed pull request #152: CB-13502: (android) Implementation of setRate 
method for Android Marshmallow and later
URL: https://github.com/apache/cordova-plugin-media/pull/152
 
 
   

This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:

As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):

diff --git a/.travis.yml b/.travis.yml
index 59a576db..dcad4ad5 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -4,7 +4,7 @@ addons:
     secure: 
M4uBGUMbanDtCBrNktJhEwNSLL0UsOV3IoINqW3GRupX7Mr13MBZzsORm4HVbdbPxQ6Bf2LhyJ/fabQRsOoJrCokgWwfKkigztQcMFeLNao9liBRA6kuQOh5/rdfoULpu96GvlYzB4ddgSBSSGQW3DesaKC/BpTXnvQ4OnXo5e4=
 env:
   global:
-  - SAUCE_USERNAME=snay
+  - SAUCE_USERNAME=jh3141
   - TRAVIS_NODE_VERSION="4.2"
 matrix:
   include:
diff --git a/README.md b/README.md
index 577cd388..41b894cb 100644
--- a/README.md
+++ b/README.md
@@ -23,36 +23,25 @@ description: Record and play audio on the device.
 
 |AppVeyor|Travis CI|
 |:-:|:-:|
-|[![Build 
status](https://ci.appveyor.com/api/projects/status/github/apache/cordova-plugin-media?branch=master)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-plugin-media)|[![Build
 
Status](https://travis-ci.org/apache/cordova-plugin-media.svg?branch=master)](https://travis-ci.org/apache/cordova-plugin-media)|
+|[![Build 
status](https://ci.appveyor.com/api/projects/status/github/apache/cordova-plugin-media?branch=master)](https://ci.appveyor.com/project/ApacheSoftwareFoundation/cordova-plugin-media)|[![Build
 
Status](https://travis-ci.org/jh3141/cordova-plugin-media.svg?branch=master)](https://travis-ci.org/jh3141/cordova-plugin-media)|
 
 # cordova-plugin-media
 
 
-This plugin provides the ability to record and play back audio files on a 
device.
+This is a forked version of the cordova-plugin-media plugin, which provides 
the ability to record
+and play back audio files on a device.  This fork adds the following changes:
 
-__NOTE__: The current implementation does not adhere to a W3C
-specification for media capture, and is provided for convenience only.
-A future implementation will adhere to the latest W3C specification
-and may deprecate the current APIs.
-
-This plugin defines a global `Media` Constructor.
-
-Although in the global scope, it is not available until after the 
`deviceready` event.
-
-```js
-document.addEventListener("deviceready", onDeviceReady, false);
-function onDeviceReady() {
-    console.log(Media);
-}
-```
-
-Report issues with this plugin on the [Apache Cordova issue 
tracker](https://issues.apache.org/jira/issues/?jql=project%20%3D%20CB%20AND%20status%20in%20(Open%2C%20%22In%20Progress%22%2C%20Reopened)%20AND%20resolution%20%3D%20Unresolved%20AND%20component%20%3D%20%22cordova-plugin-media%22%20ORDER%20BY%20priority%20DESC%2C%20summary%20ASC%2C%20updatedDate%20DESC)
+* Support the `setRate` API under Android
+* Fix broken tests
 
+Additional updates are planned for better handling of background playing, and 
supporting background
+application use.  If they aren't available here yet, there may be development 
versions in branches
+that haven't been merged yet; have a look at those if you're interested.
 
 ## Installation
 
 ```bash
-cordova plugin add cordova-plugin-media
+cordova plugin add https://github.com/jh3141/cordova-plugin-media
 ```
 
 ## Supported Platforms
@@ -322,9 +311,13 @@ function recordAudio() {
 Starts or resumes playing an audio file.
 
 ```js
-media.play();
+media.play(options);
 ```
 
+* Options specifies optional settings for player behaviour, and may be omitted 
if
+  the defaults are to be used.  See the platform-specific descriptions below 
for
+  available options.
+
 ### Quick Example
 
 ```js
diff --git a/src/android/AudioHandler.java b/src/android/AudioHandler.java
index 9e734c44..f3ad938d 100644
--- a/src/android/AudioHandler.java
+++ b/src/android/AudioHandler.java
@@ -129,13 +129,20 @@ else if (action.equals("resumeRecordingAudio")) {
         else if (action.equals("startPlayingAudio")) {
             String target = args.getString(1);
             String fileUriStr;
+            boolean ignoreFocusLost;
             try {
                 Uri targetUri = resourceApi.remapUri(Uri.parse(target));
                 fileUriStr = targetUri.toString();
             } catch (IllegalArgumentException e) {
                 fileUriStr = target;
             }
-            this.startPlayingAudio(args.getString(0), 
FileHelper.stripFileProtocol(fileUriStr));
+            try {
+                ignoreFocusLost = 
args.getJSONObject(2).getBoolean("ignoreFocusLost");
+            } catch (JSONException ignored) {
+                ignoreFocusLost = false;
+            }
+
+            this.startPlayingAudio(args.getString(0), 
FileHelper.stripFileProtocol(fileUriStr), ignoreFocusLost);
         }
         else if (action.equals("seekToAudio")) {
             this.seekToAudio(args.getString(0), args.getInt(1));
@@ -178,6 +185,12 @@ else if (action.equals("messageChannel")) {
             float f = this.getCurrentAmplitudeAudio(args.getString(0));
             callbackContext.sendPluginResult(new PluginResult(status, f));
             return true;
+        } else if (action.equals("setRate")) {
+            try {
+                this.setRate(args.getString(0), 
Float.parseFloat(args.getString(1)));
+            } catch (NumberFormatException nfe) {
+                //no-op
+            }
         }
         else { // Unrecognized action.
             return false;
@@ -314,9 +327,11 @@ public void resumeRecordingAudio(String id) {
      * Start or resume playing audio file.
      * @param id                               The id of the audio player
      * @param file                             The name of the audio file.
+     * @param ignoreFocusLost   If true, do not suspend playback when focus is 
lost
      */
-    public void startPlayingAudio(String id, String file) {
+    public void startPlayingAudio(String id, String file, boolean 
ignoreFocusLost) {
         AudioPlayer audio = getOrCreatePlayer(id, file);
+        audio.setIgnoreFocusLost (ignoreFocusLost)
         audio.startPlaying(file);
         getAudioFocus();
     }
@@ -402,7 +417,7 @@ else if (output == 1) {
 
     public void pauseAllLostFocus() {
         for (AudioPlayer audio : this.players.values()) {
-            if (audio.getState() == AudioPlayer.STATE.MEDIA_RUNNING.ordinal()) 
{
+            if (audio.getState() == AudioPlayer.STATE.MEDIA_RUNNING.ordinal() 
&& !audio.getIgnoreLostFocus()) {
                 this.pausedForFocus.add(audio);
                 audio.pausePlaying();
             }
@@ -487,6 +502,23 @@ public void setVolume(String id, float volume) {
         }
     }
 
+    /**
+     * Set the playback rate for an audio player
+     *
+     * @param id                               The id of the audio player
+     * @param rate              Playback rate (where 1.0 is normal speed)
+     */
+    public void setRate(String id, float rate) {
+        String TAG4 = "AudioHandler.setRate(): Error : ";
+
+        AudioPlayer audio = this.players.get(id);
+        if (audio != null) {
+            audio.setRate(rate);
+        } else {
+          LOG.e(TAG4,"Unknown Audio Player " + id);
+        }
+    }
+
     private void onFirstPlayerCreated() {
         origVolumeStream = cordova.getActivity().getVolumeControlStream();
         
cordova.getActivity().setVolumeControlStream(AudioManager.STREAM_MUSIC);
diff --git a/src/android/AudioPlayer.java b/src/android/AudioPlayer.java
index 861421e7..2d788bec 100644
--- a/src/android/AudioPlayer.java
+++ b/src/android/AudioPlayer.java
@@ -92,6 +92,8 @@ Licensed to the Apache Software Foundation (ASF) under one
     private MediaPlayer player = null;      // Audio player object
     private boolean prepareOnly = true;     // playback after file prepare flag
     private int seekOnPrepared = 0;     // seek to this location once media is 
prepared
+    private float setRateOnPrepared = -1;
+    private boolean ignoreFocusLost = false;
 
     /**
      * Constructor.
@@ -446,6 +448,9 @@ public void onPrepared(MediaPlayer player) {
         this.player.setOnCompletionListener(this);
         // seek to any location received while not prepared
         this.seekToPlaying(this.seekOnPrepared);
+        // apply any playback rate received while not prepared
+        if (setRateOnPrepared >= 0)
+            this.player.setPlaybackParams 
(this.player.getPlaybackParams().setSpeed(setRateOnPrepared));
         // If start playing after prepared
         if (!this.prepareOnly) {
             this.player.start();
@@ -541,6 +546,23 @@ public void setVolume(float volume) {
         }
     }
 
+    /**
+     * Set the playback rate for the player (ignored on API < 23)
+     *
+     * @param volume
+     */
+    public void setRate(float rate) {
+        if (android.os.Build.VERSION.SDK_INT < 
android.os.Build.VERSION_CODES.M) {
+            LOG.d(LOG_TAG, "AudioPlayer Warning: Request to set playback rate 
not supported on current OS version");
+            return;
+        }
+        if (this.player != null) {
+            this.player.setPlaybackParams 
(this.player.getPlaybackParams().setSpeed(rate));
+        } else {
+            setRateOnPrepared = rate;
+        }
+    }
+
     /**
      * attempts to put the player in play mode
      * @return true if in playmode, false otherwise
@@ -719,4 +741,22 @@ public float getCurrentAmplitude() {
         }
         return 0;
     }
+
+    /**
+     * Sets the flag controlling whether this player should be paused whenever
+     * audio focus is lost.  Default false => pause is performed.
+     */
+    public void setIgnoreFocusLost (boolean ignoreFocusLost)
+    {
+        this.ignoreFocusLost = ignoreFocusLost;
+    }
+
+    /**
+     * Gets the flag controlling whether this player should be paused whenever
+     * audio focus is lost.  Default false => pause is performed.
+     */
+    public boolean getIgnoreLostFocus ()
+    {
+        return ignoreFocusLost;
+    }
 }
diff --git a/tests/tests.js b/tests/tests.js
index 218f2a95..0f0159e7 100644
--- a/tests/tests.js
+++ b/tests/tests.js
@@ -27,7 +27,7 @@
 var ACTUAL_PLAYBACK_TEST_TIMEOUT = 2 * 60 * 1000;
 
 var WEB_MP3_FILE = 'https://cordova.apache.org/downloads/BlueZedEx.mp3';
-var WEB_MP3_STREAM = 
'http://c22033-l.i.core.cdn.streamfarm.net/22033mdr/live/3087mdr_figaro/ch_classic_128.mp3';
+var WEB_MP3_STREAM = 'http://forever.fm/all.mp3';
 
 var isWindows = cordova.platformId === 'windows8' || cordova.platformId === 
'windows';
 var isBrowser = cordova.platformId === 'browser';
@@ -36,6 +36,14 @@ var isBrowser = cordova.platformId === 'browser';
 // the case for Sauce Labs emulators - see CB-11430)
 var isAudioSupported = isWindows ? 
!!Windows.Media.Devices.MediaDevice.getDefaultAudioRenderId(Windows.Media.Devices.AudioDeviceRole.default)
 :
     cordova.platformId === 'ios' ? !window.SAUCELABS_ENV : true;
+// Detect OS version when running on Android
+var androidVersion = null;
+if (cordova.platformId === 'android') {
+    var ua = navigator.userAgent;
+    var androidStart = ua.indexOf('Android ');
+    var versionString = ua.substring(androidStart + 8, ua.indexOf(';', 
androidStart));
+    androidVersion = versionString.split(".").map(function(x) { return x/1; });
+}
 
 exports.defineAutoTests = function () {
     var failed = function (done, msg, context) {
@@ -376,7 +384,9 @@ exports.defineAutoTests = function () {
         });
 
         it("media.spec.24 playback rate should be set properly using setRate", 
function (done) {
-            if (cordova.platformId !== 'ios') {
+            if (cordova.platformId !== 'ios' &&
+                (cordova.platformId !== 'android' || androidVersion[0] <= 6))
+            {
                 expect(true).toFailWithMessage('Platform does not supported 
this feature');
                 pending();
             }
diff --git a/www/Media.js b/www/Media.js
index 5806b9f6..8d84ea9a 100644
--- a/www/Media.js
+++ b/www/Media.js
@@ -170,7 +170,7 @@ Media.prototype.setVolume = function(volume) {
  * Adjust the playback rate.
  */
 Media.prototype.setRate = function(rate) {
-    if (cordova.platformId === 'ios'){
+    if (cordova.platformId === 'ios' || cordova.platformId === "android"){
         exec(null, null, "Media", "setRate", [this.id, rate]);
     } else {
         console.warn('media.setRate method is currently not supported for', 
cordova.platformId, 'platform.');


 

----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
 
For queries about this service, please contact Infrastructure at:
us...@infra.apache.org


> Android - add support for "setRate" method already available on iOS
> -------------------------------------------------------------------
>
>                 Key: CB-13502
>                 URL: https://issues.apache.org/jira/browse/CB-13502
>             Project: Apache Cordova
>          Issue Type: Improvement
>          Components: cordova-plugin-media
>            Reporter: Julian Hall
>            Priority: Minor
>
> The iOS media plugin supports a method "setRate" which changes the playback 
> rate.  Android has support for this feature in the MediaPlayer class used by 
> the media plugin since API version 23 (Marshmallow), therefore supporting 
> this method there is very easy.



--
This message was sent by Atlassian JIRA
(v7.6.3#76005)

---------------------------------------------------------------------
To unsubscribe, e-mail: issues-unsubscr...@cordova.apache.org
For additional commands, e-mail: issues-h...@cordova.apache.org

Reply via email to