insertVideoTrackToAudioOnlyStream method

Future<void> insertVideoTrackToAudioOnlyStream()

Implementation

Future<void> insertVideoTrackToAudioOnlyStream() async {
  if (localUserMediaStream != null && localUserMediaStream!.stream != null) {
    final stream = await _getUserMedia(CallType.kVideo);
    if (stream != null) {
      Logs().d('[VOIP] running replaceTracks() on stream: ${stream.id}');
      _setTracksEnabled(stream.getVideoTracks(), true);
      // replace local tracks
      for (final track in localUserMediaStream!.stream!.getTracks()) {
        try {
          await localUserMediaStream!.stream!.removeTrack(track);
          await track.stop();
        } catch (e) {
          Logs().w('failed to stop track');
        }
      }
      final streamTracks = stream.getTracks();
      for (final newTrack in streamTracks) {
        await localUserMediaStream!.stream!.addTrack(newTrack);
      }

      // remove any screen sharing or remote transceivers, these don't need
      // to be replaced anyway.
      final transceivers = await pc!.getTransceivers();
      transceivers.removeWhere((transceiver) =>
          transceiver.sender.track == null ||
          (localScreenSharingStream != null &&
              localScreenSharingStream!.stream != null &&
              localScreenSharingStream!.stream!
                  .getTracks()
                  .map((e) => e.id)
                  .contains(transceiver.sender.track?.id)));

      // in an ideal case the following should happen
      // - audio track gets replaced
      // - new video track gets added
      for (final newTrack in streamTracks) {
        final transceiver = transceivers.singleWhereOrNull(
            (transceiver) => transceiver.sender.track!.kind == newTrack.kind);
        if (transceiver != null) {
          Logs().d(
              '[VOIP] replacing ${transceiver.sender.track} in transceiver');
          final oldSender = transceiver.sender;
          await oldSender.replaceTrack(newTrack);
          await transceiver.setDirection(
            await transceiver.getDirection() ==
                    TransceiverDirection.Inactive // upgrade, send now
                ? TransceiverDirection.SendOnly
                : TransceiverDirection.SendRecv,
          );
        } else {
          // adding transceiver
          Logs().d('[VOIP] adding track $newTrack to pc');
          await pc!.addTrack(newTrack, localUserMediaStream!.stream!);
        }
      }
      // for renderer to be able to show new video track
      localUserMediaStream?.onStreamChanged
          .add(localUserMediaStream!.stream!);
    }
  }
}