playMusic method
Loads and plays music from the given path
.
If music is already playing or paused, it will be stopped/paused and replaced.
You can play back mp3, ogg and wave files.
Warning:On iOS Devices ogg format is not supported.
Info:
On most browser you can only playback music after the first user interaction.
In that case, Bullseye2D retries, so as soon as the first user interaction (click)
occurs, playback will be started.
path
: The URL or path to the music file.loop
: Whether the music should loop. Defaults tofalse
.loopStart
: The start time in samples for looping, ifloop
istrue
. Converted to seconds usinghz
. RequiresloopEnd
to also be set. NOTE: Music looping might not work reliably if the web server does not supportAccept-Ranges
headers (e.g., Dart's development server).loopEnd
: The end time in samples for looping, ifloop
istrue
. Converted to seconds usinghz
. RequiresloopStart
to also be set. NOTE: Music looping might not work reliably if the web server does not supportAccept-Ranges
headers.hz
: The sample rate of the audio (e.g., 44100), used for converting sample-based loop points to seconds. Defaults to 44100.
Implementation
void playMusic(String path, bool loop, [double loopStart = -1, double loopEnd = -1, hz = 44100]) {
if (audioContext.state == 'suspended') {
audioContext.resume();
}
if (musicState != ChannelState.stopped) {
_musicVisualizer?.disconnect();
_music?.pause();
musicState = ChannelState.paused;
}
_music =
HTMLAudioElement()
..load()
..src = path
..loop = loop
..volume = _musicVolume;
_musicVisualizer?.init(_music!, audioContext);
// NOTE: The Dart Development Webs erver doesnt support
// Accept-Ranges headers for the assets
// so, music looping/seeking doesnt work.
// if you want to allow for seeking/looping please use a webserver
// who suipports accep-range headers
if (_music!.loop) {
if (loopStart > -1 && loopEnd > loopStart) {
loopStart = loopStart / hz.toDouble();
loopEnd = (loopEnd / hz.toDouble()) - 0.1;
_music!.onTimeUpdate.listen((_) {
if (_music!.paused) {
return;
}
if (_music!.currentTime >= loopEnd) {
_music!.currentTime = loopStart;
}
});
}
}
_playPromise = _music!.play().toDart;
_playPromise!.then(
(_) {
musicState = ChannelState.playing;
_music!.onpause = _onPause.toJS;
},
onError: (error) {
bool notAllowedError = false;
String? errorString = error?.toString();
notAllowedError = (errorString != null && errorString.startsWith("NotAllowedError"));
notAllowedError = notAllowedError || (error.isA<DOMException>() && error.name == "NotAllowedError");
if (notAllowedError) {
warn(errorString);
Future.delayed(Duration(milliseconds: 500), () {
playMusic(path, loop, loopStart, loopEnd);
});
}
},
);
}