enableShare method

Future<void> enableShare(
  1. DesktopCapturerSource? source, {
  2. bool iosPermissionGiven = false,
})

Implementation

Future<void> enableShare(DesktopCapturerSource? source,
    {bool iosPermissionGiven = false}) async {
  //
  if (_screenShareInProgress) {
    //
    return;
  }

  if (source == null) {
    if (!kIsWeb && (Platform.isWindows || Platform.isMacOS)) {
      var sources =
          await desktopCapturer.getSources(types: [SourceType.Screen]);

      _selectedScreenSource = sources.first;
    }
  } else {
    _selectedScreenSource = source;
  }

  Span? enableShareSpan;
  try {
    if (videoSDKTelemetery != null) {
      enableShareSpan = videoSDKTelemetery!.trace(
        spanName: 'enableShare() Calling',
      );
    }
  } catch (error) {}

  if (isMobilePlatform()) {
    if (Platform.isIOS && !iosPermissionGiven) {
      VideoSDK.requestIOSScreenSharePermission();

      if (enableShareSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: enableShareSpan,
            message: 'Permission not granted in iOS',
            status: StatusCode.error);
      }

      return;
    }

    if (Platform.isAndroid) {
      try {
        bool androidPermission = await Helper.requestCapturePermission();

        if (!androidPermission) {
          if (enableShareSpan != null) {
            videoSDKTelemetery!.completeSpan(
                span: enableShareSpan,
                message: 'Permission not granted in android',
                status: StatusCode.error);
          }
          return;
        }

        //
        await FlutterForegroundTask.startService(
            notificationTitle: _notification.title,
            notificationText: _notification.message,
            callback: null);
      } catch (error) {
        //
        VideoSDKLog.createLog(
            message:
                "error in starting foreground service \n ${error.toString()}",
            logLevel: "WARN");

        if (enableShareSpan != null) {
          videoSDKTelemetery!.completeSpan(
              span: enableShareSpan,
              message:
                  'error in starting foreground service ${error.toString()}',
              status: StatusCode.error);
        }
        //
        log("error => $error");
      }
    }
  }

  //
  _screenShareInProgress = true;

  //
  MediaStream? shareStream;
  MediaStreamTrack? videoTrack;
  MediaStreamTrack? audioTrack;

  Span? _internalSpan;
  Span? trackSpan;
  Span? producerSpan;
  Span? audioProducerSpan;
  try {
    try {
      if (enableShareSpan != null) {
        _internalSpan = videoSDKTelemetery!.trace(
          spanName: 'Generating Producer Configuration',
          span: enableShareSpan,
        );
      }
    } catch (error) {}
    //
    RtpCodecCapability? videoCodec = _device!.rtpCapabilities.codecs.firstWhere(
        (RtpCodecCapability c) {
      return c.mimeType.toLowerCase() == 'video/vp9' ||
          c.mimeType.toLowerCase() == 'video/vp8';
    },
        // (RtpCodecCapability c) => c.mimeType.toLowerCase() == 'video/h264',
        orElse: () {
      //
      VideoSDKLog.createLog(
          message:
              "Error in enableShare() \n desired vp9 codec+configuration is not supported",
          logLevel: "ERROR");

      if (_internalSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: _internalSpan,
            message: 'vp9 codec+configuration is not supported',
            status: StatusCode.error);
      }

      if (enableShareSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: enableShareSpan,
            message: 'vp9 codec+configuration is not supported',
            status: StatusCode.error);
      }
      //
      throw 'desired vp9 codec+configuration is not supported';
    });

    try {
      if (_internalSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: _internalSpan,
            message: 'Producer Configuration Generated',
            status: StatusCode.ok);

        _internalSpan = null;
      }
    } catch (error) {}

    //
    shareStream = await _createShareStream(enableShareSpan);

    if (shareStream != null) {
      try {
        if (enableShareSpan != null) {
          trackSpan = videoSDKTelemetery!.trace(
            spanName: 'Creating Track',
            span: enableShareSpan,
          );
        }
      } catch (error) {}

      //
      videoTrack = shareStream.getVideoTracks().first;
      if (shareStream.getAudioTracks().isNotEmpty) {
        audioTrack = shareStream.getAudioTracks().first;
      }

      try {
        if (trackSpan != null) {
          videoSDKTelemetery!.completeSpan(
              span: trackSpan,
              message:
                  'Track Generated with videoTrack ${videoTrack.toString()} & audioTrack ${audioTrack != null ? audioTrack.toString() : 'No audio'}',
              status: StatusCode.ok);

          trackSpan = null;
        }
      } catch (error) {}

      //
      _screenShareInProgress = true;

      try {
        if (enableShareSpan != null) {
          producerSpan = videoSDKTelemetery!.trace(
            spanName: 'Creating Share Producer',
            span: enableShareSpan,
          );
        }
      } catch (error) {}
      //
      _sendTransport!.produce(
        track: videoTrack,
        codecOptions: ProducerCodecOptions(
          videoGoogleStartBitrate: 1000,
        ),
        stream: shareStream,
        appData: {'share': true},
        source: 'screen',
        codec: videoCodec,
      );

      try {
        if (producerSpan != null) {
          videoSDKTelemetery!.completeSpan(
              span: producerSpan,
              message: 'Share Producer Created',
              status: StatusCode.ok);

          producerSpan = null;
        }
      } catch (error) {}

      if (audioTrack != null) {
        try {
          if (enableShareSpan != null) {
            audioProducerSpan = videoSDKTelemetery!.trace(
              spanName: 'Creating Share Audio Producer',
              span: enableShareSpan,
            );
          }
        } catch (error) {}

        _sendTransport!.produce(
            track: audioTrack,
            codecOptions: ProducerCodecOptions(
              opusStereo: 1,
              opusDtx: 1,
            ),
            stream: shareStream,
            appData: {'share': true},
            source: 'screen-audio');

        if (audioProducerSpan != null) {
          videoSDKTelemetery!.completeSpan(
              span: audioProducerSpan,
              message: 'Share Audio Producer Created',
              status: StatusCode.ok);

          audioProducerSpan = null;
        }
      }

      if (enableShareSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: enableShareSpan,
            message: 'Enable ScreenShare Successful',
            status: StatusCode.ok);
      }
    } else {
      if (enableShareSpan != null) {
        videoSDKTelemetery!.completeSpan(
            span: enableShareSpan,
            message: 'Enable ScreenShare Failed due to stream null',
            status: StatusCode.error);
      }
    }
  } catch (error) {
    //
    log('error enable share  error => $error');

    //
    _screenShareInProgress = false;

    if (!kIsWeb) {
      if (Platform.isAndroid) {
        //
        FlutterForegroundTask.stopService();
      }
    }

    //
    if (shareStream != null) {
      await shareStream.dispose();
    }
    if (error.toString().contains("Permission denied")) {
      //
      VideoSDKLog.createLog(
          message: "Error in enableShare() \n ${error.toString()}",
          logLevel: "WARN");
      //
      _eventEmitter.emit("error", VideoSDKErrors[3014]);
    } else {
      //
      VideoSDKLog.createLog(
          message: "Error in enableShare() \n ${error.toString()}",
          logLevel: "ERROR");
      //
      _eventEmitter.emit("error", VideoSDKErrors[3013]);
    }

    if (trackSpan != null) {
      videoSDKTelemetery!.completeSpan(
          span: trackSpan,
          message: 'Track Generation Failed',
          status: StatusCode.error);
    }

    if (producerSpan != null) {
      videoSDKTelemetery!.completeSpan(
          span: producerSpan,
          message: 'Share Producer Creation Failed',
          status: StatusCode.error);
    }

    if (audioProducerSpan != null) {
      videoSDKTelemetery!.completeSpan(
          span: audioProducerSpan,
          message: 'Share Audio Creation Failed',
          status: StatusCode.error);
    }

    if (enableShareSpan != null) {
      videoSDKTelemetery!.completeSpan(
          span: enableShareSpan,
          message: 'Enable ScreenShare Failed \n ${error.toString()}',
          status: StatusCode.error);
    }
  }
}