publishAudioTrack method

Future<LocalTrackPublication<LocalAudioTrack>> publishAudioTrack(
  1. LocalAudioTrack track, {
  2. AudioPublishOptions? publishOptions,
})

Publish an AudioTrack to the Room. For most cases, using setMicrophoneEnabled would be simpler and recommended.

Implementation

Future<LocalTrackPublication<LocalAudioTrack>> publishAudioTrack(
  LocalAudioTrack track, {
  AudioPublishOptions? publishOptions,
}) async {
  if (audioTrackPublications.any((e) => e.track?.mediaStreamTrack.id == track.mediaStreamTrack.id)) {
    throw TrackPublishException('track already exists');
  }

  // Use defaultPublishOptions if options is null
  publishOptions ??= track.lastPublishOptions ?? room.roomOptions.defaultAudioPublishOptions;

  final audioEncoding = publishOptions.encoding ?? AudioEncoding.presetMusic;
  final List<rtc.RTCRtpEncoding> encodings = [audioEncoding.toRTCRtpEncoding()];

  final req = lk_rtc.AddTrackRequest(
    cid: track.getCid(),
    name: publishOptions.name ?? AudioPublishOptions.defaultMicrophoneName,
    type: track.kind.toPBType(),
    source: track.source.toPBType(),
    muted: track.muted,
    stream: buildStreamId(publishOptions, track.source),
    disableDtx: !publishOptions.dtx,
    disableRed: room.e2eeManager != null ? true : publishOptions.red ?? true,
    encryption: room.roomOptions.lkEncryptionType,
  );

  // Populate audio features (e.g., TF_NO_DTX, TF_PRECONNECT_BUFFER)
  req.audioFeatures.addAll([
    if (!publishOptions.dtx) lk_models.AudioTrackFeature.TF_NO_DTX,
    if (publishOptions.preConnect) lk_models.AudioTrackFeature.TF_PRECONNECT_BUFFER,
  ]);

  Future<lk_models.TrackInfo> negotiate() async {
    track.transceiver = await room.engine.createTransceiverRTCRtpSender(track, publishOptions!, encodings);
    await room.engine.negotiate();
    return lk_models.TrackInfo();
  }

  late lk_models.TrackInfo trackInfo;
  if (room.engine.enabledPublishCodecs?.isNotEmpty ?? false) {
    final rets = await Future.wait<lk_models.TrackInfo>([room.engine.addTrack(req), negotiate()]);
    trackInfo = rets[0];
  } else {
    trackInfo = await room.engine.addTrack(req);

    final transceiverInit = rtc.RTCRtpTransceiverInit(
      direction: rtc.TransceiverDirection.SendOnly,
      sendEncodings: encodings,
    );
    // addTransceiver cannot pass in a kind parameter due to a bug in flutter-webrtc (web)
    track.transceiver = await room.engine.publisher?.pc.addTransceiver(
      track: track.mediaStreamTrack,
      kind: rtc.RTCRtpMediaType.RTCRtpMediaTypeAudio,
      init: transceiverInit,
    );

    await room.engine.negotiate();
  }

  logger.fine('publishAudioTrack engine.addTrack response: ${trackInfo}');

  track.lastPublishOptions = publishOptions;

  final pub = LocalTrackPublication<LocalAudioTrack>(
    participant: this,
    info: trackInfo,
    track: track,
  );
  addTrackPublication(pub);

  // did publish
  await track.onPublish();
  await track.processor?.onPublish(room);

  await room.applyAudioSpeakerSettings();

  final listener = track.createListener();
  listener.on((TrackEndedEvent event) async {
    logger.fine('TrackEndedEvent: ${event.track}');
    await removePublishedTrack(pub.sid);
  });

  [events, room.events].emit(LocalTrackPublishedEvent(
    participant: this,
    publication: pub,
  ));

  await track.start();

  return pub;
}