createOffer method

dynamic createOffer (
  1. int handleId,
  2. Map<String, dynamic> media,
  3. Callbacks callbacks
)

Implementation

createOffer(int handleId, Map<String, dynamic> media, Callbacks callbacks) {
  Plugin pluginHandle = this.pluginHandles[handleId.toString()];
  if (pluginHandle == null) {
    Janus.warn("Invalid handle");
    callbacks.error("Invalid handle");
    return;
  }
  bool simulcast = (callbacks.simulcast == true);
  if (!simulcast) {
    Janus.log(
        "Creating offer (iceDone=" + pluginHandle.iceDone.toString() + ")");
  } else {
    Janus.log("Creating offer (iceDone=" +
        pluginHandle.iceDone.toString() +
        ", simulcast=" +
        simulcast.toString() +
        ")");
  }
  // https://code.google.com/p/webrtc/issues/detail?id=3508
  Map<String, dynamic> mediaConstraints = {};
  if (Janus.unifiedPlan) {
    // We can use Transceivers
    var audioTransceiver;
    var videoTransceiver;
    // FIX ME
    // var transceivers = pc.getTransceivers();
    var transceivers = [];
    if (transceivers != null && transceivers.length > 0) {
      for (var t in transceivers) {
        if ((t['sender'] &&
                t['sender'].track &&
                t['sender'].track.kind == "audio") ||
            (t['receiver'] &&
                t['receiver'].track &&
                t['receiver'].track.kind == "audio")) {
          if (audioTransceiver == null) {
            audioTransceiver = t;
          }
          continue;
        }
        if ((t['sender'] &&
                t['sender'].track &&
                t['sender'].track.kind == "video") ||
            (t['receiver'] &&
                t['receiver'].track &&
                t['receiver'].track.kind == "video")) {
          if (videoTransceiver == null) {
            videoTransceiver = t;
          }
          continue;
        }
      }
    }
    // Handle audio (and related changes, if any)
    var audioSend = isAudioSendEnabled(media);
    var audioRecv = isAudioRecvEnabled(media);
    if (!audioSend && !audioRecv) {
      // Audio disabled: have we removed it?
      if (media['removeAudio'] && audioTransceiver) {
        if (audioTransceiver.setDirection != null) {
          audioTransceiver.setDirection("inactive");
        } else {
          audioTransceiver.direction = "inactive";
        }
        Janus.log("Setting audio transceiver to inactive:", audioTransceiver);
      }
    } else {
      // Take care of audio m-line
      if (audioSend && audioRecv) {
        if (audioTransceiver != null) {
          if (audioTransceiver.setDirection != null) {
            audioTransceiver.setDirection("sendrecv");
          } else {
            audioTransceiver.direction = "sendrecv";
          }
          Janus.log(
              "Setting audio transceiver to sendrecv:", audioTransceiver);
        }
      } else if (audioSend && !audioRecv) {
        if (audioTransceiver != null) {
          if (audioTransceiver.setDirection != null) {
            audioTransceiver.setDirection("sendonly");
          } else {
            audioTransceiver.direction = "sendonly";
          }
          Janus.log(
              "Setting audio transceiver to sendonly:", audioTransceiver);
        }
      } else if (!audioSend && audioRecv) {
        if (audioTransceiver != null) {
          if (audioTransceiver.setDirection != null) {
            audioTransceiver.setDirection("recvonly");
          } else {
            audioTransceiver.direction = "recvonly";
          }
          Janus.log(
              "Setting audio transceiver to recvonly:", audioTransceiver);
        } else {
          // FIX ME
          // // In theory, this is the only case where we might not have a transceiver yet
          // audioTransceiver =
          //     pc.addTransceiver("audio", {'direction': "recvonly"});
          // Janus.log("Adding recvonly audio transceiver:", audioTransceiver);
          Janus.log("addTransceiver is not supported");
        }
      }
    }
    // Handle video (and related changes, if any)
    var videoSend = isVideoSendEnabled(media);
    var videoRecv = isVideoRecvEnabled(media);
    if (!videoSend && !videoRecv) {
      // Video disabled: have we removed it?
      if (media['removeVideo'] && videoTransceiver != null) {
        if (videoTransceiver.setDirection != null) {
          videoTransceiver.setDirection("inactive");
        } else {
          videoTransceiver.direction = "inactive";
        }
        Janus.log("Setting video transceiver to inactive:", videoTransceiver);
      }
    } else {
      // Take care of video m-line
      if (videoSend && videoRecv) {
        if (videoTransceiver != null) {
          if (videoTransceiver.setDirection != null) {
            videoTransceiver.setDirection("sendrecv");
          } else {
            videoTransceiver.direction = "sendrecv";
          }
          Janus.log(
              "Setting video transceiver to sendrecv:", videoTransceiver);
        }
      } else if (videoSend && !videoRecv) {
        if (videoTransceiver != null) {
          if (videoTransceiver.setDirection != null) {
            videoTransceiver.setDirection("sendonly");
          } else {
            videoTransceiver.direction = "sendonly";
          }
          Janus.log(
              "Setting video transceiver to sendonly:", videoTransceiver);
        }
      } else if (!videoSend && videoRecv) {
        if (videoTransceiver != null) {
          if (videoTransceiver.setDirection != null) {
            videoTransceiver.setDirection("recvonly");
          } else {
            videoTransceiver.direction = "recvonly";
          }
          Janus.log(
              "Setting video transceiver to recvonly:", videoTransceiver);
        } else {
          // FIX ME
          // In theory, this is the only case where we might not have a transceiver yet
          // videoTransceiver =
          //     pc.addTransceiver("video", {'direction': "recvonly"});
          // Janus.log("Adding recvonly video transceiver:", videoTransceiver);
          Janus.log("addTransceiver is not supported");
        }
      }
    }
  } else {
    mediaConstraints["offerToReceiveAudio"] = isAudioRecvEnabled(media);
    mediaConstraints["offerToReceiveVideo"] = isVideoRecvEnabled(media);
  }
  bool iceRestart = (callbacks.iceRestart == true);
  if (iceRestart) {
    mediaConstraints["iceRestart"] = true;
  }
  Janus.debug(mediaConstraints);
  // Check if this is Firefox and we've been asked to do simulcasting
  bool sendVideo = isVideoSendEnabled(media);
  if (sendVideo &&
      simulcast &&
      Janus.webRTCAdapter['browserDetails']['browser'] == "firefox") {
    // FIXME Based on https://gist.github.com/voluntas/088bc3cc62094730647b
    Janus.log("Enabling Simulcasting for Firefox (RID)");
    // FIX ME No equivalent call
    // var sender = pc.getSenders().find((s) {
    //   return s.track.kind == "video";
    // });
    // if (sender) {
    //   var parameters = sender.getParameters();
    //   if (!parameters) {
    //     parameters = {};
    //   }
    //   var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates);
    //   parameters.encodings = [
    //     {'rid': "h", 'active': true, 'maxBitrate': maxBitrates['high']},
    //     {
    //       'rid': "m",
    //       'active': true,
    //       'maxBitrate': maxBitrates['medium'],
    //       'scaleResolutionDownBy': 2
    //     },
    //     {
    //       'rid': "l",
    //       'active': true,
    //       'maxBitrate': maxBitrates['low'],
    //       'scaleResolutionDownBy': 4
    //     }
    //   ];
    //   sender.setParameters(parameters);
    // }
  }

  pluginHandle.pc
      .createOffer(mediaConstraints)
      .then((RTCSessionDescription offer) {
    Janus.debug(offer.toString());
    // JSON.stringify doesn't work on some WebRTC objects anymore
    // See https://code.google.com/p/chromium/issues/detail?id=467366
    // RTCSessionDescription jsep = RTCSessionDescription(offer.sdp, offer.type);
    // FIX ME
    // callbacks.customizeSdp(jsep);
    // offer.sdp = offer.sdp;
    Janus.log("Setting local description");
    if (sendVideo && simulcast) {
      // This SDP munging only works with Chrome (Safari STP may support it too)
      if (Janus.webRTCAdapter['browserDetails']['browser'] == "chrome" ||
          Janus.webRTCAdapter['browserDetails']['browser'] == "safari") {
        Janus.log("Enabling Simulcasting for Chrome (SDP munging)");
        offer.sdp = mungeSdpForSimulcasting(offer.sdp);
      } else if (Janus.webRTCAdapter['browserDetails']['browser'] !=
          "firefox") {
        Janus.warn(
            "simulcast=true, but this is not Chrome nor Firefox, ignoring");
      }
    }
    pluginHandle.mySdp = offer.sdp;
    pluginHandle.pc.setLocalDescription(offer);
    pluginHandle.mediaConstraints = mediaConstraints;
    if (pluginHandle.iceDone == false && pluginHandle.trickle == false) {
      // Don't do anything until we have all candidates
      Janus.log("Waiting for all candidates...");
      return;
    }
    Janus.log("Offer ready");
    callbacks.success(offer);
  }).catchError((error, StackTrace stackTrace) {
    callbacks.error(error);
  });
}