addSubscribedMediaTrack method

  1. @internal
Future<void> addSubscribedMediaTrack(
  1. MediaStreamTrack mediaTrack,
  2. MediaStream stream,
  3. String trackSid, {
  4. RTCRtpReceiver? receiver,
  5. AudioOutputOptions audioOutputOptions = const AudioOutputOptions(),
})

Implementation

@internal
Future<void> addSubscribedMediaTrack(
  rtc.MediaStreamTrack mediaTrack,
  rtc.MediaStream stream,
  String trackSid, {
  rtc.RTCRtpReceiver? receiver,
  AudioOutputOptions audioOutputOptions = const AudioOutputOptions(),
}) async {
  logger.fine('addSubscribedMediaTrack()');

  // If publication doesn't exist yet...
  RemoteTrackPublication? pub = getTrackPublicationBySid(trackSid);
  if (pub == null) {
    logger.fine('addSubscribedMediaTrack() pub is null, will wait...');
    logger.fine('addSubscribedMediaTrack() tracks: $trackPublications');
    // Wait for the metadata to arrive
    final event = await events.waitFor<TrackPublishedEvent>(
      filter: (event) =>
          event.participant == this && event.publication.sid == trackSid,
      duration: room.connectOptions.timeouts.publish,
      onTimeout: () => throw TrackSubscriptionExceptionEvent(
        participant: this,
        sid: trackSid,
        reason: TrackSubscribeFailReason.notTrackMetadataFound,
      ),
    );
    pub = event.publication;
    logger.fine('addSubscribedMediaTrack() did receive pub');
  }

  // Check if track type is supported, throw if not.
  if (![lk_models.TrackType.AUDIO, lk_models.TrackType.VIDEO]
      .contains(pub.kind.toPBType())) {
    throw TrackSubscriptionExceptionEvent(
      participant: this,
      sid: trackSid,
      reason: TrackSubscribeFailReason.unsupportedTrackType,
    );
  }

  // create Track
  final RemoteTrack track;
  if (pub.kind == TrackType.VIDEO) {
    // video track
    track =
        RemoteVideoTrack(pub.source, stream, mediaTrack, receiver: receiver);
  } else if (pub.kind == TrackType.AUDIO) {
    // audio track
    track =
        RemoteAudioTrack(pub.source, stream, mediaTrack, receiver: receiver);

    var listener = track.createListener();
    listener.on<AudioPlaybackStarted>((event) {
      logger.fine('AudioPlaybackStarted');
      room.engine.events.emit(event);
    });

    listener.on<AudioPlaybackFailed>((event) {
      logger.fine('AudioPlaybackFailed');
      room.engine.events.emit(event);
    });
  } else {
    throw UnexpectedStateException('Unknown track type');
  }

  /// Apply audio output selection for the web.
  if (pub.kind == TrackType.AUDIO && lkPlatformIs(PlatformType.web)) {
    if (audioOutputOptions.deviceId != null) {
      await (track as RemoteAudioTrack)
          .setSinkId(audioOutputOptions.deviceId!);
    }
  }

  await pub.updateTrack(track);
  await pub.updateSubscriptionAllowed(true);
  addTrackPublication(pub);

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

  await track.start();
}