createAnswer method
dynamic
createAnswer
(- int handleId,
- dynamic media,
- dynamic callbacks,
- dynamic customizedSdp
)
Implementation
createAnswer(int handleId, media, callbacks, customizedSdp) {
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 answer (iceDone=" + pluginHandle.iceDone.toString() + ")");
} else {
Janus.log("Creating answer (iceDone=" +
pluginHandle.iceDone.toString() +
", simulcast=" +
simulcast.toString() +
")");
}
var mediaConstraints;
if (Janus.unifiedPlan) {
// We can use Transceivers
mediaConstraints = {};
var audioTransceiver;
var videoTransceiver;
// FIX ME no equivalent call
// var transceivers = pluginHandle.pc.getTransceivers();
// 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) 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) 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) {
try {
if (audioTransceiver.setDirection != null) {
audioTransceiver.setDirection("inactive");
} else {
audioTransceiver.direction = "inactive";
}
Janus.log(
"Setting audio transceiver to inactive:", audioTransceiver);
} catch (e) {
Janus.error(e);
}
}
} else {
// Take care of audio m-line
if (audioSend && audioRecv) {
if (audioTransceiver != null) {
try {
if (audioTransceiver.setDirection != null) {
audioTransceiver.setDirection("sendrecv");
} else {
audioTransceiver.direction = "sendrecv";
}
Janus.log(
"Setting audio transceiver to sendrecv:", audioTransceiver);
} catch (e) {
Janus.error(e);
}
}
} else if (audioSend && !audioRecv) {
try {
if (audioTransceiver != null) {
if (audioTransceiver.setDirection != null) {
audioTransceiver.setDirection("sendonly");
} else {
audioTransceiver.direction = "sendonly";
}
Janus.log(
"Setting audio transceiver to sendonly:", audioTransceiver);
}
} catch (e) {
Janus.error(e);
}
} else if (!audioSend && audioRecv) {
if (audioTransceiver != null) {
try {
if (audioTransceiver.setDirection != null) {
audioTransceiver.setDirection("recvonly");
} else {
audioTransceiver.direction = "recvonly";
}
Janus.log(
"Setting audio transceiver to recvonly:", audioTransceiver);
} catch (e) {
Janus.error(e);
}
} else {
// In theory, this is the only case where we might not have a transceiver yet
// FIX ME no addTransceiver call
// audioTransceiver =
// pc.addTransceiver("audio", {'direction': "recvonly"});
// Janus.log("Adding recvonly audio transceiver:", audioTransceiver);
Janus.log("No addTransceiver call");
}
}
}
// 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) {
try {
if (videoTransceiver.setDirection != null) {
videoTransceiver.setDirection("inactive");
} else {
videoTransceiver.direction = "inactive";
}
Janus.log(
"Setting video transceiver to inactive:", videoTransceiver);
} catch (e) {
Janus.error(e);
}
}
} else {
// Take care of video m-line
if (videoSend && videoRecv) {
if (videoTransceiver != null) {
try {
if (videoTransceiver.setDirection != null) {
videoTransceiver.setDirection("sendrecv");
} else {
videoTransceiver.direction = "sendrecv";
}
Janus.log(
"Setting video transceiver to sendrecv:", videoTransceiver);
} catch (e) {
Janus.error(e);
}
}
} else if (videoSend && !videoRecv) {
if (videoTransceiver != null) {
try {
if (videoTransceiver.setDirection != null) {
videoTransceiver.setDirection("sendonly");
} else {
videoTransceiver.direction = "sendonly";
}
Janus.log(
"Setting video transceiver to sendonly:", videoTransceiver);
} catch (e) {
Janus.error(e);
}
}
} else if (!videoSend && videoRecv) {
if (videoTransceiver != null) {
try {
if (videoTransceiver.setDirection != null) {
videoTransceiver.setDirection("recvonly");
} else {
videoTransceiver.direction = "recvonly";
}
Janus.log(
"Setting video transceiver to recvonly:", videoTransceiver);
} catch (e) {
Janus.error(e);
}
} else {
// In theory, this is the only case where we might not have a transceiver yet
// FIX ME
// videoTransceiver =
// pc.addTransceiver("video", {'direction': "recvonly"});
// Janus.log("Adding recvonly video transceiver:", videoTransceiver);
Janus.log("No addTransciever call");
}
}
}
} else {
if (Janus.webRTCAdapter['browserDetails']['browser'] == "firefox" ||
Janus.webRTCAdapter['browserDetails']['browser'] == "edge") {
mediaConstraints = {
'offerToReceiveAudio': isAudioRecvEnabled(media),
'offerToReceiveVideo': isVideoRecvEnabled(media)
};
} else {
mediaConstraints = {
'mandatory': {
'OfferToReceiveAudio': isAudioRecvEnabled(media),
'OfferToReceiveVideo': isVideoRecvEnabled(media)
}
};
}
}
Janus.debug(mediaConstraints);
// Check if this is Firefox and we've been asked to do simulcasting
var 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()[1];
// Janus.log(sender);
// var parameters = sender.getParameters();
// Janus.log(parameters);
// var maxBitrates = getMaxBitrates(callbacks.simulcastMaxBitrates);
// sender.setParameters({
// 'encodings': [
// {
// 'rid': "high",
// 'active': true,
// 'priority': "high",
// 'maxBitrate': maxBitrates['high']
// },
// {
// 'rid': "medium",
// 'active': true,
// 'priority': "medium",
// 'maxBitrate': maxBitrates['medium']
// },
// {
// 'rid': "low",
// 'active': true,
// 'priority': "low",
// 'maxBitrate': maxBitrates['low']
// }
// ]
// });
}
pluginHandle.pc
.createAnswer(mediaConstraints)
.then((RTCSessionDescription answer) {
Janus.debug(answer.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(answer.sdp, answer.type);
// FIX ME
// if (callbacks.customizeSdp != null && callbacks.customizeSdp is Function)
// callbacks.customizeSdp(jsep);
answer.sdp = jsep.sdp;
Janus.log("Setting local description");
if (sendVideo && simulcast) {
// This SDP munging only works with Chrome
if (Janus.webRTCAdapter['browserDetails']['browser'] == "chrome") {
// FIXME Apparently trying to simulcast when answering breaks video in Chrome...
//~ Janus.log("Enabling Simulcasting for Chrome (SDP munging)");
//~ answer.sdp = mungeSdpForSimulcasting(answer.sdp);
Janus.warn(
"simulcast=true, but this is an answer, and video breaks in Chrome if we enable it");
} else if (Janus.webRTCAdapter['browserDetails']['browser'] !=
"firefox") {
Janus.warn(
"simulcast=true, but this is not Chrome nor Firefox, ignoring");
}
}
pluginHandle.mySdp = answer.sdp;
pluginHandle.pc.setLocalDescription(answer).catchError(callbacks.error);
pluginHandle.mediaConstraints = mediaConstraints;
if (pluginHandle.iceDone == null && pluginHandle.trickle == null) {
// Don't do anything until we have all candidates
Janus.log("Waiting for all candidates...");
return;
}
callbacks.success(answer);
}).catchError((error, StackTrace stackTrace) {
callbacks.error(error);
});
}