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>
)