Commit 3a1c22fb authored by Dele Olajide's avatar Dele Olajide Committed by dele

Jitsi Videobridge - Implemented server-side focus agent

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@13849 b35dd754-fafc-0310-a699-88a17e54d16e
parent 10c72096
...@@ -90,7 +90,8 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) { ...@@ -90,7 +90,8 @@ $(document).bind('remotestreamadded.jingle', function (event, data, sid) {
function waitForRemoteVideo(selector, sid) { function waitForRemoteVideo(selector, sid) {
var sess = connection.jingle.sessions[sid]; var sess = connection.jingle.sessions[sid];
videoTracks = data.stream.getVideoTracks(); videoTracks = data.stream.getVideoTracks();
if (videoTracks.length === 0 || selector[0].currentTime > 0) {
if (sess.peerconnection.iceConnectionState == "connected" && sess.peerconnection.signalingState == "stable") {
RTC.attachMediaStream(selector, data.stream); // FIXME: why do i have to do this for FF? RTC.attachMediaStream(selector, data.stream); // FIXME: why do i have to do this for FF?
$(document).trigger('callactive.jingle', [selector, sid]); $(document).trigger('callactive.jingle', [selector, sid]);
console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState); console.log('waitForremotevideo', sess.peerconnection.iceConnectionState, sess.peerconnection.signalingState);
......
package com.rayo.core.verb; package com.rayo.core.verb;
import org.xmpp.packet.*; import org.xmpp.packet.*;
import org.dom4j.*;
public class RemoveSourceEvent extends AbstractVerbEvent { public class RemoveSourceEvent extends AbstractVerbEvent {
...@@ -8,6 +9,7 @@ public class RemoveSourceEvent extends AbstractVerbEvent { ...@@ -8,6 +9,7 @@ public class RemoveSourceEvent extends AbstractVerbEvent {
private String nickname; private String nickname;
private JID participant; private JID participant;
private boolean active; private boolean active;
private Element conference;
public RemoveSourceEvent() {} public RemoveSourceEvent() {}
...@@ -15,6 +17,14 @@ public class RemoveSourceEvent extends AbstractVerbEvent { ...@@ -15,6 +17,14 @@ public class RemoveSourceEvent extends AbstractVerbEvent {
super(verb); super(verb);
} }
public Element getConference() {
return conference;
}
public void setConference(Element conference) {
this.conference = conference;
}
public JID getParticipant() { public JID getParticipant() {
return participant; return participant;
} }
......
...@@ -114,6 +114,7 @@ public class ColibriProvider extends BaseProvider { ...@@ -114,6 +114,7 @@ public class ColibriProvider extends BaseProvider {
root.addAttribute("nickname", event.getNickname()); root.addAttribute("nickname", event.getNickname());
root.addAttribute("participant", event.getParticipant().toString()); root.addAttribute("participant", event.getParticipant().toString());
root.addAttribute("active", event.isActive() ? "true" : "false"); root.addAttribute("active", event.isActive() ? "true" : "false");
root.add(event.getConference().createCopy());
} }
private void createMutedEvent(MutedEvent muted, Document document) private void createMutedEvent(MutedEvent muted, Document document)
......
...@@ -159,7 +159,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -159,7 +159,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
component = null; component = null;
} }
//destroyIQHandlers(); destroyIQHandlers();
} }
/** /**
...@@ -189,7 +189,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -189,7 +189,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
WebAppContext context = new WebAppContext(contexts, pluginDirectory.getPath(), "/" + appName); WebAppContext context = new WebAppContext(contexts, pluginDirectory.getPath(), "/" + appName);
context.setWelcomeFiles(new String[]{"index.html"}); context.setWelcomeFiles(new String[]{"index.html"});
//createIQHandlers(); createIQHandlers();
} }
catch(Exception e) { catch(Exception e) {
...@@ -794,10 +794,10 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -794,10 +794,10 @@ public class PluginImpl implements Plugin, PropertyEventListener
private String focusId = null; private String focusId = null;
private int count = 0; private int count = 0;
private LocalClientSession session; private LocalClientSession session;
private Participant firstParticipant;
private String domainName = XMPPServer.getInstance().getServerInfo().getXMPPDomain(); private String domainName = XMPPServer.getInstance().getServerInfo().getXMPPDomain();
public ConcurrentHashMap<String, Participant> users = new ConcurrentHashMap<String, Participant>(); public ConcurrentHashMap<String, Participant> users = new ConcurrentHashMap<String, Participant>();
public ConcurrentHashMap<String, Participant> ids = new ConcurrentHashMap<String, Participant>(); public ConcurrentHashMap<String, Participant> ids = new ConcurrentHashMap<String, Participant>();
public ConcurrentHashMap<String, Element> ssrcs = new ConcurrentHashMap<String, Element>();
public ConcurrentHashMap<String, Participant> channels = new ConcurrentHashMap<String, Participant>(); public ConcurrentHashMap<String, Participant> channels = new ConcurrentHashMap<String, Participant>();
/** /**
...@@ -812,15 +812,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -812,15 +812,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
* *
* *
*/ */
public void notifyUser(Participant participant, Element conference) public void processUserAnswer(Participant participant, Element conference)
{
routeColibriEvent(participant, conference, true);
}
/**
*
*
*/
public void answerUser(Participant participant, Element conference)
{ {
String nickname = participant.getNickname(); String nickname = participant.getNickname();
...@@ -835,7 +827,31 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -835,7 +827,31 @@ public class PluginImpl implements Plugin, PropertyEventListener
iq.setChildElement(conference.createCopy()); iq.setChildElement(conference.createCopy());
router.route(iq); router.route(iq);
routeColibriEvent(participant, conference, true); ssrcs.put(participant.getUser().toString(), conference);
for (Participant reciepient : users.values())
{
if (participant.getUser().toString().equals(reciepient.getUser().toString()) == false)
{
Element conf = ssrcs.get(reciepient.getUser().toString());
if (conf != null) // send others to me
{
Presence presence = new Presence();
presence.setFrom(XMPPServer.getInstance().createJID(focusName, focusName));
presence.setTo(participant.getUser());
AddSourceEvent event = new AddSourceEvent();
event.setMuc(roomJid);
event.setNickname(participant.getNickname());
event.setParticipant(participant.getUser());
event.setConference(conf);
presence.getElement().add(colibriProvider.toXML(event));
router.route(presence);
}
}
}
} }
/** /**
* *
...@@ -863,14 +879,10 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -863,14 +879,10 @@ public class PluginImpl implements Plugin, PropertyEventListener
Element content = (Element) i.next(); Element content = (Element) i.next();
Element channel = content.element("channel"); Element channel = content.element("channel");
if ("audio".equals(content.attributeValue("name"))) if ("video".equals(content.attributeValue("name")))
{ {
participant.audioChannelId = channel.attributeValue("id"); participant.videoChannelId = channel.attributeValue("id");
channels.put(participant.audioChannelId, participant); channels.put(participant.videoChannelId, participant);
} else {
participant.videoChannelId = channel.attributeValue("id");
channels.put(participant.videoChannelId, participant);
} }
} }
} }
...@@ -878,7 +890,21 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -878,7 +890,21 @@ public class PluginImpl implements Plugin, PropertyEventListener
* *
* *
*/ */
public void updateUser(Participant participant, Element conference) public void broadcastSSRC(Participant participant)
{
Log.info("broadcastSSRC " + participant + " " + count);
if (ssrcs.containsKey(participant.getUser().toString()))
{
Element conference = ssrcs.get(participant.getUser().toString());
routeColibriEvent(participant, conference, true); // send to others
}
}
/**
*
*
*/
public void updateUser(Participant participant)
{ {
} }
...@@ -899,13 +925,6 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -899,13 +925,6 @@ public class PluginImpl implements Plugin, PropertyEventListener
Log.info("createColibriChannel " + participant + " " + count); Log.info("createColibriChannel " + participant + " " + count);
count++; count++;
if (count == 1)
{
firstParticipant = participant; // can't start until we have at least 2 people
return;
}
String nickname = participant.getNickname(); String nickname = participant.getNickname();
IQ iq = new IQ(IQ.Type.get); IQ iq = new IQ(IQ.Type.get);
...@@ -941,10 +960,9 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -941,10 +960,9 @@ public class PluginImpl implements Plugin, PropertyEventListener
count--; count--;
if (count <= 1) if (count < 1)
{ {
focusId = null; // invalidate current focus session focusId = null; // invalidate current focus session
count = 0;
} }
if (users.containsKey(username)) if (users.containsKey(username))
...@@ -1019,7 +1037,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1019,7 +1037,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
*/ */
public void deliver(Packet packet) throws UnauthorizedException public void deliver(Packet packet) throws UnauthorizedException
{ {
Log.info("FocusAgent deliver\n" + packet); Log.debug("FocusAgent deliver\n" + packet);
IQ iq = (IQ) packet; IQ iq = (IQ) packet;
...@@ -1034,7 +1052,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1034,7 +1052,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
Participant participant = ids.remove(id); Participant participant = ids.remove(id);
if (users.containsKey(participant.getUser().toString())) if (users.containsKey(participant.getUser().toString()))
updateUser(participant, conference); updateUser(participant); // ignore ack payload
else else
addUser(participant, conference); addUser(participant, conference);
...@@ -1042,12 +1060,6 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1042,12 +1060,6 @@ public class PluginImpl implements Plugin, PropertyEventListener
} else Log.error("FocusAgent deliver cannot find iq owner " + id + "\n" + packet); } else Log.error("FocusAgent deliver cannot find iq owner " + id + "\n" + packet);
if (firstParticipant != null) // send pending channel request for first participant
{
createColibriChannel(firstParticipant);
firstParticipant = null;
}
} else if (iq.getType() == IQ.Type.error) { } else if (iq.getType() == IQ.Type.error) {
focusId = null; // error focusId = null; // error
...@@ -1056,7 +1068,6 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1056,7 +1068,6 @@ public class PluginImpl implements Plugin, PropertyEventListener
for (Participant reciepient : users.values()) for (Participant reciepient : users.values())
{ {
Log.info("routeColibriEvent - E " + reciepient);
sendRayoEvent(reciepient, null, false, reciepient); sendRayoEvent(reciepient, null, false, reciepient);
} }
...@@ -1066,17 +1077,15 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1066,17 +1077,15 @@ public class PluginImpl implements Plugin, PropertyEventListener
Element root = iq.getChildElement(); Element root = iq.getChildElement();
Element conference = null; Element conference = null;
if (user.toString().equals("jitsi-videobridge." + domainName)) // SSRC notification from videobridge if (user.toString().equals("jitsi-videobridge." + domainName)) // SSRC notification from videobridge, ignore
{ {
/* conference = root.createCopy(); // rayo from participant
conference = root.createCopy();
String channelId = conference.element("content").element("channel").attributeValue("id"); String channelId = conference.element("content").element("channel").attributeValue("id");
if (channels.containsKey(channelId)) if (channels.containsKey(channelId))
notifyUser(channels.get(channelId), conference); broadcastSSRC(channels.get(channelId));
else Log.error("FocusAgent deliver cannot find channel owner " + channelId + "\n" + packet);
*/
} else { } else {
conference = root.element("conference").createCopy(); // rayo from participant conference = root.element("conference").createCopy(); // rayo from participant
...@@ -1084,7 +1093,7 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1084,7 +1093,7 @@ public class PluginImpl implements Plugin, PropertyEventListener
IQ reply = IQ.createResultIQ(iq); IQ reply = IQ.createResultIQ(iq);
if (users.containsKey(user.toString())) if (users.containsKey(user.toString()))
answerUser(users.get(user.toString()), conference); processUserAnswer(users.get(user.toString()), conference);
else else
reply.setError(PacketError.Condition.not_allowed); reply.setError(PacketError.Condition.not_allowed);
...@@ -1115,7 +1124,6 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1115,7 +1124,6 @@ public class PluginImpl implements Plugin, PropertyEventListener
{ {
if (participant.getUser().toString().equals(reciepient.getUser().toString()) == false) if (participant.getUser().toString().equals(reciepient.getUser().toString()) == false)
{ {
Log.info("routeColibriEvent - R " + reciepient);
sendRayoEvent(reciepient, conference, isAdd, participant); sendRayoEvent(reciepient, conference, isAdd, participant);
} }
} }
...@@ -1126,6 +1134,8 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1126,6 +1134,8 @@ public class PluginImpl implements Plugin, PropertyEventListener
*/ */
private void sendRayoEvent(Participant reciepient, Element conference, boolean isAdd, Participant participant) private void sendRayoEvent(Participant reciepient, Element conference, boolean isAdd, Participant participant)
{ {
Log.info("sendRayoEvent - " + reciepient);
Presence presence = new Presence(); Presence presence = new Presence();
presence.setFrom(XMPPServer.getInstance().createJID(focusName, focusName)); presence.setFrom(XMPPServer.getInstance().createJID(focusName, focusName));
presence.setTo(reciepient.getUser()); presence.setTo(reciepient.getUser());
...@@ -1147,6 +1157,13 @@ public class PluginImpl implements Plugin, PropertyEventListener ...@@ -1147,6 +1157,13 @@ public class PluginImpl implements Plugin, PropertyEventListener
event.setParticipant(participant.getUser()); event.setParticipant(participant.getUser());
event.setActive(focusId != null); event.setActive(focusId != null);
Element conf = ssrcs.get(participant.getUser().toString());
if (conf != null)
{
event.setConference(conf);
}
presence.getElement().add(colibriProvider.toXML(event)); presence.getElement().add(colibriProvider.toXML(event));
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment