connectSendTransportAudio function

Future<void> connectSendTransportAudio(
  1. ConnectSendTransportAudioOptions options
)

Sets up and connects the audio stream for media sharing, handling updates to local audio streams and producer transports.

Parameters:

  • options (ConnectSendTransportAudioOptions): Options containing:
    • stream (MediaStream): The audio stream to be used.
    • audioConstraints (Map<String, dynamic>): Constraints for the audio stream, if any.
    • targetOption (String?): Specifies the target option for connection ('all' by default).
    • parameters (ConnectSendTransportAudioParameters): Contains all necessary parameters and update functions.

Workflow:

  1. Audio Track Handling:
    • Checks for any existing audio tracks in the local stream (localStream or localStreamAudio) and removes them.
  2. Media Constraints:
    • Retrieves audioConstraints and fetches a new audio stream based on these constraints.
  3. Stream and Track Management:
    • Adds the new audio track to the localStream, removing any existing tracks.
  4. Transport Production:
    • Produces the audio data for transport using producerTransport, enabling audio streaming from the local device.

Returns:

  • A Future<void> which completes after setting up the audio stream and connecting the producer transport.

Example Usage:

final audioOptions = ConnectSendTransportAudioOptions(
  stream: myAudioStream,
  targetOption: 'all',
  audioConstraints: myAudioConstraints,
  parameters: myConnectSendTransportAudioParameters,
);

connectSendTransportAudio(audioOptions).then(() {
  print("Audio stream successfully set up for sharing.");
}).catchError((error) {
  print("Error setting up audio stream: $error");
});

Error Handling:

  • Logs errors to the console if showAlert is available in debug mode.

Implementation

Future<void> connectSendTransportAudio(
    ConnectSendTransportAudioOptions options) async {
  try {
    final audioConstraints = options.audioConstraints;
    MediaStream stream = options.stream;
    final ConnectSendTransportAudioParameters parameters = options.parameters;
    final targetOption = options.targetOption;

    // Destructuring the parameters for easier access
    MediaStream? localStreamAudio =
        parameters.getUpdatedAllParams().localStreamAudio;
    // Check if localStream exists and update accordingly
    MediaStream? localStream = parameters.localStream;

    // Close the existing audio track
    if (localStream != null) {
      var audioTracks = localStream.getAudioTracks().toList();
      for (var track in audioTracks) {
        await localStream.removeTrack(track);
      }
    }

    if (localStreamAudio != null) {
      var audioTracks = localStreamAudio.getAudioTracks().toList();
      for (var track in audioTracks) {
        await localStreamAudio.removeTrack(track);
      }
    }

    stream = await navigator.mediaDevices
        .getUserMedia(audioConstraints ?? {'audio': true});

    parameters.updateLocalStreamAudio(stream);

    // Add video track to localStream
    if (localStream == null) {
      localStream = stream;

      // Update the localStream
      parameters.updateLocalStream(localStream);
    } else {
      // Remove existing video tracks from localStream
      for (var track in localStream.getAudioTracks().toList()) {
        await parameters.localStream!.removeTrack(track);
      }

      // Add the new video track to the localStream
      await localStream.addTrack(stream.getAudioTracks().first);
      parameters.updateLocalStream(localStream);
    }

    // Connect the send transport for audio by producing audio data
    //get the first codec from the first video track
    if (targetOption == 'all' || targetOption == 'remote') {
      parameters.producerTransport!.produce(
        track: stream.getAudioTracks().first,
        stream: stream,
        source: 'mic',
      );
    }

    //Update the audio level
    if (parameters.audioProducer == null) {
      Future.delayed(const Duration(seconds: 1), () {
        updateMicLevel(parameters.getUpdatedAllParams().audioProducer,
            parameters.updateAudioLevel);
      });
    } else {
      updateMicLevel(parameters.audioProducer, parameters.updateAudioLevel);
    }

    // Update the audio producer and producer transport objects
    parameters.updateProducerTransport(parameters.producerTransport!);

    if (targetOption == 'all' || targetOption == 'local') {
      try {
        final optionsLocal = ConnectSendTransportAudioOptions(
          stream: stream,
          parameters: parameters,
          audioConstraints: audioConstraints,
        );
        await connectLocalSendTransportAudio(
          options: optionsLocal,
        );

        if (targetOption == 'local') {
          if (parameters.localAudioProducer == null) {
            Future.delayed(const Duration(seconds: 1), () {
              updateMicLevel(
                  parameters.getUpdatedAllParams().localAudioProducer,
                  parameters.updateAudioLevel);
            });
          } else {
            updateMicLevel(
                parameters.localAudioProducer, parameters.updateAudioLevel);
          }
        }
      } catch (error) {
        if (kDebugMode) {
          print('Error connecting local audio transport: $error');
        }
      }
    }
  } catch (error) {
    // Handle error if showAlert is available
    if (kDebugMode) {
      print('connectSendTransportAudio error: $error');
    }
  }
}