start static method

Future<WorkerAudioTrack?> start({
  1. required Uint8List bytes,
  2. required int sampleRate,
  3. required int channels,
  4. required Duration depth,
  5. double volume = 1.0,
  6. String workletUrl = kWorkletAssetUrl,
})

Starts a worker-hosted audio track over bytes, or returns null.

Null is the ordinary answer on any page that cannot host one — no shared memory (not cross-origin isolated), no AudioWorklet, no compiled payload, or a container this path cannot open. The player then runs its normal audio pump, exactly as it did before this existed.

workletUrl exists so a test can serve the module from its own tree; production always uses the package asset.

Implementation

static Future<WorkerAudioTrack?> start({
  required Uint8List bytes,
  required int sampleRate,
  required int channels,
  required Duration depth,
  double volume = 1.0,
  String workletUrl = kWorkletAssetUrl,
}) async {
  final sink = await AudioRingSink.open(
    sampleRate: sampleRate,
    channels: channels,
    depth: depth,
    workletUrl: workletUrl,
  );
  if (sink == null) return null;
  sink.volume = volume;

  final Worker worker;
  try {
    worker = await spawn(
      _entry,
      message: <String, Object?>{
        // SHARED, not transferred: both threads must address this same
        // memory, and shared memory in a transfer list is a DataCloneError.
        'ring': PlatformValue(sink.ring.shareable),
        'bytes': bytes,
      },
      timeout: const Duration(seconds: 10),
    );
  } on Object {
    await sink.close();
    return null;
  }

  final track = WorkerAudioTrack._(sink, worker, sampleRate);
  // A container the worker cannot open is not a transport failure and does
  // not look like one: the pump records it and keeps answering. Ask once
  // before committing, so the player falls back instead of playing silence.
  if (await track._failure() != null) {
    await track.close();
    return null;
  }
  return track;
}