Global audio working on firefox and chrome.

This commit is contained in:
Hugo Lazzari 2012-11-29 10:01:32 -02:00
parent 3577641137
commit 3d5fac5956
24 changed files with 435 additions and 286 deletions

View File

@ -30,6 +30,7 @@ private static Logger log = Red5LoggerFactory.getLogger(ClientConnection.class,
private final String connId;
private final String userid;
private final String username;
private String roomName;
public ClientConnection(String connId, String userid, String username, IServiceCapableConnection connection) {
this.connection = connection;
@ -37,6 +38,14 @@ private static Logger log = Red5LoggerFactory.getLogger(ClientConnection.class,
this.userid = userid;
this.username = username;
}
public void setRoomName(String roomName) {
this.roomName = roomName;
}
public String getRoomName() {
return roomName;
}
public String getConnId() {
return connId;
@ -44,16 +53,22 @@ private static Logger log = Red5LoggerFactory.getLogger(ClientConnection.class,
public void onJoinConferenceSuccess(String publishName, String playName, String codec) {
log.debug("Notify client that {} [{}] has joined the conference.", username, userid);
connection.invoke("successfullyJoinedVoiceConferenceCallback", new Object[] {publishName, playName, codec});
if(connection.isConnected())
connection.invoke("successfullyJoinedVoiceConferenceCallback", new Object[] {publishName, playName, codec});
}
public void onJoinConferenceFail() {
log.debug("Notify client that {} [{}] failed to join the conference.", username, userid);
connection.invoke("failedToJoinVoiceConferenceCallback", new Object[] {"onUaCallFailed"});
if(connection.isConnected())
connection.invoke("failedToJoinVoiceConferenceCallback", new Object[] {"onUaCallFailed"});
}
public void onLeaveConference() {
System.out.println("ESTOU AQUI + " + username + userid);
log.debug("Notify client that {} [{}] left the conference.", username, userid);
connection.invoke("disconnectedFromJoinVoiceConferenceCallback", new Object[] {"onUaCallClosed"});
if(connection != null && connection.isConnected())
connection.invoke("disconnectedFromJoinVoiceConferenceCallback", new Object[] {"onUaCallClosed"});
System.out.println("PASSEI PALA INVOCACAO");
}
}

View File

@ -40,9 +40,8 @@ public class Service {
public Boolean call(String peerId, String callerName, String destination, Boolean global) {
if(global == true) {
hangup(peerId);
if(GlobalCall.roomHasGlobalStream(destination) == false) {
String extension = callExtensionPattern.format(new String[] { destination });
try {
@ -93,6 +92,7 @@ public class Service {
String username = getUsername();
log.debug("{} is requesting to hang up from the conference.", username + "[uid=" + userid + "][clientid=" + clientId + "]");
try {
System.out.println("USUARIO " + username + " saiu da conferencia AKI OI OI OI");
sipPeerManager.hangup(peerId, getClientId());
return true;
} catch (PeerNotFoundException e) {

View File

@ -32,6 +32,8 @@ import org.slf4j.Logger;
import org.red5.logging.Red5LoggerFactory;
import org.red5.server.api.IScope;
import org.red5.server.api.stream.IBroadcastStream;
import java.net.DatagramSocket;
public class CallStream implements StreamObserver {
private final static Logger log = Red5LoggerFactory.getLogger(CallStream.class, "sip");
@ -73,6 +75,10 @@ public class CallStream implements StreamObserver {
userListenStream.start();
userTalkStream = new FlashToSipAudioStream(flashToSipTranscoder, connInfo.getSocket(), connInfo);
}
public DatagramSocket getSocket() {
return connInfo.getSocket();
}
public String getTalkStreamName() {
return userTalkStream.getStreamName();

View File

@ -55,12 +55,14 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
private ClientConnectionManager clientConnManager;
private final String clientId;
private final AudioConferenceProvider portProvider;
private DatagramSocket localSocket;
private DatagramSocket localSocket = null;
public String _callerName;
private String _destination;
private CallAgent caToInit = null;
private Boolean talking = false;
private Boolean socketGlobal = false;
private enum CallState {
UA_IDLE(0), UA_INCOMING_CALL(1), UA_OUTGOING_CALL(2), UA_ONCALL(3);
private final int state;
@ -70,11 +72,18 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
private CallState callState;
public void setLocalSocketRelatedToGlobal() {
this.socketGlobal = true;
}
public String getDestination() {
return _destination;
}
public CallAgent(SipProvider sipProvider, SipPeerProfile userProfile, AudioConferenceProvider portProvider, String clientId) {
System.out.println("FUI CRIADO AGORA");
this.sipProvider = sipProvider;
this.userProfile = userProfile;
this.portProvider = portProvider;
@ -192,11 +201,18 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
/** Closes an ongoing, incoming, or pending call */
public void hangup() {
log.debug("hangup");
if (callState == CallState.UA_IDLE) return;
closeVoiceStreams();
if (call != null) call.hangup();
callState = CallState.UA_IDLE;
if(talking) {
if (callState == CallState.UA_IDLE) return;
closeVoiceStreams();
if (call != null) call.hangup();
callState = CallState.UA_IDLE;
}
else {
callState = CallState.UA_IDLE;
System.out.println("NAO ESTOU FALANDO");
System.out.println(clientId + " eh o usuario que ta indo");
clientConnManager.leaveConference(clientId);
}
}
private DatagramSocket getLocalAudioSocket() throws Exception {
@ -250,9 +266,9 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
if(_callerName.contains("GLOBAL_AUDIO") == true) {
//String room = _callerName.subSequence(13, _callerName.length()).toString();
GlobalCall.addGlobalAudioStream(_destination, callStream.getListenStreamName());
GlobalCall.addGlobalAudioStream(_destination, callStream.getListenStreamName());
caToInit.returnGlobalStreamName(caToInit.getCallId(), _destination);
talking = false;
talking = true;
}
else {
talking = true;
@ -298,6 +314,7 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
private void closeVoiceStreams() {
log.debug("Shutting down the voice streams.");
if (callStream != null) {
System.out.println("FECHANDO AS VOICE STREAMS");
callStream.stop();
callStream = null;
} else {
@ -412,18 +429,20 @@ public class CallAgent extends CallListenerAdapter implements CallStreamObserver
}
private void notifyListenersOfOnCallClosed() {
log.debug("notifyListenersOfOnCallClosed for {}", clientId);
log.debug("notifyListenersOfOnCallClosed for {}", clientId);
clientConnManager.leaveConference(clientId);
cleanup();
cleanup();
}
private void cleanup() {
log.debug("Closing local audio port {}", localSocket.getLocalPort());
if (localSocket != null) {
localSocket.close();
if (localSocket != null) {
if(talking == true) {
localSocket.close();
}
} else {
log.debug("Trying to close un-allocated port {}", localSocket.getLocalPort());
log.debug("Trying to close un-allocated port {}", localSocket.getLocalPort());
}
}
/** Callback function called when arriving a BYE request */

View File

@ -3,6 +3,7 @@ package org.bigbluebutton.voiceconf.sip;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.net.DatagramSocket;
public class GlobalCall {
@ -26,6 +27,8 @@ public class GlobalCall {
public static void removeRoom(String roomName) {
System.out.println("REMOVENDO A SALA "+roomName);
voiceConference.remove(roomName);
numberOfUsers.remove(roomName);
}
public static void addUser(String roomName) {
@ -40,6 +43,7 @@ public class GlobalCall {
int nUsers = numberOfUsers.get(roomName);
nUsers-=1;
numberOfUsers.put(roomName, nUsers);
System.out.println("REMOVENDO USUARIO: numero eh de " + nUsers);
}
}

View File

@ -114,9 +114,9 @@ public class SipPeer implements SipRegisterAgentListener {
SipPeerProfile callerProfileGlobal = SipPeerProfile.copy(registeredProfile);
CallAgent ca = new CallAgent(sipProvider, callerProfile, audioconfProvider, clientId);
ca.setLocalSocketRelatedToGlobal();
CallAgent caGlobal = new CallAgent(sipProvider, callerProfileGlobal, audioconfProvider, clientIdGlobal);
ca.setClientConnectionManager(clientConnManager);
ca.setClientConnectionManager(clientConnManager);
ca.setCallStreamFactory(callStreamFactory);
caGlobal.setClientConnectionManager(clientConnManager);
@ -142,7 +142,7 @@ public class SipPeer implements SipRegisterAgentListener {
SipPeerProfile callerProfile = SipPeerProfile.copy(registeredProfile);
CallAgent ca = new CallAgent(sipProvider, callerProfile, audioconfProvider, clientId);
ca.setClientConnectionManager(clientConnManager);
ca.setClientConnectionManager(clientConnManager);
ca.setCallStreamFactory(callStreamFactory);
callManager.add(ca);
ca.call(callerName, destination);
@ -151,7 +151,7 @@ public class SipPeer implements SipRegisterAgentListener {
public void returnGlobalStream(String clientId, String destination) {
SipPeerProfile callerProfile = SipPeerProfile.copy(registeredProfile);
CallAgent ca = new CallAgent(sipProvider, callerProfile, audioconfProvider, clientId);
ca.setClientConnectionManager(clientConnManager);
ca.setClientConnectionManager(clientConnManager);
ca.setCallStreamFactory(callStreamFactory);
callManager.add(ca);
ca.returnGlobalStreamName(clientId, destination);
@ -180,23 +180,27 @@ public class SipPeer implements SipRegisterAgentListener {
else {
destination = clientId;
}
if(ca != null && ca.isTalking() == false)
GlobalCall.removeUser(destination);
if(GlobalCall.roomHasGlobalStream(destination) && GlobalCall.getNumberOfUsers(destination) <= 0) {
CallAgent caGlobal = callManager.removeGlobal(destination);
GlobalCall.removeRoom(destination);
if(caGlobal != null) {
caGlobal.hangup();
}
}
if (ca != null) {
ca.hangup();
if(ca != null) {
if(ca.isTalking()) {
System.out.println("CA ESTA FALANDO");
ca.hangup();
}
else {
System.out.println("REMOVE USER");
GlobalCall.removeUser(destination);
ca.hangup();
if(GlobalCall.roomHasGlobalStream(destination) && GlobalCall.getNumberOfUsers(destination) <= 0) {
System.out.println("REMOVE GLOBAL");
CallAgent caGlobal = callManager.removeGlobal(destination);
GlobalCall.removeRoom(destination);
caGlobal.hangup();
}
}
}
}
}
public void unregister() {
log.debug( "SIPUser unregister" );

View File

@ -131,6 +131,8 @@ bbb.desktopView.fitToWindow = Fit to Window
bbb.desktopView.actualSize = Display actual size
bbb.toolbar.phone.toolTip.start = Share My Microphone
bbb.toolbar.phone.toolTip.stop = Stop Sharing My Microphone
bbb.toolbar.phone.toolTip.mute = Stop Listening Voice Conference
bbb.toolbar.phone.toolTip.unmute = Start Listening Voice Conference
bbb.toolbar.deskshare.toolTip.start = Share My Desktop
bbb.toolbar.deskshare.toolTip.stop = Stop Sharing My Desktop
bbb.toolbar.video.toolTip.start = Share My Camera

View File

@ -24,7 +24,7 @@ package org.bigbluebutton.main.model.users
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.common.Role;
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
import org.bigbluebutton.main.model.users.events.StreamStartedEvent;
public class BBBUser {
public static const MODERATOR:String = "MODERATOR";
@ -46,7 +46,6 @@ package org.bigbluebutton.main.model.users
[Bindable] public var voiceMuted:Boolean = false;
[Bindable] public var voiceJoined:Boolean = false;
[Bindable] public var voiceLocked:Boolean = false;
[Bindable] public var firstTimeUnMute:Boolean = true;
private var _status:StatusCollection = new StatusCollection();
@ -125,4 +124,4 @@ package org.bigbluebutton.main.model.users
dispatcher.dispatchEvent(new StreamStartedEvent(userid, name, streamName));
}
}
}
}

View File

@ -152,15 +152,7 @@ package org.bigbluebutton.main.model.users {
public function amIThisUser(userid:int):Boolean {
return me.userid == userid;
}
public function setFirstTimeUnMute(firstTimeUnMute:Boolean):void {
me.firstTimeUnMute = firstTimeUnMute;
}
public function getFirstTimeUnMute():Boolean {
return me.firstTimeUnMute;
}
public function amIModerator():Boolean {
return me.role == Role.MODERATOR;
}
@ -271,4 +263,4 @@ package org.bigbluebutton.main.model.users {
users.refresh();
}
}
}
}

View File

@ -23,8 +23,6 @@
[Bindable] private var cancelIcon:Class = images.delete_icon;
private function initDefaultMic():void {
mic = Microphone.getMicrophone(-1);
mic.setLoopBack(true);
if (mic != null) {
@ -35,8 +33,6 @@
timer = new Timer(100);
timer.addEventListener(TimerEvent.TIMER, updateMicLevel);
timer.start();
}
private function micStatusEventHandler(event:StatusEvent):void {
@ -76,10 +72,9 @@
private function onJoinClicked():void {
cleanUp();
dispatchEvent(new BBBEvent("VOICE_CONFERENCE_EVENT_BEGIN_PUBLISH"));
//var joinEvent:BBBEvent = new BBBEvent("JOIN_VOICE_CONFERENCE_EVENT");
//joinEvent.payload['useMicrophone'] = true;
//dispatchEvent(joinEvent);
var joinEvent:BBBEvent = new BBBEvent("JOIN_VOICE_CONFERENCE_EVENT");
joinEvent.payload['useMicrophone'] = true;
dispatchEvent(joinEvent);
PopUpManager.removePopUp(this);
}
@ -88,9 +83,6 @@
var event:BBBEvent = new BBBEvent("MIC_SETTINGS_CLOSED");
event.payload['clicked'] = "cancel";
dispatchEvent(event);
dispatchEvent(new BBBEvent("UNMUTE_VOICE_CONFIG"));
PopUpManager.removePopUp(this);
}

View File

@ -31,7 +31,7 @@ package org.bigbluebutton.modules.listeners.business
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.modules.listeners.business.vo.Listener;
import org.bigbluebutton.modules.listeners.business.vo.Listeners;
import org.bigbluebutton.modules.listeners.events.ListenersEvent;
import org.bigbluebutton.modules.listeners.events.ListenersEvent;
public class ListenersSOService
{
@ -153,28 +153,7 @@ package org.bigbluebutton.modules.listeners.business
* Let's store the voice userid so we can do push to talk.
*/
if (UserManager.getInstance().getConference().amIThisVoiceUser(userId)) {
UserManager.getInstance().getConference().muteMyVoice(l.muted);
if(l.muted == false && UserManager.getInstance().getConference().getFirstTimeUnMute()) {
UserManager.getInstance().getConference().setFirstTimeUnMute(false);
dispatcher.dispatchEvent(new BBBEvent("MUTE_AUDIO_CONFIG"));
dispatcher.dispatchEvent(new BBBEvent("SHOW_MIC_SETTINGS"));
//dispatcher.dispatchEvent(new BBBEvent("VOICE_CONFERENCE_EVENT_BEGIN_PUBLISH"));
}
else {
if(l.muted == true && UserManager.getInstance().getConference().getFirstTimeUnMute() == false) {
dispatcher.dispatchEvent(new BBBEvent("STOP_OUT_STREAM"));
}
else if(l.muted == false && UserManager.getInstance().getConference().getFirstTimeUnMute() == false){
dispatcher.dispatchEvent(new BBBEvent("VOICE_CONFERENCE_EVENT_BEGIN_PUBLISH"));
}
}
UserManager.getInstance().getConference().muteMyVoice(l.muted);
}
}
}
@ -332,7 +311,6 @@ package org.bigbluebutton.modules.listeners.business
if (result.count > 0) {
for(var p:Object in result.participants)
{
var u:Object = result.participants[p]
userJoin(u.participant, u.name, u.name, u.muted, u.talking, u.locked);
}
@ -435,4 +413,4 @@ package org.bigbluebutton.modules.listeners.business
_soErrors.push(error);
}
}
}
}

View File

@ -28,10 +28,9 @@ package org.bigbluebutton.modules.listeners.business.vo {
public var muted:Boolean;
public var talking:Boolean;
public var locked:Boolean;
public var firstTimeUnMute:Boolean = true;
// Stores if the participant is moderator or not.
// This is not the role of the joining listener
// but of the participant running the client.
public var moderator:Boolean = false;
}
}
}

View File

@ -45,8 +45,7 @@
[Bindable] private var statusTooltip : String = "";
[Bindable] private var ejectTooltip : String = ResourceUtil.getInstance().getString('bbb.listeners.ejectTooltip');
[Bindable] private var moderator:Boolean = false;
private var firstMute:Boolean = true;
public function onRollOver():void{
if (moderator) kickUserBtn.visible = true;
}

View File

@ -12,5 +12,8 @@ package org.bigbluebutton.modules.phone
[Bindable]
public var enabledEchoCancel:Boolean = false;
[Bindable]
public var joinGlobal:Boolean = true;
}
}
}

View File

@ -56,6 +56,10 @@ package org.bigbluebutton.modules.phone.managers {
public function getConnection():NetConnection {
return netConnection;
}
public function getConnected():Boolean {
return isConnected;
}
public function connect(uid:String, externUID:String, username:String, room:String, uri:String):void {
if (isConnected) return;
@ -137,6 +141,8 @@ package org.bigbluebutton.modules.phone.managers {
event.codec = codec;
dispatcher.dispatchEvent(event);
}
//********************************************************************************************
//
@ -145,10 +151,14 @@ package org.bigbluebutton.modules.phone.managers {
//********************************************************************************************
public function doCall(dialStr:String):void {
LogUtil.debug("in doCall - Calling " + dialStr);
//netConnection.call("voiceconf.call", null, "default", username, dialStr);
netConnection.call("voiceconf.call", null, "default", username, dialStr, "true");
netConnection.call("voiceconf.call", null, "default", username, dialStr, "false");
}
public function doCallGlobal(dialStr:String):void {
LogUtil.debug("in doCallGlobal - Calling " + dialStr + " " + username);
netConnection.call("voiceconf.call", null, "default", username, dialStr, "true");
}
public function doHangUp():void {
if (isConnected) {
netConnection.call("voiceconf.hangup", null, "default");

View File

@ -41,13 +41,16 @@ package org.bigbluebutton.modules.phone.managers {
private var rejoining:Boolean = false;
// User has requested to leave the voice conference.
private var userHangup:Boolean = false;
private var globalCall:Boolean = true;
private var userRequestedToChangeToGlobal:Boolean = true;
private var userRequestedToChange:Boolean = false;
public function PhoneManager() {
connectionManager = new ConnectionManager();
streamManager = new StreamManager();
}
public function setModuleAttributes(attributes:Object):void {
this.attributes = attributes;
var vxml:XML = BBB.getConfigForModule("PhoneModule");
@ -56,24 +59,26 @@ package org.bigbluebutton.modules.phone.managers {
phoneOptions.showButton = (vxml.@showButton.toString().toUpperCase() == "TRUE") ? true : false;
phoneOptions.autoJoin = (vxml.@autoJoin.toString().toUpperCase() == "TRUE") ? true : false;
phoneOptions.skipCheck = (vxml.@skipCheck.toString().toUpperCase() == "TRUE") ? true : false;
phoneOptions.joinGlobal = (vxml.@joinGlobal.toString().toUpperCase() == "TRUE") ? true : false;
}
if (phoneOptions.autoJoin) {
if (phoneOptions.skipCheck || noMicrophone()) {
/*
if (noMicrophone()) {
joinVoice(false);
} else {
joinVoice(true);
}
*/
joinVoice(false);
} else {
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new BBBEvent("SHOW_MIC_SETTINGS"));
}
if (phoneOptions.autoJoin) {
if (phoneOptions.skipCheck) {
if (phoneOptions.joinGlobal)
joinVoiceGlobal();
else if (noMicrophone()) {
joinVoice(false);
} else {
joinVoice(true);
}
} else {
if (phoneOptions.joinGlobal)
joinVoiceGlobal();
else {
var dispatcher:Dispatcher = new Dispatcher();
dispatcher.dispatchEvent(new BBBEvent("SHOW_MIC_SETTINGS"));
}
}
}
}
@ -89,49 +94,55 @@ package org.bigbluebutton.modules.phone.managers {
else
streamManager.initWithNoMicrophone();
}
public function muteAudio():void {
streamManager.muteAudio();
}
public function unMuteAudio():void {
streamManager.unMuteAudio();
}
public function stopOutStream():void {
streamManager.stopOutStream();
}
private function setupConnection():void {
streamManager.setConnection(connectionManager.getConnection());
}
public function joinVoiceGlobal():void {
userHangup = false;
globalCall = true;
var uid:String = String(Math.floor(new Date().getTime()));
var uname:String = encodeURIComponent(UserManager.getInstance().getConference().getMyUserId() + "-" + attributes.username);
connectionManager.connect(uid, attributes.externUserID, uname , attributes.room, attributes.uri);
}
public function joinVoice(autoJoin:Boolean):void {
userHangup = false;
globalCall = false;
setupMic(autoJoin);
var uid:String = String(Math.floor(new Date().getTime()));
var uname:String = encodeURIComponent(UserManager.getInstance().getConference().getMyUserId() + "-" + attributes.username);
connectionManager.connect(uid, attributes.externUserID, uname , attributes.room, attributes.uri);
}
public function rejoin():void {
if (!rejoining && !userHangup) {
// We got disconnected and it's not because the user requested it. Let's rejoin the conference.
LogUtil.debug("Rejoining the conference");
rejoining = true;
joinVoice(withMic);
}
}
public function dialConference():void {
LogUtil.debug("*** Dialling conference ***");
connectionManager.doCall(attributes.webvoiceconf);
}
public function beginPublish():void {
streamManager.beginPublishing();
public function rejoin():void {
if (!rejoining && !userHangup) {
LogUtil.debug("Rejoining the conference");
rejoining = true;
if(globalCall == false) {
joinVoice(true);
}
else
joinVoiceGlobal();
}
}
public function dialConference():void {
if(globalCall == false) {
LogUtil.debug("*** Talking/Listening ***");
connectionManager.doCall(attributes.webvoiceconf);
}
else {
LogUtil.debug("*** Only Listening ***");
connectionManager.doCallGlobal(attributes.webvoiceconf);
}
}
public function callConnected(event:CallConnectedEvent):void {
@ -141,19 +152,56 @@ package org.bigbluebutton.modules.phone.managers {
// We have joined the conference. Reset so that if and when we get disconnected, we
// can rejoin automatically.
rejoining = false;
userHangup = false;
var dispatcher:Dispatcher = new Dispatcher();
if(globalCall)
dispatcher.dispatchEvent(new BBBEvent("LISTENING_ONLY"));
else
dispatcher.dispatchEvent(new BBBEvent("SPEAKING_AND_LISTENING"));
}
public function userRequestedHangup():void {
LogUtil.debug("User has requested to hangup and leave the conference");
userHangup = true;
rejoining = false;
this.userRequestedToChange = false;
hangup();
}
public function userRequestedHangupToChange(event:BBBEvent):void {
userHangup = true;
rejoining = true;
userRequestedToChange = true;
userRequestedToChangeToGlobal = event.payload.global;
hangup();
}
public function muteAudio():void {
LogUtil.debug("User has requested to mute audio");
streamManager.muteAudio();
}
public function unmuteAudio():void {
LogUtil.debug("User has requested to unmute audio");
streamManager.unmuteAudio();
}
public function hangup():void {
if (onCall) {
streamManager.stopStreams();
connectionManager.doHangUp();
onCall = false;
}
else {
if(this.userRequestedToChange) {
this.userRequestedToChange = false;
if(userRequestedToChangeToGlobal)
joinVoiceGlobal();
else
joinVoice(withMic);
}
}
}
}

View File

@ -36,9 +36,6 @@ package org.bigbluebutton.modules.phone.managers {
import org.bigbluebutton.modules.phone.PhoneOptions;
import org.bigbluebutton.modules.phone.events.MicrophoneUnavailEvent;
import org.bigbluebutton.modules.phone.events.PlayStreamStatusEvent;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.modules.listeners.events.ListenersCommand;
public class StreamManager {
public var connection:NetConnection = null;
@ -50,8 +47,8 @@ package org.bigbluebutton.modules.phone.managers {
private var muted:Boolean = false;
private var audioCodec:String = "SPEEX";
private var dispatcher:Dispatcher;
private var onlyListening:Boolean = true;
private var _custom_obj:Object = null;
private var listeningOnGlobal:Boolean;
public function StreamManager() {
dispatcher = new Dispatcher();
}
@ -64,20 +61,12 @@ package org.bigbluebutton.modules.phone.managers {
mic = Microphone.getMicrophone(-1);
if(mic == null){
initWithNoMicrophone();
onlyListening = true;
} else {
setupMicrophone();
mic.addEventListener(StatusEvent.STATUS, micStatusHandler);
onlyListening = false;
}
}
public function muteAudio():void {
incomingStream.receiveAudio(false);
}
public function unMuteAudio():void {
incomingStream.receiveAudio(true);
}
private function setupMicrophone():void {
var vxml:XML = BBB.getConfigForModule("PhoneModule");
var phoneOptions:PhoneOptions = new PhoneOptions();
@ -116,17 +105,8 @@ package org.bigbluebutton.modules.phone.managers {
}
public function initWithNoMicrophone(): void {
mic = Microphone.getMicrophone(-1);
if(mic == null){
var event:MicrophoneUnavailEvent = new MicrophoneUnavailEvent();
dispatcher.dispatchEvent(event);
} else {
setupMicrophone();
mic.addEventListener(StatusEvent.STATUS, micStatusHandler);
mic = null;
}
onlyListening = true;
var event:MicrophoneUnavailEvent = new MicrophoneUnavailEvent();
dispatcher.dispatchEvent(event);
}
private function micStatusHandler(event:StatusEvent):void {
@ -141,50 +121,46 @@ package org.bigbluebutton.modules.phone.managers {
LogUtil.debug("unknown micStatusHandler event: " + event);
}
}
public function beginPublishing():void {
unMuteAudio();
if(mic == null) {
setupMicrophone();
}
if(mic != null) {
onlyListening = false;
setupOutgoingStream();
outgoingStream.client = _custom_obj;
publish(publishName);
}
}
public function callConnected(playStreamName:String, publishStreamName:String, codec:String):void {
LogUtil.debug("TOCANDO STREAM");
setupMicrophone();
if(codec != null)
audioCodec = codec;
isCallConnected = true;
//audioCodec = codec;
publishName = publishStreamName;
if(incomingStream != null) {
stopStreams();
incomingStream = null;
}
setupIncomingStream();
if (mic != null) {
onlyListening = true;
setupOutgoingStream();
if (publishStreamName != "") {
listeningOnGlobal = false;
if (mic != null) {
setupOutgoingStream();
}
}
if(onlyListening) {
dispatcher.dispatchEvent(new BBBEvent("ONLY_LISTENING_USER"));
else {
//mic = null;
listeningOnGlobal = true;
}
setupPlayStatusHandler();
play(playStreamName);
publish(publishStreamName);
if (listeningOnGlobal == false && publishStreamName != null) {
publish(publishStreamName);
}
}
private function play(playStreamName:String):void {
private function play(playStreamName:String):void {
LogUtil.debug("PLAY TO");
incomingStream.play(playStreamName);
}
private function publish(publishStreamName:String):void {
if (mic != null)
if (listeningOnGlobal == false && mic != null)
outgoingStream.publish(publishStreamName, "live");
else
LogUtil.debug("SM publish: No Microphone to publish");
@ -206,17 +182,23 @@ package org.bigbluebutton.modules.phone.managers {
incomingStream.receiveAudio(true);
incomingStream.receiveVideo(false);
}
public function muteAudio():void {
if(incomingStream != null)
incomingStream.receiveAudio(false);
}
public function unmuteAudio():void {
if(incomingStream != null)
incomingStream.receiveAudio(true);
}
private function setupOutgoingStream():void {
if(outgoingStream == null) {
outgoingStream = new NetStream(connection);
}
outgoingStream = new NetStream(connection);
outgoingStream.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
outgoingStream.addEventListener(AsyncErrorEvent.ASYNC_ERROR, asyncErrorHandler);
setupMicrophone();
outgoingStream.attachAudio(mic);
}
private function setupPlayStatusHandler():void {
@ -224,21 +206,12 @@ package org.bigbluebutton.modules.phone.managers {
custom_obj.onPlayStatus = playStatus;
custom_obj.onMetadata = onMetadata;
incomingStream.client = custom_obj;
_custom_obj = custom_obj;
if (mic != null)
if (listeningOnGlobal == false && mic != null)
outgoingStream.client = custom_obj;
}
public function stopOutStream():void {
outgoingStream.attachAudio(null);
//outgoingStream.close();
mic = null;
//outgoingStream = null;
}
public function stopStreams():void {
LogUtil.debug("Stopping Stream(s)");
if(incomingStream != null) {
LogUtil.debug("--Stopping Incoming Stream");
@ -257,6 +230,7 @@ package org.bigbluebutton.modules.phone.managers {
isCallConnected = false;
LogUtil.debug("Stopped Stream(s)");
}
private function netStatus (evt:NetStatusEvent ):void {

View File

@ -63,55 +63,52 @@
<EventHandlers type="{StopPhoneModuleEvent.STOP_PHONE_MODULE_EVENT}">
<MethodInvoker generator="{PhoneEventMapDelegate}" method="removeToolbarButton"/>
<MethodInvoker generator="{PhoneManager}" method="userRequestedHangup"/>
<MethodInvoker generator="{PhoneManager}" method="userRequestedHangup" />
</EventHandlers>
<EventHandlers type="LEAVE_VOICE_CONFERENCE_EVENT">
<MethodInvoker generator="{PhoneManager}" method="userRequestedHangup"/>
</EventHandlers>
<EventHandlers type="ASK_TO_CHANGE_VOICE_CONFERENCE_EVENT">
<MethodInvoker generator="{PhoneManager}" method="userRequestedHangupToChange" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="JOIN_VOICE_CONFERENCE_EVENT">
<MethodInvoker generator="{PhoneManager}" method="joinVoice" arguments="{event.payload.useMicrophone}"/>
</EventHandlers>
<EventHandlers type="VOICE_CONFERENCE_EVENT_BEGIN_PUBLISH">
<MethodInvoker generator="{PhoneManager}" method="beginPublish"/>
<EventHandlers type="JOIN_VOICE_CONFERENCE_EVENT_GLOBAL">
<MethodInvoker generator="{PhoneManager}" method="joinVoiceGlobal" arguments="{event.payload.useMicrophone}"/>
</EventHandlers>
<EventHandlers type="MUTE_AUDIO_CONFIG">
<EventHandlers type="MUTE_AUDIO_VOICE_CONFERENCE">
<MethodInvoker generator="{PhoneManager}" method="muteAudio"/>
</EventHandlers>
<EventHandlers type="UNMUTE_AUDIO_CONFIG">
<MethodInvoker generator="{PhoneManager}" method="unMuteAudio"/>
<EventHandlers type="UNMUTE_AUDIO_VOICE_CONFERENCE">
<MethodInvoker generator="{PhoneManager}" method="unmuteAudio"/>
</EventHandlers>
<EventHandlers type="STOP_O2">
<MethodInvoker generator="{PhoneManager}" method="stopOutStream2"/>
</EventHandlers>
<EventHandlers type="STOP_OUT_STREAM">
<MethodInvoker generator="{PhoneManager}" method="stopOutStream"/>
</EventHandlers>
<EventHandlers type="{CallConnectedEvent.CALL_CONNECTED_EVENT}">
<MethodInvoker generator="{PhoneEventMapDelegate}" method="disableToolbarButton"/>
<MethodInvoker generator="{PhoneManager}" method="callConnected" arguments="{event}"/>
</EventHandlers>
<EventHandlers type="{CallDisconnectedEvent.CALL_DISCONNECTED_EVENT}">
<MethodInvoker generator="{PhoneManager}" method="hangup" />
<MethodInvoker generator="{PhoneEventMapDelegate}" method="enableToolbarButton" />
<MethodInvoker generator="{PhoneManager}" method="rejoin" />
<MethodInvoker generator="{PhoneEventMapDelegate}" method="enableToolbarButton" />
<MethodInvoker generator="{PhoneManager}" method="rejoin" />
</EventHandlers>
<EventHandlers type="{ConnectionStatusEvent.CONNECTION_STATUS_EVENT}">
<MethodInvoker generator="{PhoneManager}" method="dialConference"/>
</EventHandlers>
<EventHandlers type="{ConnectionStatusEvent.SUCCESS}">
<MethodInvoker generator="{PhoneManager}" method="calledFromGlobal" arguments="ConnectionStatusEvent.SUCCESS"/>
</EventHandlers>
</EventMap>

View File

@ -26,15 +26,17 @@ package org.bigbluebutton.modules.phone.maps
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.modules.phone.PhoneOptions;
import org.bigbluebutton.modules.phone.views.components.ToolbarButton;
import org.bigbluebutton.modules.phone.views.components.MuteButton;
public class PhoneEventMapDelegate {
private var phoneOptions:PhoneOptions;
private var phoneButton:ToolbarButton;
private var soundButton:MuteButton;
private var buttonOpen:Boolean = false;
private var globalDispatcher:Dispatcher;
public function PhoneEventMapDelegate() {
phoneButton = new ToolbarButton();
soundButton = new MuteButton();
globalDispatcher = new Dispatcher();
phoneOptions = new PhoneOptions();
var vxml:XML = BBB.getConfigForModule("PhoneModule");
@ -56,6 +58,11 @@ package org.bigbluebutton.modules.phone.maps
globalDispatcher.dispatchEvent(event);
buttonOpen = true;
}
var event2:ToolbarButtonEvent = new ToolbarButtonEvent(ToolbarButtonEvent.ADD);
event2.button = soundButton;
globalDispatcher.dispatchEvent(event2);
}
public function removeToolbarButton():void {
@ -78,7 +85,7 @@ package org.bigbluebutton.modules.phone.maps
public function enableToolbarButton():void {
phoneButton.selected = false;
phoneButton.enabled = true;
phoneButton.userJoinedConference(false);
//phoneButton.userJoinedConference(false);
}
}
}
}

View File

@ -30,6 +30,13 @@ package org.bigbluebutton.modules.phone.views.assets
[Embed(source="images/headset_open.png")]
public var headsetActiveIcon:Class;
[Embed(source="images/sound.png")]
public var speakerActiveIcon:Class;
[Embed(source="images/sound_mute.png")]
public var speakerInactiveIcon:Class;
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 610 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 474 B

View File

@ -0,0 +1,122 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
BigBlueButton open source conferencing system - http://www.bigbluebutton.org
Copyright (c) 2010 BigBlueButton Inc. and by respective authors (see below).
BigBlueButton is free software; you can redistribute it and/or modify it under the
terms of the GNU Lesser General Public License as published by the Free Software
Foundation; either version 2.1 of the License, or (at your option) any later
version.
BigBlueButton is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License along
with BigBlueButton; if not, see <http://www.gnu.org/licenses/>.
$Id: $
-->
<mx:Button xmlns:mx="http://www.adobe.com/2006/mxml" xmlns:mate="http://mate.asfusion.com/"
icon="{phoneIcon}" click="startSound()"
mouseOver = "mouseOverHandler(event)"
mouseOut = "mouseOutHandler(event)"
creationComplete = "initMuteButton()"
toolTip="{ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.mute')}"
implements="org.bigbluebutton.common.IBbbToolbarComponent">
<mx:Script>
<![CDATA[
import com.asfusion.mate.events.Dispatcher;
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.views.MainToolbar;
import org.bigbluebutton.modules.phone.PhoneOptions;
import org.bigbluebutton.modules.phone.events.CallConnectedEvent;
import org.bigbluebutton.modules.phone.events.CallDisconnectedEvent;
import org.bigbluebutton.modules.phone.views.assets.Images;
import org.bigbluebutton.util.i18n.ResourceUtil;
private var images:Images = new Images();
private var dispatcher:Dispatcher = new Dispatcher();
private var talking:Boolean = false;
public const MUTE_STATE:Number = 0;
public const LISTENING_STATE:Number = 1;
private var _currentState:Number = LISTENING_STATE;
[Bindable] public var phoneIcon:Class = images.speakerActiveIcon;
private function initMuteButton():void {
this.selected = true;
this.enabled = true;
phoneIcon = images.speakerActiveIcon;
}
private function startSound():void {
this.enabled = false;
if (this.selected) {
muteLocalUser();
this.selected = false;
phoneIcon = images.speakerInactiveIcon;
_currentState = MUTE_STATE;
this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.unmute');
} else {
unmuteLocalUser();
this.selected = true;
phoneIcon = images.speakerActiveIcon;
_currentState = LISTENING_STATE;
this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.mute');
}
}
public function muteLocalUser():void {
var e:BBBEvent = new BBBEvent("MUTE_AUDIO_VOICE_CONFERENCE");
dispatcher.dispatchEvent(e);
this.enabled = true;
}
public function unmuteLocalUser():void{
var e:BBBEvent = new BBBEvent("UNMUTE_AUDIO_VOICE_CONFERENCE");
dispatcher.dispatchEvent(e);
this.enabled = true;
}
private function mouseOverHandler(event:MouseEvent):void {
if(_currentState == LISTENING_STATE)
phoneIcon = images.speakerInactiveIcon;
else
phoneIcon = images.speakerActiveIcon;
}
private function mouseOutHandler(event:MouseEvent):void {
if(_currentState == LISTENING_STATE)
phoneIcon = images.speakerActiveIcon;
else
phoneIcon = images.speakerInactiveIcon;
}
//For whatever reason the tooltip does not update when localization is changed dynamically. Overrideing it here
override protected function resourcesChanged():void{
this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');
}
public function getAlignment():String{
return MainToolbar.ALIGN_LEFT;
}
]]>
</mx:Script>
</mx:Button>

View File

@ -27,9 +27,10 @@
toolTip="{ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.stop')}"
implements="org.bigbluebutton.common.IBbbToolbarComponent">
<mate:Listener type="{BBBEvent.JOIN_VOICE_CONFERENCE}" method="handleBBBJoinConferenceEvent"/>
<mate:Listener type="MIC_SETTINGS_CLOSED" method="handleMicSettingsClosedEvent"/>
<mate:Listener type="ONLY_LISTENING_USER" method="muteUserOnlyListening" />
<mate:Listener type="SPEAKING_AND_LISTENING" method="handleBBBSpeakingAndListening"/>
<mate:Listener type="LISTENING_ONLY" method="handleBBBListeningOnly"/>
<mx:Script>
<![CDATA[
@ -37,7 +38,6 @@
import org.bigbluebutton.common.LogUtil;
import org.bigbluebutton.core.BBB;
import org.bigbluebutton.core.managers.UserManager;
import org.bigbluebutton.main.events.BBBEvent;
import org.bigbluebutton.main.views.MainToolbar;
import org.bigbluebutton.modules.phone.PhoneOptions;
@ -45,9 +45,7 @@
import org.bigbluebutton.modules.phone.events.CallDisconnectedEvent;
import org.bigbluebutton.modules.phone.views.assets.Images;
import org.bigbluebutton.util.i18n.ResourceUtil;
import org.bigbluebutton.modules.listeners.events.ListenersCommand;
private var images:Images = new Images();
private var dispatcher:Dispatcher = new Dispatcher();
@ -55,53 +53,22 @@
public const DEFAULT_STATE:Number = 0;
public const ACTIVE_STATE:Number = 1;
private var _currentState:Number = DEFAULT_STATE;
private var _changeState:Boolean = false;
[Bindable] public var phoneIcon:Class = images.headsetDefaultIcon;
private function startPhone():void {
// Disable the button right away to prevent the user from clicking
// multiple times.
this.enabled = false;
UserManager.getInstance().getConference().setFirstTimeUnMute(true);
if (this.selected) {
var vxml:XML = BBB.getConfigForModule("PhoneModule");
var phoneOptions:PhoneOptions = new PhoneOptions();
if (vxml != null) {
phoneOptions.showButton = (vxml.@showButton.toString().toUpperCase() == "TRUE") ? true : false;
phoneOptions.autoJoin = (vxml.@autoJoin.toString().toUpperCase() == "TRUE") ? true : false;
phoneOptions.skipCheck = (vxml.@skipCheck.toString().toUpperCase() == "TRUE") ? true : false;
}
//if (phoneOptions.skipCheck || noMicrophone()) {
/*
* If the user had no mic, let her join but she'll just be listening.
* We should indicate a warning that the user is joining without mic
* so that he will know that others won't be able to hear him.
*/
var joinEvent:BBBEvent = new BBBEvent("JOIN_VOICE_CONFERENCE_EVENT");
joinEvent.payload['useMicrophone'] = false;
dispatcher.dispatchEvent(joinEvent);
//} else {
// dispatcher.dispatchEvent(new BBBEvent("SHOW_MIC_SETTINGS"));
//}
} else {
var leaveEvent:BBBEvent = new BBBEvent("LEAVE_VOICE_CONFERENCE_EVENT");
leaveEvent.payload["userRequested"] = true;
dispatcher.dispatchEvent(leaveEvent);
userJoinedConference(false);
}
var askToChangeEvent:BBBEvent;
askToChangeEvent = new BBBEvent("ASK_TO_CHANGE_VOICE_CONFERENCE_EVENT");
if(_currentState == DEFAULT_STATE)
askToChangeEvent.payload["global"] = false;
else
askToChangeEvent.payload["global"] = true;
dispatcher.dispatchEvent(askToChangeEvent);
}
public function muteUserOnlyListening():void {
LogUtil.debug("MUTANDO O USUARIO");
var e:ListenersCommand = new ListenersCommand(ListenersCommand.MUTE_USER);
e.userid = UserManager.getInstance().getConference().getMyVoiceUserId();
e.mute = true;
dispatcher.dispatchEvent(e);
}
private function mouseOverHandler(event:MouseEvent):void {
if(_currentState == ACTIVE_STATE)
phoneIcon = images.headsetInactiveIcon;
@ -132,6 +99,7 @@
phoneIcon = images.headsetDefaultIcon;
this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');
}
dispatcher.dispatchEvent(new BBBEvent("UNMUTE_AUDIO_VOICE_CONFERENCE"));
}
@ -149,14 +117,18 @@
this.toolTip = ResourceUtil.getInstance().getString('bbb.toolbar.phone.toolTip.start');
}
private function handleMicSettingsClosedEvent(event:BBBEvent):void {
private function handleBBBListeningOnly(event:BBBEvent):void {
userJoinedConference(false);
}
private function handleBBBSpeakingAndListening(event:BBBEvent):void {
userJoinedConference(true);
}
private function handleBBBJoinConferenceEvent(event:BBBEvent):void {
var joinEvent:BBBEvent = new BBBEvent("JOIN_VOICE_CONFERENCE_EVENT");
joinEvent.payload['useMicrophone'] = false;
dispatcher.dispatchEvent(joinEvent);
//var joinEvent:BBBEvent = new BBBEvent("JOIN_VOICE_CONFERENCE_EVENT");
//joinEvent.payload['useMicrophone'] = false;
//dispatcher.dispatchEvent(joinEvent);
}
//For whatever reason the tooltip does not update when localization is changed dynamically. Overrideing it here