play static method
Plays the provided asset
.
If the returned Stream is canceled, then the playback stops.
Implementation
static Stream<void> play(String asset, {bool loop = false}) {
Log.debug('play($asset, loop: $loop)', 'WebUtils');
StreamController? controller;
StreamSubscription? onEnded;
web.AudioBufferSourceNode? node;
controller = StreamController(
onListen: () async {
_context ??= web.AudioContext();
if (_context?.state == 'suspended') {
Log.debug(
'play($asset, loop: $loop) -> _context?.state == `suspended`, resuming',
'WebUtils',
);
await (_context?.resume())?.toDart;
}
if (controller?.hasListener == false) {
return;
}
if (_context == null) {
throw Exception('AudioContext is `null`, cannot `play($asset)`');
}
final web.AudioBufferSourceNode source = _context!.createBufferSource();
final Response bytes = await (await PlatformUtils.dio).get(
'assets/assets/$asset',
options: Options(responseType: ResponseType.bytes),
);
if (controller?.hasListener == false) {
return;
}
final JSPromise<web.AudioBuffer> audioBuffer = _context!
.decodeAudioData((bytes.data as Uint8List).buffer.toJS);
node = source;
source.buffer = await audioBuffer.toDart;
if (controller?.hasListener == false) {
return;
}
source.loop = loop;
source.connect(_context!.destination);
source.start();
onEnded = source.onEnded.listen((_) {
controller?.close();
});
},
onCancel: () {
onEnded?.cancel();
node?.stop();
controller?.close();
},
);
return controller.stream;
}