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;
}