restartTrack method

Future<void> restartTrack([
  1. LocalTrackOptions? options
])

Restarts the track with new options. This is useful when switching between front and back cameras.

Implementation

Future<void> restartTrack([
  LocalTrackOptions? options,
]) async {
  if (sender == null) throw TrackCreateException('could not restart track');
  if (options != null && currentOptions.runtimeType != options.runtimeType) {
    throw Exception('options must be a ${currentOptions.runtimeType}');
  }

  currentOptions = options ?? currentOptions;

  // stop if not already stopped...
  await _stopKeepingProcessor();

  // create new track with options
  final newStream = await LocalTrack.createStream(currentOptions);
  final newTrack = newStream.getTracks().first;

  // set new stream & track to this object
  updateMediaStreamAndTrack(newStream, newTrack);

  // Restart the processor on the new track before the sender gets it, so
  // the sender carries the processed track when the processor has one.
  final processor = _processor;
  if (processor != null) {
    try {
      await processor.restart(
        kind == TrackType.VIDEO ? VideoProcessorOptions(track: newTrack) : AudioProcessorOptions(track: newTrack),
      );
      final processedTrack = processor.processedTrack;
      if (processedTrack != null) {
        setProcessedTrack(processedTrack);
      }
    } catch (error) {
      logger.severe('TrackProcessor.restart() did throw $error');
    }
  }

  // replace track on sender
  try {
    await sender?.replaceTrack(mediaStreamTrack);
    if (this is LocalVideoTrack) {
      final videoTrack = this as LocalVideoTrack;
      await videoTrack.replaceTrackForMultiCodecSimulcast(mediaStreamTrack);
    }
  } catch (error) {
    logger.severe('RTCRtpSender.replaceTrack() did throw $error');
  }

  // mark as started
  await start();

  // notify so VideoView can re-compute mirror mode if necessary
  events.emit(
    LocalTrackOptionsUpdatedEvent(
      track: this,
      options: currentOptions,
    ),
  );
}