Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Must call prepare or prepareAsync when instantiating a new MediaPlayer and not using create() #184

Closed
wants to merge 1 commit into from

Conversation

ndbroadbent
Copy link
Contributor

Android URL support was broken by #162 (no sounds were playing), so this is the fix for that.

@ndbroadbent ndbroadbent changed the title Must call prepare() when instantiating a new MediaPlayer without using create() Must call prepare or prepareAsync when instantiating a new MediaPlayer and not using create() May 20, 2017
@SoorajChandran
Copy link

How can I use this version of react-native-sound in my app? With the android issue fixed.

@ndbroadbent
Copy link
Contributor Author

Hi @SoorajChandran, you can use this branch by running:

npm install ndbroadbent/react-native-sound#android-url-fix --save

@fabiancook
Copy link
Contributor

fabiancook commented May 25, 2017

It appears that if play is invoked too soon, you will receive an error in OnErrorListener, with what as -38, referencing https://stackoverflow.com/questions/9008770/media-player-called-in-state-0-error-38-0 it looks like you need to wait for the audio file to be prepared.

By removing prepareAsync, and then replacing the prepare function with this, everything works perfectly:

  @ReactMethod
  public void prepare(final String fileName, final Integer key, final Callback callback) {
    MediaPlayer player = createMediaPlayer(fileName);
    if (player == null) {
      WritableMap e = Arguments.createMap();
      e.putInt("code", -1);
      e.putString("message", "resource not found");
      callback.invoke(e);
      return;
    }
    final RNSoundModule module = this;
    player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() {
      boolean callbackWasCalled = false;

      @Override
      public synchronized void onPrepared(MediaPlayer mp) {
        if (callbackWasCalled) return;
        callbackWasCalled = true;

        module.playerPool.put(key, mp);
        WritableMap props = Arguments.createMap();
        props.putDouble("duration", mp.getDuration() * .001);
        callback.invoke(NULL, props);
      }

    });
    player.prepareAsync();
  }

@benvium
Copy link
Collaborator

benvium commented May 25, 2017

@fabiancook That is true, but using .prepare rather than .prepareAsync means network playback is problematic as the whole thread is blocked until enough data has been downloaded, which can be 10+ seconds on a slow connection.

@ndbroadbent
Copy link
Contributor Author

@benvium I think that is a different issue. They are still using prepareAsync, but moving the callback logic inside the onPrepared handler, which makes sense to me

@benvium
Copy link
Collaborator

benvium commented Jun 9, 2017

@ndbroadbent Thanks all. If @fabiancook's suggestion looks good can we update this PR and I'll merge it in. Would be good to be absolutely sure that Android playback works in all the cases

@fabiancook
Copy link
Contributor

I have been using my changes in production, working great

@benvium
Copy link
Collaborator

benvium commented Jun 9, 2017

@fabiancook Thanks - do you have a PR I can merge with those changes in?

@fabiancook
Copy link
Contributor

One moment :)

@benvium
Copy link
Collaborator

benvium commented Jun 16, 2017

I'm closing this for now as I believe the issue is fixed in 0.10.2. Let me know if not and I'll re-open.

@benvium benvium closed this Jun 16, 2017
@sejas
Copy link

sejas commented Mar 15, 2018

I think we should reopen the issue.
I got same error in versions 0.10.5 and 0.10.9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants