A universal player for audio sprites generated by the 'audiosprite' tool. Supports playing multiple sounds at same time!
npm install react-native-audiospritesyarn add react-native-audiospritesFirst, you need to generate an audio sprite and a JSON manifest file using the audiosprite tool.
Assuming you have audiosprite installed globally:
audiosprite --output src/__tests__/sounds/mygameaudio --format howler --loop "bg_loop" src/__tests__/sounds/bg_loop.wav src/__tests__/sounds/Sound_1.m4a src/__tests__/sounds/Sound_2.m4a src/__tests__/sounds/Sound_3.m4a src/__tests__/sounds/Sound_4.m4aThis command will generate mygameaudio.json, mygameaudio.mp3, mygameaudio.ogg, mygameaudio.m4a, and mygameaudio.ac3 in the src/__tests__/sounds/ directory.
You can create looping sounds by using the --loop option with the audiosprite command. The value of the --loop option should be the name of the sound you want to loop.
For example, to loop the bg_music sound, you would use the following command:
audiosprite --output audiosprite --format howler --loop "bg_music" --path ./src/__tests__/ Sound_1.m4a Sound_2.m4a Sound_3.m4a Sound_4.m4a bg_music.wavWhen you play a looping sound, it will play continuously until you stop it using the player.stop() method. The looping functionality is supported on both web and mobile platforms.
Then, you can use the AudioSpritePlayer to play the sounds from the sprite.
import { AudioSpritePlayer } from 'react-native-audiosprites';
const player = new AudioSpritePlayer({
platform: 'web',
});
async function playSound(soundName: string) {
try {
// Load the audio sprite manifest and audio files
// Adjust the path to your audiosprite.json file
await player.load('./src/__tests__/sounds/mygameaudio.json');
console.log('Audio sprite loaded successfully.');
// Play a sound from the spritemap
player.play(soundName);
console.log(`Playing sound: ${soundName}`);
} catch (error) {
console.error('Error playing sound:', error);
}
}
function stopSound() {
player.stop();
console.log('Stopped looping sound.');
}
// Example usage:
playSound('Sound_1');
// playSound('Sound_2');
// To stop a looping sound:
// stopSound();For React Native, you'll need react-native-audio-api and expo-asset to handle audio playback and asset loading.
First, install the dependencies:
npm install react-native-audio-api expo-asset expo-file-system
# or
yarn add react-native-audio-api expo-asset expo-file-systemChange metro.config.js as per react-native-audio-api documentation: https://docs.swmansion.com/react-native-audio-api/docs/fundamentals/getting-started
module.exports = wrapWithAudioAPIMetroConfig(config);Then, you can use it in your component:
import { StyleSheet, View, Text, Platform, TouchableOpacity } from 'react-native';
import { AudioSpritePlayer } from 'react-native-audiosprites';
import { AudioManager, AudioContext } from 'react-native-audio-api';
import { useEffect, useState, useRef } from 'react';
import { Asset } from 'expo-asset';
import { fetch } from 'expo/fetch';
import manifest from '../assets/mygameaudio.json';
// Import the audio asset
const audioAsset = require('../assets/mygameaudio.mp3');
export default function App() {
const [isLoaded, setIsLoaded] = useState(false);
const playerRef = useRef<AudioSpritePlayer | null>(null);
useEffect(() => {
const loadPlayer = async () => {
const asset = Asset.fromModule(audioAsset);
await asset.downloadAsync();
const audioUri = asset.localUri || asset.uri;
if (!audioUri) {
console.error('Failed to get audio URI.');
return;
}
if (Platform.OS === 'ios') {
try {
await AudioManager.setAudioSessionOptions({
iosCategory: 'playback',
iosOptions: ['mixWithOthers'],
});
await AudioManager.setAudioSessionActivity(true);
} catch (e) {
console.error('Failed to configure AudioSession options:', e);
}
}
const audioContext = new AudioContext();
const audioPlayer = new AudioSpritePlayer({
audioContext,
fetch: fetch.bind(globalThis),
platform: Platform.OS,
});
try {
await audioPlayer.load(manifest, audioUri);
playerRef.current = audioPlayer;
setIsLoaded(true);
console.log('Audio sprite loaded successfully.');
} catch (error) {
console.error('Failed to load audio sprite:', error);
}
};
loadPlayer();
}, []);
const playSound = (soundName: string) => {
const player = playerRef.current;
if (player && isLoaded) {
player.play(soundName);
console.log(`Playing sound: ${soundName}`);
} else {
console.warn('Player not loaded yet.');
}
};
const stopBGM = () => {
const player = playerRef.current;
if (player) {
player.stop();
}
};
return (
<View style={styles.container}>
<Text>AudioSprite Player Example</Text>
<TouchableOpacity
onPress={() => loadPlayer()}
style={styles.button}
disabled={!isLoaded}
>
<Text style={styles.buttonText}>Load Player</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => playSound('Sound_1')}
style={styles.button}
disabled={!isLoaded}
>
<Text style={styles.buttonText}>Play Sound 1</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => playSound('Sound_2')}
style={styles.button}
disabled={!isLoaded}
>
<Text style={styles.buttonText}>Play Sound 2</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={() => playSound('bg_loop')}
style={styles.button}
disabled={!isLoaded}
>
<Text style={styles.buttonText}>Play Background Loop</Text>
</TouchableOpacity>
<TouchableOpacity
onPress={stopBGM}
style={styles.button}
disabled={!isLoaded}
>
<Text style={styles.buttonText}>Stop BGM</Text>
</TouchableOpacity>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
alignItems: 'center',
justifyContent: 'center',
},
button: {
backgroundColor: '#DDDDDD',
padding: 10,
marginVertical: 5,
borderRadius: 5,
},
buttonText: {
color: '#000000',
textAlign: 'center',
},
});https://github.com/goldfire/howler.js Generated json also works with new Howl({ sprite: { key1: [offset, duration, (loop)] }, });
MIT
Shaker, Woda, Conga, Bongo, Templeblock.wav by kwazi | License: Attribution 3.0
Made with create-react-native-library