Audio plays inconsistently in android device

The app works perfectly on iOS devices but has a weird audio bug in Android. The app has several sound files. When I play the sound sometimes it plays and sometimes, the same file doesn’t play any sound! I checked the log and the function is being triggered properly. Following is the code snippet. Thanks in advance.

iconAudio.js

    export default IconSound = {
        w0: require('./assets/sounds/words/0.m4a'),
        w1: require('./assets/sounds/words/1.m4a'),
        ...
      }

files.js

    import iconAudio from './components/Icon/iconAudio'
    export const initialLoadFiles = {
        iconAudio,
        ...
      }

audio.js

    import { Audio } from 'expo'
    import * as files from './../files'

    Audio.setAudioModeAsync({
      playsInSilentModeIOS: true,
      allowsRecordingIOS: false,
      interruptionModeIOS: Audio.INTERRUPTION_MODE_IOS_DO_NOT_MIX,
      shouldDuckAndroid: false,
      interruptionModeAndroid: Audio.INTERRUPTION_MODE_ANDROID_DO_NOT_MIX,
    })

    export const cachedAudio = {}

    export function setAudioCache(audios) {
      Object.keys(audios).map(async key => {
        const res = audios[key]
        const { sound } = await Audio.Sound.create(res)
        await sound.setStatusAsync({
          volume: 1,
        })
        cachedAudio[key] = async () => {
          try {
            await sound.setPositionAsync(0)
            const playing = await sound.playAsync()
            return new Promise(resolve => setTimeout(() => {
              sound.stopAsync()
              console.log('sound stopped playing')
              resolve('played')
            }, playing.durationMillis))
          } catch (error) {
            console.warn('sound error', { error })
            // An error occurred!
          }
        }
      })
    }

    setAudioCache(files.initialLoadFiles.iconAudio)

App.js

    import { AppLoading } from 'expo'
    import React from 'react'

    import RootNavigator from './navigation/RootNavigator'
    import arrayFromObject from './utils/arrayFromObject'
    import cacheAssetsAsync from './utils/cacheAssetsAsync'
    import * as files from './Files'

    /*
      This is the base class.
      Here we preload the assets and present the Game.
    */
    class App extends React.Component {
      constructor() {
        super()
        this.state = {
          assetsLoaded: false
        }
      }

      componentWillMount() {
        this.loadAssetsAsync()
      }

      loadAssetsAsync = async () => {
        try {
          await cacheAssetsAsync({
            files: arrayFromObject(files.initialLoadFiles),
          })
        } catch (e) {
          console.warn(
            'There was an error caching assets (see: app.js), perhaps due to a ' +
            'network timeout, so we skipped caching. Reload the app to try again.'
          );
          console.log(e.message)
        } finally {
          console.log('Initial Load is preloaded!')
          await cacheAssetsAsync({
            files: arrayFromObject(files.cache), // start pre loading the secondary audio files
          })
          this.setState({
            assetsLoaded: true
          })
        }
      }

      render() {
        return this.state.assetsLoaded ? <RootNavigator /> : <AppLoading />
      }
    }

    export default App    

icon.js

    const Icon = props => (
      <TouchableOpacity
        style={styles.container}
        activeOpacity={0.5}
        onPress={() => {
          cachedAudio[`w${props.id}`]()
        }}
      >
      </TouchableOpacity>
    )

Hey @rexonms,

Do you think you would be able to create a reproducible example of the bug using https://snack.expo.io/?

It really helps us with the bug-squashing process and sometimes can reveal that it is something else causing the issue rather than the suspected code.

Cheers,

Adam

Hi @adamjnav ,
Thanks for the suggestion. I created a snack.

Best,
Rexon

@adamjnav,
I am pretty sure the bug has nothing to do with the way I am calling the cached audio.

This topic was automatically closed 15 days after the last reply. New replies are no longer allowed.