// Mangle SDP to prefer ISAC/16000 over any other audio codec. private string preferISAC(string sdpDescription) { string[] lines = sdpDescription.Split("\n", true); int mLineIndex = -1; string isac16kRtpMap = null; Java.Util.Regex.Pattern isac16kPattern = Java.Util.Regex.Pattern.Compile("^a=rtpmap:(\\d+) ISAC/16000[\r]?$"); for (int i = 0; (i < lines.Length) && (mLineIndex == -1 || isac16kRtpMap == null); ++i) { if (lines[i].StartsWith("m=audio ")) { mLineIndex = i; continue; } Matcher isac16kMatcher = isac16kPattern.Matcher(lines[i]); if (isac16kMatcher.Matches()) { isac16kRtpMap = isac16kMatcher.Group(1); continue; } } if (mLineIndex == -1) { Log.Debug(TAG, "No m=audio line, so can't prefer iSAC"); return(sdpDescription); } if (isac16kRtpMap == null) { Log.Debug(TAG, "No ISAC/16000 line, so can't prefer iSAC"); return(sdpDescription); } string[] origMLineParts = lines[mLineIndex].Split(" ", true); StringBuilder newMLine = new StringBuilder(); int origPartIndex = 0; // Format is: m=<media> <port> <proto> <fmt> ... newMLine.Append(origMLineParts[origPartIndex++]).Append(" "); newMLine.Append(origMLineParts[origPartIndex++]).Append(" "); newMLine.Append(origMLineParts[origPartIndex++]).Append(" "); newMLine.Append(isac16kRtpMap).Append(" "); for (; origPartIndex < origMLineParts.Length; ++origPartIndex) { if (!origMLineParts[origPartIndex].Equals(isac16kRtpMap)) { newMLine.Append(origMLineParts[origPartIndex]).Append(" "); } } lines[mLineIndex] = newMLine.ToString(); StringBuilder newSdpDescription = new StringBuilder(); foreach (string line in lines) { newSdpDescription.Append(line).Append("\n"); } return(newSdpDescription.ToString()); }
// Fetches |url| and fishes the signaling parameters out of the HTML via // regular expressions. // // TODO(fischman): replace this hackery with a dedicated JSON-serving URL in // apprtc so that this isn't necessary (here and in other future apps that // want to interop with apprtc). private AppRTCSignalingParameters getParametersForRoomUrl(string url) { Java.Util.Regex.Pattern fullRoomPattern = Java.Util.Regex.Pattern.Compile(".*\n *Sorry, this room is full\\..*"); string roomHtml = drainStream((new URL(url)).OpenConnection().InputStream); Matcher fullRoomMatcher = fullRoomPattern.Matcher(roomHtml); if (fullRoomMatcher.Find()) { throw new IOException("Room is full!"); } string gaeBaseHref = url.Substring(0, url.IndexOf('?')); string token = getVarValue(roomHtml, "channelToken", true); string postMessageUrl = "/message?r=" + getVarValue(roomHtml, "roomKey", true) + "&u=" + getVarValue(roomHtml, "me", true); bool initiator = getVarValue(roomHtml, "initiator", false).Equals("1"); List <PeerConnection.IceServer> iceServers = outerInstance.iceServersFromPCConfigJSON(getVarValue(roomHtml, "pcConfig", false)); bool isTurnPresent = false; foreach (PeerConnection.IceServer server in iceServers) { if (server.Uri.StartsWith("turn:")) { isTurnPresent = true; break; } } if (!isTurnPresent) { iceServers.Add(requestTurnServer(getVarValue(roomHtml, "turnUrl", true))); } MediaConstraints pcConstraints = constraintsFromJSON(getVarValue(roomHtml, "pcConstraints", false)); Log.Debug(TAG, "pcConstraints: " + pcConstraints); MediaConstraints videoConstraints = constraintsFromJSON(getVideoConstraints(getVarValue(roomHtml, "mediaConstraints", false))); Log.Debug(TAG, "videoConstraints: " + videoConstraints); return(new AppRTCSignalingParameters(outerInstance, iceServers, gaeBaseHref, token, postMessageUrl, initiator, pcConstraints, videoConstraints)); }
// Scan |roomHtml| for declaration & assignment of |varName| and return its // value, optionally stripping outside quotes if |stripQuotes| requests it. private string getVarValue(string roomHtml, string varName, bool stripQuotes) { Java.Util.Regex.Pattern pattern = Java.Util.Regex.Pattern.Compile(".*\n *var " + varName + " = ([^\n]*);\n.*"); Matcher matcher = pattern.Matcher(roomHtml); if (!matcher.Find()) { throw new IOException("Missing " + varName + " in HTML: " + roomHtml); } string varValue = matcher.Group(1); if (matcher.Find()) { throw new IOException("Too many " + varName + " in HTML: " + roomHtml); } if (stripQuotes) { varValue = varValue.Substring(1, varValue.Length - 1 - 1); } return(varValue); }