React-native-sound: No sound on Android APK

Created on 15 May 2017  路  10Comments  路  Source: zmxv/react-native-sound

Hi guys!
I've found a problem and I don't know how to solve It. Right now I'm playing an audio from a 'require' like this:

{...}
const requireAudio = require('../../assets/audio/audio_sample.mp3');
{...}
Sound.setCategory('Ambient', true);

    this.sound = null;

    this.playSoundFromRequire = () => {
      const sound = new Sound(requireAudio, (error) => {
        if (error) {
          console.log('error', error);
          return;
        }
        if (this.state.opened) {
          sound.play(() => sound.release());
        }   
      });
{...}

If I use the app with the React packager the sound is playing fine, but once I deploy the app as an APK the sound Is missing. I haven't tested It yet on iOS, but on Android I have this issue, any ideas?

All 10 comments

@FacuAcosta have you been able to fix this? I can play on a simulator, but not an actual device

From the instruction of react-native-sound, it describes:
Android: Save your sound clip files under the directory android/app/src/main/res/raw. Note that files in this directory must be lowercase and underscored (e.g. my_file_name.mp3) and that subdirectories are not supported by Android.

So to build apk file, you need to firstly put the audio file to the right path, then use Sound.MAIN_BUNDLE as the path for the constructor. e.g.:
var alarmSound = new Sound('analog_watch_alarm.mp3', Sound.MAIN_BUNDLE, (error) => {})

same issue锛寃ho know why

@FacuAcosta any solution?

Hey @zk2401 , so in the end my project had to use online data and it's working fine, I wasn't able to find a solution for local data.

Have you tried it without using require()? This is working fine for us (wrapping in a Promise):

const soundPromise: Promise<Sound> =
  new Promise<Sound>((resolve, reject) => {
    const sound = new Sound(
      audioFileName,
      Sound.MAIN_BUNDLE,
      (error: Error) => {
        if (error) {
          reject(error);
        }
        sound.setNumberOfLoops(-1); // indefinite looping, or whatever you need
        resolve(sound);
      },
    );
    return;
  });

I also stucked with this issue for a long time. I want to play a sound on Android app but it failed without errors, meanwhile everything is OK on iOS app. So after many times trying without success, I noticed about this on npm page:

To minimize playback delay, you may want to preload a sound file without calling play() (e.g. var s = new Sound(...);) during app initialization. This also helps avoid a race condition where play() may be called before loading of the sound is complete, which results in no sound but no error because loading is still being processed.

Then I try to follow this guide then BUM! it works on Android like a charm.
So what I have done is below:

  1. create a _preLoad_ function in my SoundManager
static preLoad = () => {
        console.log("preload sound message");
        this.sound = new Sound(YOUR_SOUND_FILENAME, Sound.MAIN_BUNDLE, (error) => {
            if (error) {
                console.log('failed to load the sound', error);
            }else{ 
                console.log('duration in seconds: ' + sound.getDuration() + ' number of channels: ' + sound.getNumberOfChannels());                                 
            }           
        })
    }

_playSound_ function just use preloaded sound resource to play

static playMySound = () => {
        console.log("play notification sound");
        this.sound.play((success) => {
                    if (success) {
                        console.log('successfully finished playing');
                    } else {
                        console.log('playback failed due to audio decoding errors');
                        sound.reset();
                    }
                })
    }
  1. call _preLoad_ on App / componentWillMount, e.g at the beginning of app execution
componentWillMount(){
        // YOUR OTHER LOGICS
        SoundManager.preLoad();
    }
  1. play sound in your necessary place as usual
    SoundManager.playSound();

so for me it was a path issue:

    if (Platform.OS === 'ios'){
      // I have/had a folder for all my files for the iOS app but this does not work for android
      this.path = "sounds/"
    }else{
      // android: drop files in ./android/app/src/main/res/raw
      // all files must be lower case and with underscores "_"
      this.path = ""
    }

   new Sound(this.path + YOUR_FILE_NAME, Sound.MAIN_BUNDLE)
Was this page helpful?
0 / 5 - 0 ratings