flutter_soloud provides multiple ways to load audio content:
- ๐ Local files
- ๐ฆ Assets
- ๐ Network URLs
- ๐พ Memory buffers
- ๐ Stereo buffer joining (
joinTwoSources) - ๐ Generated waveforms
Each loaded sound returns an AudioSource that must be managed:
// Load and store the audio source
final sound = await SoLoud.instance.loadFile('path/to/sound.mp3');
// Use the sound multiple times
final handle1 = await SoLoud.instance.play(sound);
final handle2 = await SoLoud.instance.play(sound);
// Clean up when no longer needed
await SoLoud.instance.disposeSource(sound);You can listen for events related to playback handles using the sound.soundEvents stream. This allows you to react to changes such as when a sound finishes playing (or stopped) or is disposed.
sound.soundEvents.listen((event) {
debugPrint('Sound event: $event');
});Each event is a record containing the following:
SoundEventTypeโ the type of event (see below)AudioSourceโ the source associated with the eventSoundHandleโ the handle for the specific playback instance
The SoundEventType enum includes:
/// Types of sound events
enum SoundEventType {
/// The handle has reached the end of playback and is no longer valid
handleIsNoMoreValid,
/// The audio source has been disposed
soundDisposed,
}Listen to allInstancesFinished to automatically dispose when all instances complete:
final sound = await SoLoud.instance.loadFile('path/to/sound.mp3');
sound.allInstancesFinished.first.then((_) {
SoLoud.instance.disposeSource(sound);
});
await SoLoud.instance.play(sound);All load* methods support an autoDispose parameter that automatically disposes the audio source when all its handles have finished playing. This eliminates the need to manually call disposeSource.
// This sound will be automatically disposed when playback finishes
final sound = await SoLoud.instance.loadFile(
'path/to/sound.mp3',
autoDispose: true,
);
await SoLoud.instance.play(sound);
// No need to call disposeSource - it happens automatically!Using autoDispose: true is recommended for short sounds that play once (like sound effects), while manual disposal is better for sounds you intend to reuse multiple times.
You can inspect the loaded source identifier and any temporary file path directly from the AudioSource:
sound.soundPath: Stores the parameter used to load the audio:- For
loadFile(),loadMem(), andjoinTwoSources(): thepathargument. - For
loadAsset(): the assetkey(e.g.'assets/sound.mp3'). - For
loadUrl(): the networkurl(e.g.'https://example.com/sound.mp3'). - For generated sources (
loadWaveform(),speechText()): an empty string''.
- For
sound.tempFilePath: Stores the path of the temporary file created on disk when loading an asset or URL on native platforms. ForloadFile(),loadMem(), generated sources, or on the Web platform, this is an empty string''.
final sound = await SoLoud.instance.loadAsset('assets/audio/laser.mp3');
// Prints the asset key
debugPrint('Loaded asset: ${sound.soundPath}'); // assets/audio/laser.mp3
// Prints the local temporary cached file path (on native platforms)
debugPrint('Temp cache file: ${sound.tempFilePath}');You can load audio in several ways, depending on your source and platform requirements. Below are the available methods:
Load audio directly from a file path.
final sound = await SoLoud.instance.loadFile(
'/path/to/sound.mp3',
mode: LoadMode.memory, // Default
);Loading from files is not supported on the Web platform. Use loadMem() instead when targeting web.
Memory modes:
LoadMode.memoryโ Loads the entire file into RAM (better performance for small files)LoadMode.diskโ Streams from disk (lower memory usage, suitable for large files)
Load audio from a byte buffer, such as data read from a file, asset, network or self-made wav file.
final bytes = await File('sound.mp3').readAsBytes();
final sound = await SoLoud.instance.loadMem(
'reference_name.mp3',
bytes,
mode: LoadMode.memory,
);When targeting the web platform, this is the recommended method to load audio files. You can load the bytes from your assets or network sources.
Load audio from bundled assets in your Flutter project.
final sound = await SoLoud.instance.loadAsset(
'assets/sound.mp3',
mode: LoadMode.memory,
assetBundle: rootBundle, // Optional
);Load audio directly from a network URL.
final sound = await SoLoud.instance.loadUrl(
'https://example.com/sound.mp3',
mode: LoadMode.memory,
httpClient: client, // Optional custom client
);Note: When using loadAsset or loadUrl, a temporary file is created on the device. On mobile platforms, the operating system may automatically clear the cache without notice. If this happens after loading the sound but before playing it, a crash may occur because the file is no longer available. This is a known but rare issue. To prevent this, consider using loadMem() with LoadMode.memory mode.
You can load two separate audio byte buffers and join them into a single stereo AudioSource in memory.
final leftBytes = await File('left_track.wav').readAsBytes();
final rightBytes = await File('right_track.wav').readAsBytes();
final stereoSound = await SoLoud.instance.joinTwoSources(
'reference_name_stereo',
leftBytes,
rightBytes,
autoDispose: false, // Optional: auto-dispose when playback completes
);
final handle = SoLoud.instance.play(stereoSound);Key behavior of joinTwoSources():
- Mono conversion: If either buffer contains non-mono channels, it is converted to mono on the native side before joining.
- Engine resampling: Both audio buffers are automatically resampled to the player engine's sample rate, eliminating any real-time resampling during mixer playback.
- Length matching: If the buffers have different lengths, the resulting audio length matches the longer buffer, and the shorter buffer is automatically padded with silence.
- Memory mode: Always loads completely into RAM (
LoadMode.memory).
Supported audio formats:
| Format | Extension | Description |
|---|---|---|
| MP3 | .mp3 | Most common compressed format |
| WAV | .wav | Uncompressed PCM audio |
| OGG | .ogg | Free compressed format |
| FLAC | .flac | Lossless compression |
- Reuse loaded sounds instead of loading multiple times
- Dispose sounds when no longer needed
- Use
LoadMode.diskfor large background music files - Use
LoadMode.memoryfor sound effects needing quick access
- Load frequently used sounds at app startup
- Consider memory constraints when loading multiple files
- Use appropriate load modes based on usage patterns
- Implement proper error handling for all load operations
When you need to load multiple audio files at once, it is recommended to use the wait method in a Future list, which will load 20 to 40% faster.
final sounds = await [
SoLoud.instance.loadAsset('your/asset/sound1.mp3'),
SoLoud.instance.loadAsset('your/asset/sound2.mp3'),
SoLoud.instance.loadAsset('your/asset/sound3.mp3'),
[...]
].wait;try {
final sound = await SoLoud.instance.loadFile('path/to/sound.mp3');
} on SoLoudNotInitializedException {
print('Initialize SoLoud first');
} on SoLoudFileLoadFailedException {
print('Could not load audio file');
} catch (e) {
print('Unexpected error: $e');
}