public class PollingService { private static Logger log = Red5LoggerFactory.getLogger(PollingService.class, "bigbluebutton"); private MessagePublisher red5GW; public void setRed5Publisher(MessagePublisher inGW) { red5GW = inGW; } public void votePoll(Map<String, Object> message) { String meetingID = Red5.getConnectionLocal().getScope().getName(); String userId = getBbbSession().getInternalUserID(); String pollId = (String) message.get("pollId"); Integer questionId = (Integer) message.get("answerId"); Integer answerId = (Integer) message.get("answerId"); red5GW.votePoll(meetingID, userId, pollId, questionId, answerId); } public void showPollResult(Map<String, Object> message) { String meetingID = Red5.getConnectionLocal().getScope().getName(); String userId = getBbbSession().getInternalUserID(); String pollId = (String) message.get("pollId"); Boolean show = (Boolean) message.get("show"); red5GW.showPollResult(meetingID, userId, pollId, show); } public void sendPollingMessage(String json) { String meetingID = Red5.getConnectionLocal().getScope().getName(); String userId = getBbbSession().getInternalUserID(); red5GW.sendPollingMessage(json); } public void startPoll(Map<String, Object> message) { String meetingID = Red5.getConnectionLocal().getScope().getName(); String userId = getBbbSession().getInternalUserID(); String pollId = (String) message.get("pollId"); String pollType = (String) message.get("pollType"); red5GW.startPoll(meetingID, userId, pollId, pollType); } public void stopPoll(Map<String, Object> message) { String meetingID = Red5.getConnectionLocal().getScope().getName(); String userId = getBbbSession().getInternalUserID(); String pollId = (String) message.get("pollId"); red5GW.stopPoll(meetingID, userId, pollId); } private BigBlueButtonSession getBbbSession() { return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); } }
/** Contains information about a ChatRoom. */ @ThreadSafe public class ChatRoom { private static Logger log = Red5LoggerFactory.getLogger(ChatRoom.class, "bigbluebutton"); private final String name; private final Map<String, IChatRoomListener> listeners; ArrayList<String> messages; public ChatRoom(String name) { this.name = name; listeners = new ConcurrentHashMap<String, IChatRoomListener>(); this.messages = new ArrayList<String>(); } public String getName() { return name; } public void addRoomListener(IChatRoomListener listener) { if (!listeners.containsKey(listener.getName())) { log.debug("adding room listener"); listeners.put(listener.getName(), listener); } } public void removeRoomListener(IChatRoomListener listener) { log.debug("removing room listener"); listeners.remove(listener); } public List<String> getChatMessages() { return messages; } @SuppressWarnings("unchecked") public void sendMessage(String msg) { messages.add(msg); for (Iterator iter = listeners.values().iterator(); iter.hasNext(); ) { log.debug("calling on listener"); IChatRoomListener listener = (IChatRoomListener) iter.next(); log.debug("calling newChatMessage on listener " + listener.getName()); listener.newChatMessage(msg); } } }
public class LibraryDocuments { private static final Logger log = Red5LoggerFactory.getLogger(LibraryDocuments.class, OpenmeetingsVariables.webAppRootKey); private static LibraryDocuments instance; private LibraryDocuments() {} public static synchronized LibraryDocuments getInstance() { if (instance == null) { log.debug("instance created"); instance = new LibraryDocuments(); } return instance; } }
public class ProviderService implements IProviderService { private static final Logger log = Red5LoggerFactory.getLogger(ProviderService.class); /** {@inheritDoc} */ public INPUT_TYPE lookupProviderInput(IScope scope, String name, int type) { INPUT_TYPE result = INPUT_TYPE.NOT_FOUND; if (scope.getBasicScope(ScopeType.BROADCAST, name) != null) { // we have live input result = INPUT_TYPE.LIVE; } else { // "default" to VOD as a missing file will be picked up later on result = INPUT_TYPE.VOD; File file = getStreamFile(scope, name); if (file == null) { if (type == -2) { result = INPUT_TYPE.LIVE_WAIT; } log.debug("Requested stream: {} does not appear to be of VOD type", name); } } return result; } /** {@inheritDoc} */ public IMessageInput getProviderInput(IScope scope, String name) { IMessageInput msgIn = getLiveProviderInput(scope, name, false); if (msgIn == null) { return getVODProviderInput(scope, name); } return msgIn; } /** {@inheritDoc} */ public IMessageInput getLiveProviderInput(IScope scope, String name, boolean needCreate) { log.debug("Get live provider input for {} scope: {}", name, scope); // make sure the create is actually needed IBroadcastScope broadcastScope = scope.getBroadcastScope(name); if (broadcastScope == null && needCreate) { synchronized (scope) { // re-check if another thread already created the scope broadcastScope = scope.getBroadcastScope(name); if (broadcastScope == null) { broadcastScope = new BroadcastScope(scope, name); scope.addChildScope(broadcastScope); } } } return broadcastScope; } /** {@inheritDoc} */ public IMessageInput getVODProviderInput(IScope scope, String name) { log.debug("getVODProviderInput - scope: {} name: {}", scope, name); File file = getVODProviderFile(scope, name); if (file == null) { return null; } IPipe pipe = new InMemoryPullPullPipe(); pipe.subscribe(new FileProvider(scope, file), null); return pipe; } /** {@inheritDoc} */ public File getVODProviderFile(IScope scope, String name) { if (log.isDebugEnabled()) { log.debug("getVODProviderFile - scope: {} name: {}", scope, name); } File file = getStreamFile(scope, name); if (file == null || !file.exists()) { // if there is no file extension this is most likely a live stream if (name.indexOf('.') > 0) { log.info("File was null or did not exist: {}", name); } else { log.trace("VOD file {} was not found, may be live stream", name); } } return file; } /** {@inheritDoc} */ public boolean registerBroadcastStream(IScope scope, String name, IBroadcastStream bs) { if (log.isDebugEnabled()) { log.debug("Registering - name: {} stream: {} scope: {}", new Object[] {name, bs, scope}); ((Scope) scope).dump(); } IBroadcastScope broadcastScope = scope.getBroadcastScope(name); if (broadcastScope == null) { log.debug("Creating a new scope"); broadcastScope = new BroadcastScope(scope, name); if (scope.addChildScope(broadcastScope)) { log.debug("Broadcast scope added"); } else { log.warn("Broadcast scope was not added to {}", scope); } } // set the client broadcast stream if we have a broadcast scope if (broadcastScope != null && bs instanceof IClientBroadcastStream) { broadcastScope.setClientBroadcastStream((IClientBroadcastStream) bs); } if (log.isDebugEnabled()) { log.debug("Subscribing scope {} to provider {}", broadcastScope, bs.getProvider()); } return broadcastScope.subscribe(bs.getProvider(), null); } /** {@inheritDoc} */ public Set<String> getBroadcastStreamNames(IScope scope) { return scope.getBasicScopeNames(ScopeType.BROADCAST); } /** {@inheritDoc} */ public boolean unregisterBroadcastStream(IScope scope, String name) { return unregisterBroadcastStream(scope, name, null); } /** {@inheritDoc} */ public boolean unregisterBroadcastStream(IScope scope, String name, IBroadcastStream bs) { if (log.isDebugEnabled()) { log.debug("Unregistering - name: {} stream: {} scope: {}", new Object[] {name, bs, scope}); ((Scope) scope).dump(); } IBroadcastScope broadcastScope = scope.getBroadcastScope(name); if (bs != null) { log.debug("Unsubscribing scope {} from provider {}", broadcastScope, bs.getProvider()); broadcastScope.unsubscribe(bs.getProvider()); } // if the scope has no listeners try to remove it if (!((BasicScope) broadcastScope).hasEventListeners()) { if (log.isDebugEnabled()) { log.debug("Scope has no event listeners attempting removal"); } scope.removeChildScope(broadcastScope); } // verify that scope was removed return scope.getBasicScope(ScopeType.BROADCAST, name) == null; } private File getStreamFile(IScope scope, String name) { if (log.isDebugEnabled()) { log.debug("getStreamFile - name: {}", name); } IStreamableFileFactory factory = (IStreamableFileFactory) ScopeUtils.getScopeService(scope, IStreamableFileFactory.class); if (name.indexOf(':') == -1 && name.indexOf('.') == -1) { // Default to .flv files if no prefix and no extension is given. name = "flv:" + name; } // ams sends an asterisk at the start of the name on mp4, so remove it if (name.charAt(0) == '*') { name = name.substring(1); if (log.isTraceEnabled()) { log.trace("Removed star prefix: {}", name); } } for (IStreamableFileService service : factory.getServices()) { if (name.startsWith(service.getPrefix() + ':')) { name = service.prepareFilename(name); break; } } // look for a custom filename gen class IStreamFilenameGenerator filenameGenerator = (IStreamFilenameGenerator) ScopeUtils.getScopeService( scope, IStreamFilenameGenerator.class, DefaultStreamFilenameGenerator.class); // get the filename String filename = filenameGenerator.generateFilename(scope, name, GenerationType.PLAYBACK); File file; try { // most likely case first if (!filenameGenerator.resolvesToAbsolutePath()) { try { file = scope.getContext().getResource(filename).getFile(); } catch (FileNotFoundException e) { log.debug("File {} not found, nulling it", filename); file = null; } } else { file = new File(filename); } // check file existence if (file != null && !file.exists()) { // if it does not exist then null it out file = null; } } catch (IOException e) { log.info("Exception attempting to lookup file: {}", e.getMessage()); if (log.isDebugEnabled()) { log.warn("Exception attempting to lookup file: {}", name, e); } // null out the file (fix for issue #238) file = null; } return file; } }
/** * @author swagner This Class handles all session management * <p>TODO: Delete all inactive session by a scheduler */ @Transactional public class SessiondataDao { private static final Logger log = Red5LoggerFactory.getLogger(SessiondataDao.class, OpenmeetingsVariables.webAppRootKey); @PersistenceContext private EntityManager em; @Autowired private ManageCryptStyle manageCryptStyle; @Autowired private ISessionManager sessionManager; /** * creates a new session-object in the database * * @return */ public Sessiondata startsession() { try { log.debug("startsession :: startsession"); long thistime = new Date().getTime(); Sessiondata sessiondata = new Sessiondata(); sessiondata.setSession_id( manageCryptStyle .getInstanceOfCrypt() .createPassPhrase(String.valueOf(thistime).toString())); sessiondata.setRefresh_time(new Date()); sessiondata.setStarttermin_time(new Date()); sessiondata.setUser_id(null); sessiondata = em.merge(sessiondata); return sessiondata; } catch (Exception ex2) { log.error("[startsession]: ", ex2); } return null; } public Sessiondata getSessionByHash(String SID) { try { log.debug("updateUser User SID: " + SID); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Sessiondata> cq = cb.createQuery(Sessiondata.class); Root<Sessiondata> c = cq.from(Sessiondata.class); Predicate condition = cb.equal(c.get("session_id"), SID); cq.where(condition); TypedQuery<Sessiondata> q = em.createQuery(cq); List<Sessiondata> fullList = q.getResultList(); if (fullList.size() == 0) { log.error("Could not find session to update: " + SID); return null; } Sessiondata sd = fullList.get(0); return sd; } catch (Exception ex2) { log.error("[updateUser]: ", ex2); } return null; } /** * @param SID * @return */ public Long checkSession(String SID) { try { TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionById", Sessiondata.class); query.setParameter("session_id", SID); List<Sessiondata> sessions = query.getResultList(); Sessiondata sessiondata = null; if (sessions != null && sessions.size() > 0) { sessiondata = sessions.get(0); } // Update the Session Object if (sessiondata != null) updatesession(SID); // Checks if wether the Session or the User Object of that Session // is set yet if (sessiondata == null || sessiondata.getUser_id() == null || sessiondata.getUser_id().equals(new Long(0))) { return new Long(0); } else { return sessiondata.getUser_id(); } } catch (Exception ex2) { log.error("[checkSession]: ", ex2); } return null; } /** * update the session of a user with a new user id this is needed to see if the session is * loggedin * * @param SID * @param USER_ID */ public Boolean updateUser(String SID, long USER_ID) { try { log.debug("updateUser User: "******" || " + SID); TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionById", Sessiondata.class); query.setParameter("session_id", SID); List<Sessiondata> sessions = query.getResultList(); Sessiondata sessiondata = null; if (sessions != null && sessions.size() > 0) { sessiondata = sessions.get(0); } if (sessiondata == null) { log.error("Could not find session to Update"); return false; } log.debug("Found session to update: " + sessiondata.getSession_id() + " userId: " + USER_ID); sessiondata.setRefresh_time(new Date()); sessiondata.setUser_id(USER_ID); if (sessiondata.getId() == null) { em.persist(sessiondata); } else { if (!em.contains(sessiondata)) { em.merge(sessiondata); } } return true; } catch (Exception ex2) { log.error("[updateUser]: ", ex2); } return null; } public Boolean updateUser(String SID, long USER_ID, boolean storePermanent, Long language_id) { try { log.debug("updateUser User: "******" || " + SID); TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionById", Sessiondata.class); query.setParameter("session_id", SID); List<Sessiondata> sessions = query.getResultList(); Sessiondata sessiondata = null; if (sessions != null && sessions.size() > 0) { sessiondata = sessions.get(0); } if (sessiondata == null) { log.error("Could not find session to Update"); return false; } log.debug("Found session to update: " + sessiondata.getSession_id() + " userId: " + USER_ID); sessiondata.setRefresh_time(new Date()); sessiondata.setUser_id(USER_ID); if (storePermanent) { sessiondata.setStorePermanent(storePermanent); } sessiondata.setLanguage_id(language_id); if (sessiondata.getId() == null) { em.persist(sessiondata); } else { if (!em.contains(sessiondata)) { em.merge(sessiondata); } } // log.debug("session updated User: "******"[updateUser]: ", ex2); } return null; } public Boolean updateUserOrg(String SID, Long organization_id) { try { log.debug("updateUserOrg User: "******" || " + SID); TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionById", Sessiondata.class); query.setParameter("session_id", SID); List<Sessiondata> sessions = query.getResultList(); Sessiondata sessiondata = null; if (sessions != null && sessions.size() > 0) { sessiondata = sessions.get(0); } if (sessiondata == null) { log.error("Could not find session to Update"); return false; } log.debug( "Found session to update: " + sessiondata.getSession_id() + " organisation_id: " + organization_id); sessiondata.setRefresh_time(new Date()); sessiondata.setOrganization_id(organization_id); if (sessiondata.getId() == null) { em.persist(sessiondata); } else { if (!em.contains(sessiondata)) { em.merge(sessiondata); } } return true; } catch (Exception ex2) { log.error("[updateUser]: ", ex2); } return null; } public Boolean updateUserWithoutSession(String SID, Long USER_ID) { try { log.debug("updateUser User: "******" || " + SID); TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionById", Sessiondata.class); query.setParameter("session_id", SID); List<Sessiondata> sessions = query.getResultList(); Sessiondata sessiondata = null; if (sessions != null && sessions.size() > 0) { sessiondata = sessions.get(0); } if (sessiondata == null) { log.error("Could not find session to Update"); return false; } log.debug("Found session to update: " + sessiondata.getSession_id() + " userId: " + USER_ID); sessiondata.setRefresh_time(new Date()); sessiondata.setUser_id(USER_ID); if (sessiondata.getId() == null) { em.persist(sessiondata); } else { if (!em.contains(sessiondata)) { em.merge(sessiondata); } } return true; } catch (Exception ex2) { log.error("[updateUser]: ", ex2); } return null; } public Boolean updateUserRemoteSession(String SID, String sessionXml) { try { log.debug("updateUser User SID: " + SID); CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Sessiondata> cq = cb.createQuery(Sessiondata.class); Root<Sessiondata> c = cq.from(Sessiondata.class); Predicate condition = cb.equal(c.get("session_id"), SID); cq.where(condition); TypedQuery<Sessiondata> q = em.createQuery(cq); List<Sessiondata> fullList = q.getResultList(); if (fullList.size() == 0) { log.error("Could not find session to update: " + SID); return false; } else { // log.error("Found session to update: "+SID); } Sessiondata sd = fullList.get(0); sd.setRefresh_time(new Date()); sd.setSessionXml(sessionXml); if (sd.getId() == null) { em.persist(sd); } else { if (!em.contains(sd)) { em.merge(sd); } } return true; } catch (Exception ex2) { log.error("[updateUserRemoteSession]: ", ex2); } return null; } /** * update the session every time a user makes a request * * @param SID */ private void updatesession(String SID) { try { CriteriaBuilder cb = em.getCriteriaBuilder(); CriteriaQuery<Sessiondata> cq = cb.createQuery(Sessiondata.class); Root<Sessiondata> c = cq.from(Sessiondata.class); Predicate condition = cb.equal(c.get("session_id"), SID); cq.where(condition); TypedQuery<Sessiondata> q = em.createQuery(cq); List<Sessiondata> fullList = q.getResultList(); if (fullList.size() == 0) { log.error("Found NO session to updateSession: "); } else { // log.debug("Found session to updateSession: "); Sessiondata sd = fullList.iterator().next(); // log.debug("Found session to updateSession sd "+sd.getUser_id()+" "+sd.getSession_id()); sd.setRefresh_time(new Date()); if (sd.getId() == null) { em.persist(sd); } else { if (!em.contains(sd)) { em.merge(sd); } } } } catch (Exception ex2) { log.error("[updatesession]: ", ex2); } } /** * @param date * @return */ private List<Sessiondata> getSessionToDelete(Date refresh_time) { try { TypedQuery<Sessiondata> query = em.createNamedQuery("getSessionToDelete", Sessiondata.class); query.setParameter("refresh_time", refresh_time); return query.getResultList(); } catch (Exception ex2) { log.error("[getSessionToDelete]: ", ex2); } return null; } /** */ public void clearSessionTable() { try { log.debug("****** clearSessionTable: "); Calendar rightNow = Calendar.getInstance(); rightNow.setTimeInMillis(rightNow.getTimeInMillis() - 1800000); List<Sessiondata> l = this.getSessionToDelete(rightNow.getTime()); log.debug("clearSessionTable: " + l.size()); for (Iterator<Sessiondata> it = l.iterator(); it.hasNext(); ) { Sessiondata sData = it.next(); sData = em.find(Sessiondata.class, sData.getId()); em.remove(sData); } } catch (Exception err) { log.error("clearSessionTable", err); } } /** @param room_id */ public void clearSessionByRoomId(Long room_id) { try { for (Client rcl : sessionManager.getClientListByRoom(room_id)) { String aux = rcl.getSwfurl(); int init_pos = aux.indexOf("sid=") + 4; int end_pos = init_pos + 32; if (end_pos > aux.length()) end_pos = aux.length(); String SID = aux.substring(init_pos, end_pos); Sessiondata sData = this.getSessionByHash(SID); sData = em.find(Sessiondata.class, sData.getId()); em.remove(sData); } } catch (Exception err) { log.error("clearSessionByRoomId", err); } } }
public class DemoService { private static Logger log = Red5LoggerFactory.getLogger(DemoService.class, "video"); { log.info("oflaDemo DemoService created"); } private String formatDate(Date date) { SimpleDateFormat formatter; String pattern = "dd/MM/yy H:mm:ss"; Locale locale = new Locale("en", "US"); formatter = new SimpleDateFormat(pattern, locale); return formatter.format(date); } /** * Getter for property 'listOfAvailableFLVs'. * * @return Value for property 'listOfAvailableFLVs'. */ public Map<String, Map<String, Object>> getListOfAvailableFLVs() { IScope scope = Red5.getConnectionLocal().getScope(); Map<String, Map<String, Object>> filesMap = new HashMap<String, Map<String, Object>>(); try { log.debug("getting the FLV files"); addToMap(filesMap, scope.getResources("streams/*.flv")); addToMap(filesMap, scope.getResources("streams/*.f4v")); addToMap(filesMap, scope.getResources("streams/*.mp3")); addToMap(filesMap, scope.getResources("streams/*.mp4")); addToMap(filesMap, scope.getResources("streams/*.m4a")); addToMap(filesMap, scope.getResources("streams/*.3g2")); addToMap(filesMap, scope.getResources("streams/*.3gp")); } catch (IOException e) { log.error("", e); } return filesMap; } private void addToMap(Map<String, Map<String, Object>> filesMap, Resource[] files) throws IOException { if (files != null) { for (Resource flv : files) { File file = flv.getFile(); Date lastModifiedDate = new Date(file.lastModified()); String lastModified = formatDate(lastModifiedDate); String flvName = flv.getFile().getName(); String flvBytes = Long.toString(file.length()); if (log.isDebugEnabled()) { log.debug("flvName: {}", flvName); log.debug("lastModified date: {}", lastModified); log.debug("flvBytes: {}", flvBytes); log.debug("-------"); } Map<String, Object> fileInfo = new HashMap<String, Object>(); fileInfo.put("name", flvName); fileInfo.put("lastModified", lastModified); fileInfo.put("size", flvBytes); filesMap.put(flvName, fileInfo); } } } }
public class ClientManager implements ClientNotifier { private static Logger log = Red5LoggerFactory.getLogger(ClientManager.class, "bigbluebutton"); private final ConcurrentMap<String, RoomInfo> voiceRooms; private final ConcurrentMap<String, RoomInfo> webRooms; public ClientManager() { voiceRooms = new ConcurrentHashMap<String, RoomInfo>(); webRooms = new ConcurrentHashMap<String, RoomInfo>(); } public void addSharedObject(String webRoom, String voiceRoom, ISharedObject so) { log.debug("Adding SO for [" + webRoom + "," + voiceRoom + "]"); RoomInfo soi = new RoomInfo(webRoom, voiceRoom, so); voiceRooms.putIfAbsent(voiceRoom, soi); webRooms.putIfAbsent(webRoom, soi); } public void removeSharedObject(String webRoom) { RoomInfo soi = webRooms.remove(webRoom); if (soi != null) voiceRooms.remove(soi.getVoiceRoom()); } private void joined( String room, Integer participant, String name, Boolean muted, Boolean talking, Boolean locked) { log.debug("Participant " + name + "joining room " + room); RoomInfo soi = voiceRooms.get(room); if (soi != null) { List<Object> list = new ArrayList<Object>(); list.add(participant); list.add(name); list.add(name); list.add(muted); list.add(talking); list.add(locked); log.debug("Sending join to client " + name); soi.getSharedObject().sendMessage("userJoin", list); } } private void left(String room, Integer participant) { log.debug("Participant [" + participant + "," + room + "] leaving"); RoomInfo soi = voiceRooms.get(room); if (soi != null) { List<Object> list = new ArrayList<Object>(); list.add(participant); soi.getSharedObject().sendMessage("userLeft", list); } } private void muted(String room, Integer participant, Boolean muted) { log.debug("Participant " + participant + " is muted = " + muted); RoomInfo soi = voiceRooms.get(room); if (soi != null) { List<Object> list = new ArrayList<Object>(); list.add(participant); list.add(muted); soi.getSharedObject().sendMessage("userMute", list); } } private void locked(String room, Integer participant, Boolean locked) { log.debug("Participant " + participant + " is locked = " + locked); RoomInfo soi = voiceRooms.get(room); if (soi != null) { List<Object> list = new ArrayList<Object>(); list.add(participant); list.add(locked); soi.getSharedObject().sendMessage("userLockedMute", list); } } private void talking(String room, Integer participant, Boolean talking) { log.debug("Participant " + participant + " is talking = " + talking); RoomInfo soi = voiceRooms.get(room); if (soi != null) { List<Object> list = new ArrayList<Object>(); list.add(participant); list.add(talking); soi.getSharedObject().sendMessage("userTalk", list); } } public void handleConferenceEvent(ConferenceEvent event) { if (event instanceof ParticipantJoinedEvent) { ParticipantJoinedEvent pje = (ParticipantJoinedEvent) event; joined( pje.getRoom(), pje.getParticipantId(), pje.getCallerIdName(), pje.getMuted(), pje.getSpeaking(), pje.isLocked()); } else if (event instanceof ParticipantLeftEvent) { left(event.getRoom(), event.getParticipantId()); } else if (event instanceof ParticipantMutedEvent) { ParticipantMutedEvent pme = (ParticipantMutedEvent) event; muted(pme.getRoom(), pme.getParticipantId(), pme.isMuted()); } else if (event instanceof ParticipantTalkingEvent) { ParticipantTalkingEvent pte = (ParticipantTalkingEvent) event; talking(pte.getRoom(), pte.getParticipantId(), pte.isTalking()); } else if (event instanceof ParticipantLockedEvent) { ParticipantLockedEvent ple = (ParticipantLockedEvent) event; locked(ple.getRoom(), ple.getParticipantId(), ple.isLocked()); } } }
public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { private static Logger log = Red5LoggerFactory.getLogger(BigBlueButtonApplication.class, "bigbluebutton"); private ConnectionInvokerService connInvokerService; private MessagePublisher red5InGW; private final UserConnectionMapper userConnections = new UserConnectionMapper(); private final String APP = "BBB"; private final String CONN = "RED5-"; @Override public boolean appConnect(IConnection conn, Object[] params) { return super.appConnect(conn, params); } @Override public void appDisconnect(IConnection conn) { super.appDisconnect(conn); } @Override public boolean appJoin(IClient client, IScope scope) { return super.appJoin(client, scope); } @Override public void appLeave(IClient client, IScope scope) { super.appLeave(client, scope); } @Override public boolean roomJoin(IClient client, IScope scope) { return super.roomJoin(client, scope); } @Override public void roomLeave(IClient client, IScope scope) { super.roomLeave(client, scope); } @Override public boolean appStart(IScope app) { super.appStart(app); connInvokerService.setAppScope(app); return true; } @Override public void appStop(IScope app) { super.appStop(app); } @Override public boolean roomStart(IScope room) { return super.roomStart(room); } @Override public void roomStop(IScope room) { super.roomStop(room); } @Override public boolean roomConnect(IConnection connection, Object[] params) { String username = ((String) params[0]).toString(); String role = ((String) params[1]).toString(); String room = ((String) params[2]).toString(); String voiceBridge = ((String) params[3]).toString(); boolean record = (Boolean) params[4]; String externalUserID = ((String) params[5]).toString(); String internalUserID = ((String) params[6]).toString(); Boolean muted = false; if (params.length >= 7 && ((Boolean) params[7])) { muted = true; } Map<String, Boolean> lsMap = null; if (params.length >= 8) { try { lsMap = (Map<String, Boolean>) params[8]; } catch (Exception e) { lsMap = new HashMap<String, Boolean>(); } } String userId = internalUserID; String sessionId = CONN + userId; BigBlueButtonSession bbbSession = new BigBlueButtonSession( room, internalUserID, username, role, voiceBridge, record, externalUserID, muted, sessionId); connection.setAttribute(Constants.SESSION, bbbSession); connection.setAttribute("INTERNAL_USER_ID", internalUserID); connection.setAttribute("USER_SESSION_ID", sessionId); connection.setAttribute("TIMESTAMP", System.currentTimeMillis()); red5InGW.initLockSettings(room, lsMap); red5InGW.initAudioSettings(room, internalUserID, muted); String meetingId = bbbSession.getRoom(); String connType = getConnectionType(Red5.getConnectionLocal().getType()); String userFullname = bbbSession.getUsername(); String connId = Red5.getConnectionLocal().getSessionId(); String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("connType", connType); logData.put("connId", connId); logData.put("conn", remoteHost + ":" + remotePort); logData.put("userId", userId); logData.put("externalUserId", externalUserID); logData.put("sessionId", sessionId); logData.put("username", userFullname); logData.put("event", "user_joining_bbb_apps"); logData.put("description", "User joining BBB Apps."); Gson gson = new Gson(); String logStr = gson.toJson(logData); log.info("User joining bbb-apps: data={}", logStr); userConnections.addUserConnection(userId, connId); return super.roomConnect(connection, params); } private String getConnectionType(String connType) { if ("persistent".equals(connType.toLowerCase())) { return "RTMP"; } else if ("polling".equals(connType.toLowerCase())) { return "RTMPT"; } else { return connType.toUpperCase(); } } @Override public void roomDisconnect(IConnection conn) { String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); String clientId = Red5.getConnectionLocal().getClient().getId(); BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); String meetingId = bbbSession.getRoom(); String userId = bbbSession.getInternalUserID(); String connType = getConnectionType(Red5.getConnectionLocal().getType()); String userFullname = bbbSession.getUsername(); String connId = Red5.getConnectionLocal().getSessionId(); String sessionId = CONN + userId; Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("connType", connType); logData.put("connId", connId); logData.put("conn", remoteHost + ":" + remotePort); logData.put("sessionId", sessionId); logData.put("userId", userId); logData.put("username", userFullname); logData.put("event", "user_leaving_bbb_apps"); logData.put("description", "User leaving BBB Apps."); Gson gson = new Gson(); String logStr = gson.toJson(logData); boolean removeUser = userConnections.userDisconnected(userId, connId); if (removeUser) { log.info("User leaving bbb-apps: data={}", logStr); red5InGW.userLeft(bbbSession.getRoom(), getBbbSession().getInternalUserID(), sessionId); } else { log.info("User not leaving bbb-apps but just disconnected: data={}", logStr); } super.roomDisconnect(conn); } public void validateToken(Map<String, String> msg) { String token = (String) msg.get("authToken"); BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); assert bbbSession != null; String userId = bbbSession.getInternalUserID(); String meetingId = Red5.getConnectionLocal().getScope().getName(); String connId = Red5.getConnectionLocal().getSessionId(); String sessionId = CONN + connId + "-" + userId; Map<String, Object> logData = new HashMap<String, Object>(); logData.put("meetingId", meetingId); logData.put("connId", connId); logData.put("sessionId", sessionId); logData.put("userId", userId); logData.put("token", token); logData.put("event", "user_validate_token_bbb_apps"); logData.put("description", "User validate token BBB Apps."); Gson gson = new Gson(); String logStr = gson.toJson(logData); log.info("User validate token bbb-apps: data={}", logStr); red5InGW.validateAuthToken(meetingId, userId, token, meetingId + "/" + userId, sessionId); } public void setApplicationListeners(Set<IApplication> listeners) { Iterator<IApplication> iter = listeners.iterator(); while (iter.hasNext()) { super.addListener((IApplication) iter.next()); } } private BigBlueButtonSession getBbbSession() { return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); } public void setConnInvokerService(ConnectionInvokerService connInvokerService) { this.connInvokerService = connInvokerService; } public void setRed5Publisher(MessagePublisher red5InGW) { this.red5InGW = red5InGW; } }
public class SipPhoneApplication extends MultiThreadedApplicationAdapter implements IStreamAwareScopeHandler { protected static Logger log = Red5LoggerFactory.getLogger(SipPhoneApplication.class, "sip"); private SipUserManager sipManager; private boolean available = false; private int startSIPPort = 5070; private int stopSIPPort = 5099; private int sipPort; private int startRTPPort = 3000; private int stopRTPPort = 3029; private int rtpPort; private Map<String, String> userNames = new HashMap<String, String>(); @Override public boolean appStart(IScope scope) { loginfo("Red5SIP starting in scope " + scope.getName() + " " + System.getProperty("user.dir")); loginfo( "Red5SIP using RTP port range " + startRTPPort + "-" + stopRTPPort + ", using SIP port range " + startSIPPort + "-" + stopSIPPort); sipPort = startSIPPort; rtpPort = startRTPPort; return true; } @Override public void appStop(IScope scope) { loginfo("Red5SIP stopping in scope " + scope.getName()); sipManager.destroyAllSessions(); } @Override public boolean appConnect(IConnection conn, Object[] params) { IServiceCapableConnection service = (IServiceCapableConnection) conn; loginfo("Red5SIP Client connected " + conn.getClient().getId() + " service " + service); return true; } @Override public boolean appJoin(IClient client, IScope scope) { loginfo("Red5SIP Client joined app " + client.getId()); IConnection conn = Red5.getConnectionLocal(); IServiceCapableConnection service = (IServiceCapableConnection) conn; return true; } @Override public void appLeave(IClient client, IScope scope) { IConnection conn = Red5.getConnectionLocal(); loginfo("Red5SIP Client leaving app " + client.getId()); if (userNames.containsKey(client.getId())) { loginfo("Red5SIP Client closing client " + userNames.get(client.getId())); // sipManager.closeSIPUser( userNames.get( client.getId() ) ); userNames.remove(client.getId()); } } public void streamPublishStart(IBroadcastStream stream) { loginfo("Red5SIP Stream publish start: " + stream.getPublishedName()); IConnection current = Red5.getConnectionLocal(); } public void streamBroadcastClose(IBroadcastStream stream) { loginfo("Red5SIP Stream broadcast close: " + stream.getPublishedName()); } public void streamBroadcastStart(IBroadcastStream stream) { loginfo("Red5SIP Stream broadcast start: " + stream.getPublishedName()); } public void streamPlaylistItemPlay( IPlaylistSubscriberStream stream, IPlayItem item, boolean isLive) { loginfo("Red5SIP Stream play: " + item.getName()); } public void streamPlaylistItemStop(IPlaylistSubscriberStream stream, IPlayItem item) { loginfo("Red5SIP Stream stop: " + item.getName()); } public void streamPlaylistVODItemPause( IPlaylistSubscriberStream stream, IPlayItem item, int position) {} public void streamPlaylistVODItemResume( IPlaylistSubscriberStream stream, IPlayItem item, int position) {} public void streamPlaylistVODItemSeek( IPlaylistSubscriberStream stream, IPlayItem item, int position) {} public void streamSubscriberClose(ISubscriberStream stream) { loginfo("Red5SIP Stream subscribe close: " + stream.getName()); } public void streamSubscriberStart(ISubscriberStream stream) { loginfo("Red5SIP Stream subscribe start: " + stream.getName()); } public Set<String> getStreams() { IConnection conn = Red5.getConnectionLocal(); return getBroadcastStreamNames(conn.getScope()); } public void onPing() { loginfo("Red5SIP Ping"); } public void open( String obproxy, String uid, String phone, String username, String password, String realm, String proxy) { loginfo("Red5SIP open"); login(obproxy, uid, phone, username, password, realm, proxy); register(uid); } public void login( String obproxy, String uid, String phone, String username, String password, String realm, String proxy) { loginfo("Red5SIP login " + uid); /* IConnection conn = Red5.getConnectionLocal(); IServiceCapableConnection service = (IServiceCapableConnection) conn; SipUser sipUser = sipManager.getSIPUser(uid); if(sipUser == null) { loginfo("Red5SIP open creating sipUser for " + username + " on sip port " + sipPort + " audio port " + rtpPort + " uid " + uid ); try { sipUser = new User(conn.getClient().getId(), service, sipPort, rtpPort); sipManager.addSIPUser(uid, sipUser); } catch (Exception e) { loginfo("open error " + e); } } sipUser.login(obproxy,phone,username, password, realm, proxy); userNames.put(conn.getClient().getId(), uid); sipPort++; if (sipPort > stopSIPPort) sipPort = startSIPPort; rtpPort++; if (rtpPort > stopRTPPort) rtpPort = startRTPPort; */ } public void register(String uid) { loginfo("Red5SIP register"); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { sipUser.register(); } */ } public void call(String uid, String destination) { loginfo("Red5SIP Call " + destination); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { loginfo("Red5SIP Call found user " + uid + " making call to " + destination); sipUser.call(destination); } */ } /** call tarensfer test by Lior */ public void transfer(String uid, String transferTo) { loginfo("Red5SIP transfer " + transferTo); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { loginfo("Red5SIP Call found user " + uid + " transfering call to " + transferTo); sipUser.transfer(transferTo); } */ } /** transfer end tetst */ public void addToConf(String uid, String conf) { loginfo("Red5SIP addToConf " + conf); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { loginfo("Red5SIP addToConf found user " + uid + " adding to conf " + conf); sipUser.transfer("8" + conf); } */ } public void joinConf(String uid, String conf) { loginfo("Red5SIP joinConf " + conf); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { loginfo("Red5SIP joinConf found user " + uid + " joining conf " + conf); sipUser.call("8" + conf ); } */ } public void dtmf(String uid, String digits) { loginfo("Red5SIP DTMF " + digits); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { loginfo("Red5SIP DTMF found user " + uid + " sending dtmf digits " + digits); sipUser.dtmf(digits); } */ } public void accept(String uid) { loginfo("Red5SIP Accept"); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { sipUser.accept(); } */ } // Lior Add public void unregister(String uid) { loginfo("Red5SIP unregister"); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { sipUser.unregister(); } */ } public void hangup(String uid) { loginfo("Red5SIP Hangup"); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { sipUser.hangup(); } */ } public void streamStatus(String uid, String status) { loginfo("Red5SIP streamStatus"); /* User sipUser = sipManager.getSIPUser(uid); if(sipUser != null) { sipUser.streamStatus(status); } */ } public void close(String uid) { loginfo("Red5SIP endRegister"); /* IConnection conn = Red5.getConnectionLocal(); sipManager.closeSIPUser(uid); userNames.remove(conn.getClient().getId()); */ } private void loginfo(String s) { log.info(s); } public void setSipUserManager(SipUserManager sum) { sipManager = sum; } }
public class BlockStreamEventMessageHandler extends IoHandlerAdapter { private final Logger log = Red5LoggerFactory.getLogger(BlockStreamEventMessageHandler.class, "deskshare"); private ISessionManagerGateway sessionManager; private static final String ROOM = "ROOM"; @Override public void exceptionCaught(IoSession session, Throwable cause) throws Exception { log.warn(cause.toString() + " \n " + cause.getMessage()); cause.printStackTrace(); closeSession(session); } private void closeSession(IoSession session) { String room = (String) session.getAttribute(ROOM, null); if (room != null) { log.info("Closing session [" + room + "]. "); } else { log.info("Cannot determine session to close."); } CloseFuture future = session.close(true); } @Override public void messageReceived(IoSession session, Object message) throws Exception { if (message instanceof CaptureStartBlockEvent) { System.out.println("Got CaptureStartBlockEvent"); CaptureStartBlockEvent event = (CaptureStartBlockEvent) message; sessionManager.createSession( event.getRoom(), event.getScreenDimension(), event.getBlockDimension(), event.getSequenceNum(), event.isUseSVC2()); } else if (message instanceof CaptureUpdateBlockEvent) { // System.out.println("Got CaptureUpdateBlockEvent"); CaptureUpdateBlockEvent event = (CaptureUpdateBlockEvent) message; sessionManager.updateBlock( event.getRoom(), event.getPosition(), event.getVideoData(), event.isKeyFrame(), event.getSequenceNum()); } else if (message instanceof CaptureEndBlockEvent) { CaptureEndBlockEvent event = (CaptureEndBlockEvent) message; sessionManager.removeSession(event.getRoom(), event.getSequenceNum()); } else if (message instanceof MouseLocationEvent) { MouseLocationEvent event = (MouseLocationEvent) message; sessionManager.updateMouseLocation(event.getRoom(), event.getLoc(), event.getSequenceNum()); } } @Override public void sessionIdle(IoSession session, IdleStatus status) throws Exception { log.debug("IDLE " + session.getIdleCount(status)); super.sessionIdle(session, status); } @Override public void sessionCreated(IoSession session) throws Exception { log.debug("Session Created"); super.sessionCreated(session); } @Override public void sessionOpened(IoSession session) throws Exception { log.debug("Session Opened."); super.sessionOpened(session); } @Override public void sessionClosed(IoSession session) throws Exception { log.debug("Session Closed."); String room = (String) session.getAttribute("ROOM"); if (room != null) { log.debug("Session Closed for room " + room); sessionManager.removeSession(room, 0); } else { log.warn("Closing session for a NULL room"); } } public void setSessionManagerGateway(ISessionManagerGateway sm) { sessionManager = sm; } }
@SuppressWarnings("unchecked") public class RetroDocumentDAOImpl extends SqlMapClientTemplate implements RetroDocumentDAO { private static final Logger logger = Red5LoggerFactory.getLogger(RetroDocumentDAOImpl.class, "visu"); public Collection<RetroDocument> getRetroDocumentsByOwnerAndBySession( Integer ownerId, Integer sessionId) throws SQLException { return (List<RetroDocument>) getSqlMapClient() .queryForList( "rd.getDocumentsByOwnerIdAndSessionId", createParams("ownerId", ownerId, "sessionId", sessionId)); } public RetroDocument getRetroDocumentById(Integer id) throws SQLException { return (RetroDocument) getSqlMapClient().queryForObject("rd.getDocumentById", id); } public RetroDocument createRetroDocument(Integer ownerId, Integer sessionId) throws SQLException { RetroDocument doc = new RetroDocument(); Date creationDate = new Date(); doc.setCreationDate(creationDate); doc.setLastModified(creationDate); doc.setSessionId(sessionId); doc.setOwnerId(ownerId); doc.setDocumentId((Integer) getSqlMapClient().insert("rd.insertDocument", doc)); return doc; } public static Map<String, Object> createParams(Object... params) { Map<String, Object> map = new HashMap<String, Object>(); for (int k = 0; k < params.length / 2; k++) map.put((String) params[2 * k], params[2 * k + 1]); return map; } public boolean saveRetroDocument(RetroDocument document) throws SQLException { return getSqlMapClient().update("rd.updateDocument", document) == 1; } public boolean deleteRetroDocument(Integer documentId) throws SQLException { SqlMapClient sqlMapClient = getSqlMapClient(); sqlMapClient.startTransaction(); boolean b = sqlMapClient.delete("rd.deleteDocument", documentId) == 1 && sqlMapClient.delete("rd.deleteAllInvitations", documentId) == 1; sqlMapClient.commitTransaction(); return b; } public Collection<RetroDocument> getRetroDocumentsByOwner(Integer ownerId) throws SQLException { return (Collection<RetroDocument>) getSqlMapClient().queryForList("rd.getDocumentsByOwner", ownerId); } public void createInvitee(Integer documentId, Integer inviteeId) throws SQLException { getSqlMapClient() .insert("rd.insertInvitation", createParams("documentId", documentId, "userId", inviteeId)); } public boolean removeInvitee(Integer documentId, Integer inviteeId) throws SQLException { return getSqlMapClient() .delete( "rd.deleteInvitation", createParams("documentId", documentId, "userId", inviteeId)) == 1; } public Collection<String> getInviteeList(Integer documentId) throws SQLException { return getSqlMapClient().queryForList("rd.getInviteesByDocumentId", documentId); } public Collection<RetroDocument> getRetroDocumentIdByInviteeId(Integer inviteeId) throws SQLException { return getSqlMapClient().queryForList("rd.getDocumentsByInviteeId", inviteeId); } public Collection<RetroDocument> getRetroDocumentsByOwnerAndBySessionWithoutXML( Integer ownerId, Integer sessionId) throws SQLException { return (List<RetroDocument>) getSqlMapClient() .queryForList( "rd.getDocumentsByOwnerIdAndSessionIdWithoutXML", createParams("ownerId", ownerId, "sessionId", sessionId)); } public Collection<RetroDocument> getRetroDocumentsByOwnerWithoutXML(Integer ownerId) throws SQLException { return (List<RetroDocument>) getSqlMapClient() .queryForList("rd.getDocumentsAndInviteeListAndSessionByOwnerIdWithoutXML", ownerId); } public Collection<RetroDocument> getRetroDocumentsByInviteeWithoutXML(Integer inviteeId) throws SQLException { return (List<RetroDocument>) getSqlMapClient() .queryForList( "rd.getDocumentsAndInviteeListAndSessionByInviteeIdWithoutXML", inviteeId); } public Collection<RetroDocument> getRetroDocumentWithoutXMLByInviteeIdAndSessionId( Integer inviteeId, Integer sessionId) throws SQLException { return (List<RetroDocument>) getSqlMapClient() .queryForList( "rd.getDocumentsByInviteeIdAndSessionIdWithoutXML", createParams("inviteeId", inviteeId, "sessionId", sessionId)); } }
public class Application extends MultiThreadedApplicationAdapter { private static Logger log = Red5LoggerFactory.getLogger(Application.class, "sip"); private SipPeerManager sipPeerManager; private ClientConnectionManager clientConnManager; private String sipServerHost = "localhost"; private int sipPort = 5070; private int startAudioPort = 3000; private int stopAudioPort = 3029; private String password = "******"; private String username; private CallStreamFactory callStreamFactory; @Override public boolean appStart(IScope scope) { log.debug("VoiceConferenceApplication appStart[" + scope.getName() + "]"); callStreamFactory = new CallStreamFactory(); callStreamFactory.setScope(scope); sipPeerManager.setCallStreamFactory(callStreamFactory); sipPeerManager.setClientConnectionManager(clientConnManager); sipPeerManager.createSipPeer("default", sipServerHost, sipPort, startAudioPort, stopAudioPort); try { sipPeerManager.register("default", username, password); } catch (PeerNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } return true; } @Override public void appStop(IScope scope) { log.debug("VoiceConferenceApplication appStop[" + scope.getName() + "]"); sipPeerManager.destroyAllSessions(); } @Override public boolean appConnect(IConnection conn, Object[] params) { String userid = ((String) params[0]).toString(); String username = ((String) params[1]).toString(); String clientId = Red5.getConnectionLocal().getClient().getId(); String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); if ((userid == null) || ("".equals(userid))) userid = "unknown-userid"; if ((username == null) || ("".equals(username))) username = "******"; Red5.getConnectionLocal().setAttribute("USERID", userid); Red5.getConnectionLocal().setAttribute("USERNAME", username); log.info( "{} [clientid={}] has connected to the voice conf app.", username + "[uid=" + userid + "]", clientId); log.info("[clientid={}] connected from {}.", clientId, remoteHost + ":" + remotePort); clientConnManager.createClient( clientId, userid, username, (IServiceCapableConnection) Red5.getConnectionLocal()); return true; } @Override public void appDisconnect(IConnection conn) { String clientId = Red5.getConnectionLocal().getClient().getId(); String userid = getUserId(); String username = getUsername(); String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); log.info("[clientid={}] disconnnected from {}.", clientId, remoteHost + ":" + remotePort); log.debug( "{} [clientid={}] is leaving the voice conf app. Removing from ConnectionManager.", username + "[uid=" + userid + "]", clientId); clientConnManager.removeClient(clientId); String peerId = (String) Red5.getConnectionLocal().getAttribute("VOICE_CONF_PEER"); if (peerId != null) { try { log.debug( "Forcing hang up {} [clientid={}] in case the user is still in the conference.", username + "[uid=" + userid + "]", clientId); sipPeerManager.hangup(peerId, clientId); } catch (PeerNotFoundException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } @Override public void streamPublishStart(IBroadcastStream stream) { String clientId = Red5.getConnectionLocal().getClient().getId(); String userid = getUserId(); String username = getUsername(); log.debug( "{} has started publishing stream [{}]", username + "[uid=" + userid + "][clientid=" + clientId + "]", stream.getPublishedName()); System.out.println("streamPublishStart: " + stream.getPublishedName()); IConnection conn = Red5.getConnectionLocal(); String peerId = (String) conn.getAttribute("VOICE_CONF_PEER"); if (peerId != null) { super.streamPublishStart(stream); sipPeerManager.startTalkStream(peerId, clientId, stream, conn.getScope()); // recordStream(stream); } } /** * A hook to record a sample stream. A file is written in webapps/sip/streams/ * * @param stream */ private void recordStream(IBroadcastStream stream) { IConnection conn = Red5.getConnectionLocal(); String streamName = stream.getPublishedName(); try { ClientBroadcastStream cstream = (ClientBroadcastStream) this.getBroadcastStream(conn.getScope(), stream.getPublishedName()); cstream.saveAs(streamName, false); } catch (Exception e) { System.out.println("ERROR while recording stream " + e.getMessage()); e.printStackTrace(); } } @Override public void streamBroadcastClose(IBroadcastStream stream) { String clientId = Red5.getConnectionLocal().getClient().getId(); String userid = getUserId(); String username = getUsername(); log.debug( "{} has stopped publishing stream [{}]", username + "[uid=" + userid + "][clientid=" + clientId + "]", stream.getPublishedName()); IConnection conn = Red5.getConnectionLocal(); String peerId = (String) conn.getAttribute("VOICE_CONF_PEER"); if (peerId != null) { super.streamPublishStart(stream); sipPeerManager.stopTalkStream(peerId, clientId, stream, conn.getScope()); super.streamBroadcastClose(stream); } } public List<String> getStreams() { IConnection conn = Red5.getConnectionLocal(); return getBroadcastStreamNames(conn.getScope()); } public void onPing() { log.debug("Red5SIP Ping"); } public void setSipServerHost(String h) { sipServerHost = h.trim(); } public void setUsername(String un) { this.username = un.trim(); } public void setPassword(String pw) { this.password = pw.trim(); } public void setSipPort(int sipPort) { this.sipPort = sipPort; } public void setStartAudioPort(int startRTPPort) { this.startAudioPort = startRTPPort; } public void setStopAudioPort(int stopRTPPort) { this.stopAudioPort = stopRTPPort; } public void setSipPeerManager(SipPeerManager spm) { sipPeerManager = spm; } public void setClientConnectionManager(ClientConnectionManager ccm) { clientConnManager = ccm; } private String getUserId() { String userid = (String) Red5.getConnectionLocal().getAttribute("USERID"); if ((userid == null) || ("".equals(userid))) userid = "unknown-userid"; return userid; } private String getUsername() { String username = (String) Red5.getConnectionLocal().getAttribute("USERNAME"); if ((username == null) || ("".equals(username))) username = "******"; return username; } }
public class ChatService { private static Logger log = Red5LoggerFactory.getLogger(ChatService.class, "bigbluebutton"); private MessagePublisher red5BBBInGw; public void sendPublicChatHistory() { String meetingID = Red5.getConnectionLocal().getScope().getName(); String requesterID = getBbbSession().getInternalUserID(); // Just hardcode as we don't really need it for flash client. (ralam may 7, 2014) String replyTo = meetingID + "/" + requesterID; red5BBBInGw.getChatHistory(meetingID, requesterID, replyTo); } private BigBlueButtonSession getBbbSession() { return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); } public void sendPublicMessage(Map<String, Object> msg) { String chatType = msg.get(ChatKeyUtil.CHAT_TYPE).toString(); String fromUserID = msg.get(ChatKeyUtil.FROM_USERID).toString(); String fromUsername = msg.get(ChatKeyUtil.FROM_USERNAME).toString(); String fromColor = msg.get(ChatKeyUtil.FROM_COLOR).toString(); String fromTime = msg.get(ChatKeyUtil.FROM_TIME).toString(); String fromTimezoneOffset = msg.get(ChatKeyUtil.FROM_TZ_OFFSET).toString(); String toUserID = msg.get(ChatKeyUtil.TO_USERID).toString(); String toUsername = msg.get(ChatKeyUtil.TO_USERNAME).toString(); String chatText = msg.get(ChatKeyUtil.MESSAGE).toString(); Map<String, String> message = new HashMap<String, String>(); message.put(ChatKeyUtil.CHAT_TYPE, chatType); message.put(ChatKeyUtil.FROM_USERID, fromUserID); message.put(ChatKeyUtil.FROM_USERNAME, fromUsername); message.put(ChatKeyUtil.FROM_COLOR, fromColor); message.put(ChatKeyUtil.FROM_TIME, fromTime); message.put(ChatKeyUtil.FROM_TZ_OFFSET, fromTimezoneOffset); message.put(ChatKeyUtil.TO_USERID, toUserID); message.put(ChatKeyUtil.TO_USERNAME, toUsername); message.put(ChatKeyUtil.MESSAGE, chatText); String meetingID = Red5.getConnectionLocal().getScope().getName(); String requesterID = getBbbSession().getInternalUserID(); red5BBBInGw.sendPublicMessage(meetingID, requesterID, message); } public void setRed5Publisher(MessagePublisher inGW) { red5BBBInGw = inGW; } public void sendPrivateMessage(Map<String, Object> msg) { String chatType = msg.get(ChatKeyUtil.CHAT_TYPE).toString(); String fromUserID = msg.get(ChatKeyUtil.FROM_USERID).toString(); String fromUsername = msg.get(ChatKeyUtil.FROM_USERNAME).toString(); String fromColor = msg.get(ChatKeyUtil.FROM_COLOR).toString(); String fromTime = msg.get(ChatKeyUtil.FROM_TIME).toString(); String fromTimezoneOffset = msg.get(ChatKeyUtil.FROM_TZ_OFFSET).toString(); String toUserID = msg.get(ChatKeyUtil.TO_USERID).toString(); String toUsername = msg.get(ChatKeyUtil.TO_USERNAME).toString(); String chatText = msg.get(ChatKeyUtil.MESSAGE).toString(); Map<String, String> message = new HashMap<String, String>(); message.put(ChatKeyUtil.CHAT_TYPE, chatType); message.put(ChatKeyUtil.FROM_USERID, fromUserID); message.put(ChatKeyUtil.FROM_USERNAME, fromUsername); message.put(ChatKeyUtil.FROM_COLOR, fromColor); message.put(ChatKeyUtil.FROM_TIME, fromTime); message.put(ChatKeyUtil.FROM_TZ_OFFSET, fromTimezoneOffset); message.put(ChatKeyUtil.TO_USERID, toUserID); message.put(ChatKeyUtil.TO_USERNAME, toUsername); message.put(ChatKeyUtil.MESSAGE, chatText); String meetingID = Red5.getConnectionLocal().getScope().getName(); String requesterID = getBbbSession().getInternalUserID(); red5BBBInGw.sendPrivateMessage(meetingID, requesterID, message); } }
public class RtpStreamReceiver { protected static Logger log = Red5LoggerFactory.getLogger(RtpStreamReceiver.class, "sip"); // Maximum blocking time, spent waiting for reading new bytes [milliseconds] // private static final int SO_TIMEOUT = 200; private static int RTP_HEADER_SIZE = 12; private RtpSocket rtpSocket = null; private final Executor exec = Executors.newSingleThreadExecutor(); private Runnable rtpPacketReceiver; private volatile boolean receivePackets = false; private RtpStreamReceiverListener listener; private final int payloadLength; private int lastSequenceNumber = 0; private long lastPacketTimestamp = 0; private boolean firstPacket = true; private boolean lastPacketDropped = false; private int successivePacketDroppedCount = 0; private long lastPacketReceived = 0; public RtpStreamReceiver(DatagramSocket socket, int expectedPayloadLength) { this.payloadLength = expectedPayloadLength; rtpSocket = new RtpSocket(socket); initializeSocket(); } public void setRtpStreamReceiverListener(RtpStreamReceiverListener listener) { this.listener = listener; } private void initializeSocket() { /* try { rtpSocket.getDatagramSocket().setSoTimeout(SO_TIMEOUT); } catch (SocketException e1) { log.warn("SocketException while setting socket block time."); } */ } public void start() { receivePackets = true; rtpPacketReceiver = new Runnable() { public void run() { receiveRtpPackets(); } }; exec.execute(rtpPacketReceiver); } public void stop() { receivePackets = false; } public void receiveRtpPackets() { int packetReceivedCounter = 0; int internalBufferLength = payloadLength + RTP_HEADER_SIZE; byte[] internalBuffer; RtpPacket rtpPacket; while (receivePackets) { try { internalBuffer = new byte[internalBufferLength]; rtpPacket = new RtpPacket(internalBuffer, internalBufferLength); rtpSocket.receive(rtpPacket); packetReceivedCounter++; // log.debug("Received packet [" + rtpPacket.getRtcpPayloadType() + "," + // rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] // seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber // + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + // "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); if (shouldDropDelayedPacket(rtpPacket)) { continue; } if (rtpPacket.isRtcpPacket()) { /** * Asterisk (1.6.2.5) send RTCP packets. We just ignore them (for now). It could be for * KeepAlive (http://tools.ietf.org/html/draft-ietf-avt-app-rtp-keepalive-09) */ if (log.isDebugEnabled()) log.debug( "RTCP packet [" + rtpPacket.getRtcpPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); } else { if (shouldHandlePacket(rtpPacket)) { // log.debug("Handling packet [" + rtpPacket.getRtcpPayloadType() + "," + // rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] // seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber // + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + // lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + // "]"); processRtpPacket(rtpPacket); } else { if (log.isDebugEnabled()) log.debug( "Corrupt packet [" + rtpPacket.getRtcpPayloadType() + "," + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); if (lastPacketDropped) successivePacketDroppedCount++; else lastPacketDropped = true; } } } catch ( IOException e) { // We get this when the socket closes when the call hangs up. receivePackets = false; } } log.debug("Rtp Receiver stopped. Packet Received = " + packetReceivedCounter + "."); if (listener != null) listener.onStoppedReceiving(); } private boolean shouldDropDelayedPacket(RtpPacket rtpPacket) { long now = System.currentTimeMillis(); if (now - lastPacketReceived > 100) { if (log.isDebugEnabled()) log.debug( "Delayed packet [" + rtpPacket.getRtcpPayloadType() + "," + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); lastPacketReceived = now; return true; } lastPacketReceived = now; return false; } private boolean isMarkerPacket(RtpPacket rtpPacket) { /* * FreeSWITCH sends a marker packet at the beginning of the voice frame. * If you stop talking and then start talking, a marker packet is received on start talking. (ralam sept 20, 2010). */ if (rtpPacket.hasMarker()) { if (log.isDebugEnabled()) log.debug( "Marked packet [" + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); return true; } return false; } private boolean shouldHandlePacket(RtpPacket rtpPacket) { /** * Take seq number only into account and not timestamps. Seems like the timestamp sometimes * change whenever the audio changes source. For example, in FreeSWITCH, the audio prompt will * have it's own "start" timestamp and then another "start" timestamp will be generated for the * voice. (ralam, sept 7, 2010). && packetIsNotCorrupt(rtpPacket)) { */ return isFirstPacket(rtpPacket) || isMarkerPacket(rtpPacket) || resetDueToSuccessiveDroppedPackets() || validSeqNum(rtpPacket) || seqNumRolledOver(rtpPacket); } private boolean resetDueToSuccessiveDroppedPackets() { /* * I notice that Asterisk (1.6.2.5) sets the rtp sequence number to 12 every time it sends a marked rtp packet. This screws up our * way of determining which packet to drop. To get around this, we detect if consecutive packets have been dropped then reset * the sequence number to handle the next incoming packets (ralam sept. 20, 2010). */ if (lastPacketDropped && successivePacketDroppedCount > 3) { if (log.isDebugEnabled()) log.debug( "Resetting after successive dropped packets [successivePacketDroppedCount=" + successivePacketDroppedCount + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); lastPacketDropped = false; successivePacketDroppedCount = 0; return true; } return false; } private boolean isFirstPacket(RtpPacket rtpPacket) { if (firstPacket) { lastPacketReceived = System.currentTimeMillis(); firstPacket = false; if (log.isDebugEnabled()) log.debug( "First packet [" + rtpPacket.getPayloadType() + ", length=" + rtpPacket.getPayloadLength() + "] seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); return true; } return false; } private boolean validSeqNum(RtpPacket rtpPacket) { /* * Assume if the sequence number jumps by more that 100, that the sequence number is corrupt. */ return (rtpPacket.getSeqNum() > lastSequenceNumber && rtpPacket.getSeqNum() - lastSequenceNumber < 100); } private boolean seqNumRolledOver(RtpPacket rtpPacket) { /* * Max sequence num is 65535 (16-bits). Let's use 65000 as check to take into account * delayed packets. */ if (lastSequenceNumber - rtpPacket.getSeqNum() > 65000) { if (log.isDebugEnabled()) log.debug( "Packet rolling over seqNum[rtpSeqNum=" + rtpPacket.getSeqNum() + ",lastSeqNum=" + lastSequenceNumber + "][rtpTS=" + rtpPacket.getTimestamp() + ",lastTS=" + lastPacketTimestamp + "][port=" + rtpSocket.getDatagramSocket().getLocalPort() + "]"); return true; } return false; } private void processRtpPacket(RtpPacket rtpPacket) { lastSequenceNumber = rtpPacket.getSeqNum(); lastPacketTimestamp = rtpPacket.getTimestamp(); AudioByteData audioData = new AudioByteData(rtpPacket.getPayload()); if (listener != null) listener.onAudioDataReceived(audioData); else log.debug("No listener for incoming audio packet"); } }
public class VideoDrawService { private static Logger log = Red5LoggerFactory.getLogger(VideoDrawService.class, "bigbluebutton"); private VideoDrawApplication application; public void setVideoDrawApplication(VideoDrawApplication a) { log.debug("Setting whiteboard application instance"); this.application = a; } public void sendAnnotation(Map<String, Object> annotation) { // for (Map.Entry<String, Object> entry : annotation.entrySet()) { // String key = entry.getKey(); // Object value = entry.getValue(); // if (key.equals("points")) { // String points = "points=["; // ArrayList<Double> v = (ArrayList<Double>) value; // log.debug(points + pointsToString(v) + "]"); // } else { // log.debug(key + "=[" + value + "]"); // } // } Annotation a = new Annotation(annotation); application.sendAnnotation(a); } private String pointsToString(ArrayList<Double> points) { String datapoints = ""; for (Double i : points) { datapoints += i + ","; } // Trim the trailing comma // log.debug("Data Point = " + datapoints); return datapoints.substring(0, datapoints.length() - 1); // application.sendShape(shape, type, color, thickness, fill, fillColor, transparency, id, // status); } public void setActivePage(Map<String, Object> message) { log.info( "VideoDrawApplication - Getting number of shapes for page: " + (Integer) message.get("pageNum")); application.changePage((Integer) message.get("pageNum")); } public void requestAnnotationHistory(Map<String, Object> message) { log.info("VideoDrawApplication - requestAnnotationHistory"); application.sendAnnotationHistory( getBbbSession().getInternalUserID(), (String) message.get("presentationID"), (Integer) message.get("pageNumber")); } public void clear(Map<String, Object> annotation) { log.info("VideoDrawApplication - Clearing board"); Annotation a = new Annotation(annotation); application.clear(a); } public void undo(Map<String, Object> annotation) { log.info("VideoDrawApplication - Deleting last graphic"); Annotation a = new Annotation(annotation); application.undo(a); } public void toggleGrid() { log.info("VideoDrawApplication - Toggling grid mode"); application.toggleGrid(); } public void setActivePresentation(Map<String, Object> message) { log.info( "VideoDrawApplication - Setting active presentation: " + (String) message.get("presentationID")); application.setActivePresentation( (String) message.get("presentationID"), (Integer) message.get("numberOfSlides")); } public void enableWhiteboard(Map<String, Object> message) { log.info( "VideoDrawApplication - Setting whiteboard enabled: " + (Boolean) message.get("enabled")); application.enableWhiteboard((Boolean) message.get("enabled")); } public void isWhiteboardEnabled() { application.isWhiteboardEnabled(getBbbSession().getInternalUserID()); } private BigBlueButtonSession getBbbSession() { return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); } }
public class ChatHandler implements IApplication { private static Logger log = Red5LoggerFactory.getLogger(ChatHandler.class, "bigbluebutton"); private RecorderApplication recorderApplication; private ChatApplication chatApplication; private static final String APP = "CHAT"; @Override public boolean appConnect(IConnection conn, Object[] params) { log.debug("***** " + APP + " [ " + " appConnect *********"); return true; } @Override public void appDisconnect(IConnection conn) { log.debug("***** " + APP + " [ " + " appDisconnect *********"); } @Override public boolean appJoin(IClient client, IScope scope) { log.debug("***** " + APP + " [ " + " appJoin [ " + scope.getName() + "] *********"); return true; } @Override public void appLeave(IClient client, IScope scope) { log.debug("***** " + APP + " [ " + " appLeave [ " + scope.getName() + "] *********"); } @Override public boolean appStart(IScope scope) { log.debug("***** " + APP + " [ " + " appStart [ " + scope.getName() + "] *********"); return true; } @Override public void appStop(IScope scope) { log.debug("***** " + APP + " [ " + " appStop [ " + scope.getName() + "] *********"); } @Override public void roomDisconnect(IConnection connection) { log.debug( "***** " + APP + " [ " + " roomDisconnect [ " + connection.getScope().getName() + "] *********"); } @Override public boolean roomJoin(IClient client, IScope scope) { log.debug("***** " + APP + " [ " + " roomJoin [ " + scope.getName() + "] *********"); return true; } @Override public void roomLeave(IClient client, IScope scope) { log.debug("***** " + APP + " [ " + " roomLeave [ " + scope.getName() + "] *********"); } @Override public boolean roomConnect(IConnection connection, Object[] params) { log.debug( "***** " + APP + " [ " + " roomConnect [ " + connection.getScope().getName() + "] *********"); return true; } @Override public boolean roomStart(IScope scope) { log.debug("***** " + APP + " [ " + " roomStart [ " + scope.getName() + "] *********"); return true; } @Override public void roomStop(IScope scope) { log.debug("***** " + APP + " [ " + " roomStop [ " + scope.getName() + "] *********"); } public void setChatApplication(ChatApplication a) { log.debug("Setting chat application"); chatApplication = a; } public void setRecorderApplication(RecorderApplication a) { log.debug("Setting archive application"); recorderApplication = a; } }
public class FlvInterviewConverter extends BaseConverter { private static final Logger log = Red5LoggerFactory.getLogger(FlvInterviewConverter.class, webAppRootKey); private class ReConverterParams { private int leftSideLoud = 1; private int rightSideLoud = 1; private Integer leftSideTime = 0; private Integer rightSideTime = 0; } // Spring loaded Beans @Autowired private FlvRecordingDao recordingDao; @Autowired private FlvRecordingMetaDataDao metaDataDao; @Autowired private FlvRecordingLogDao logDao; @Autowired private GenerateThumbs generateThumbs; public void startReConversion( Long flvRecordingId, Integer leftSideLoud, Integer rightSideLoud, Integer leftSideTime, Integer rightSideTime) { log.debug("++++++++++++ leftSideLoud :: " + leftSideLoud); log.debug("++++++++++++ rightSideLoud :: " + rightSideLoud); ReConverterParams rcv = new ReConverterParams(); rcv.leftSideLoud += leftSideLoud; rcv.rightSideLoud += rightSideLoud; rcv.leftSideTime = leftSideTime; rcv.rightSideTime = rightSideTime; log.debug("++++++++++++ this.leftSideLoud :: " + rcv.leftSideLoud); log.debug("++++++++++++ this.rightSideLoud :: " + rcv.rightSideLoud); log.debug("++++++++++++ this.leftSideTime :: " + rcv.leftSideTime); log.debug("++++++++++++ this.rightSideTime :: " + rcv.rightSideTime); startConversion(flvRecordingId, true, rcv); } private String[] mergeAudioToWaves( List<String> listOfFullWaveFiles, String outputFullWav, List<FlvRecordingMetaData> metaDataList, ReConverterParams rcv) { String[] argv_full_sox = new String[listOfFullWaveFiles.size() + 5]; argv_full_sox[0] = this.getPathToSoX(); argv_full_sox[1] = "-m"; int counter = 2; for (int i = 0; i < listOfFullWaveFiles.size(); i++) { for (FlvRecordingMetaData flvRecordingMetaData : metaDataList) { String hashFileFullNameStored = flvRecordingMetaData.getFullWavAudioData(); String fullFilePath = listOfFullWaveFiles.get(i); String fileNameOnly = new File(fullFilePath).getName(); if (hashFileFullNameStored.equals(fileNameOnly)) { if (flvRecordingMetaData.getInteriewPodId() == 1) { argv_full_sox[counter] = "-v " + rcv.leftSideLoud; counter++; } if (flvRecordingMetaData.getInteriewPodId() == 2) { argv_full_sox[counter] = "-v " + rcv.rightSideLoud; counter++; } } } argv_full_sox[counter] = listOfFullWaveFiles.get(i); counter++; } argv_full_sox[counter] = outputFullWav; return argv_full_sox; } public void startConversion(Long flvRecordingId) { startConversion(flvRecordingId, false, new ReConverterParams()); } public void startConversion(Long flvRecordingId, boolean reconversion, ReConverterParams rcv) { FlvRecording flvRecording = null; try { flvRecording = recordingDao.get(flvRecordingId); log.debug("flvRecording " + flvRecording.getFlvRecordingId()); List<ConverterProcessResult> returnLog = new ArrayList<ConverterProcessResult>(); List<String> listOfFullWaveFiles = new LinkedList<String>(); File streamFolder = getStreamFolder(flvRecording); List<FlvRecordingMetaData> metaDataList = metaDataDao.getAudioMetaDataByRecording(flvRecording.getFlvRecordingId()); stripAudioFirstPass(flvRecording, returnLog, listOfFullWaveFiles, streamFolder, metaDataList); // Merge Wave to Full Length File streamFolderGeneral = getStreamsHibernateDir(); String hashFileFullName = "INTERVIEW_" + flvRecording.getFlvRecordingId() + "_FINAL_WAVE.wav"; String outputFullWav = streamFolder.getAbsolutePath() + File.separatorChar + hashFileFullName; deleteFileIfExists(outputFullWav); if (listOfFullWaveFiles.size() == 1) { outputFullWav = listOfFullWaveFiles.get(0); } else if (listOfFullWaveFiles.size() > 0) { String[] argv_full_sox; if (reconversion) { argv_full_sox = mergeAudioToWaves(listOfFullWaveFiles, outputFullWav, metaDataList, rcv); } else { argv_full_sox = mergeAudioToWaves(listOfFullWaveFiles, outputFullWav); } returnLog.add(ProcessHelper.executeScript("mergeAudioToWaves", argv_full_sox)); } else { // create default Audio to merge it. // strip to content length File outputWav = new File(streamFolderGeneral, "one_second.wav"); // Calculate delta at beginning Long deltaTimeMilliSeconds = flvRecording.getRecordEnd().getTime() - flvRecording.getRecordStart().getTime(); Float deltaPadding = (Float.parseFloat(deltaTimeMilliSeconds.toString()) / 1000) - 1; String[] argv_full_sox = new String[] { getPathToSoX(), outputWav.getCanonicalPath(), outputFullWav, "pad", "0", deltaPadding.toString() }; returnLog.add(ProcessHelper.executeScript("generateSampleAudio", argv_full_sox)); } // Default Image for empty interview video pods final File defaultInterviewImageFile = new File(streamFolderGeneral, "default_interview_image.png"); if (!defaultInterviewImageFile.exists()) { throw new Exception("defaultInterviewImageFile does not exist!"); } final int flvWidth = 320; final int flvHeight = 260; final int frameRate = 25; // Merge Audio with Video / Calculate resulting FLV String[] pods = new String[2]; boolean found = false; for (FlvRecordingMetaData meta : metaDataList) { File flv = new File(streamFolder, meta.getStreamName() + ".flv"); Integer pod = meta.getInteriewPodId(); if (flv.exists() && pod != null && pod > 0 && pod < 3) { String path = flv.getCanonicalPath(); /* * CHECK FILE: * ffmpeg -i rec_316_stream_567_2013_08_28_11_51_45.flv -v error -f null file.null */ String[] args = new String[] { getPathToFFMPEG(), "-i", path, "-an" // only input files with video will be treated as video sources , "-v", "error", "-f", "null", "file.null" }; ConverterProcessResult r = ProcessHelper.executeScript("checkFlvPod_" + pod, args); returnLog.add(r); if ("".equals(r.getError())) { pods[pod - 1] = path; } found = true; } } if (!found) { ConverterProcessResult r = new ConverterProcessResult(); r.setProcess("CheckFlvFilesExists"); r.setError("No valid pods found"); returnLog.add(r); return; } boolean shortest = false; List<String> args = new ArrayList<String>(); args.add(getPathToFFMPEG()); for (int i = 0; i < 2; ++i) { /* * INSERT BLANK INSTEAD OF BAD PAD: * ffmpeg -loop 1 -i default_interview_image.jpg -i rec_316_stream_569_2013_08_28_11_51_45.flv -filter_complex '[0:v]scale=320:260,pad=2*320:260[left];[1:v]scale=320:260[right];[left][right]overlay=main_w/2:0' -shortest -y out4.flv * * JUST MERGE: * ffmpeg -i rec_316_stream_569_2013_08_28_11_51_45.flv -i rec_316_stream_569_2013_08_28_11_51_45.flv -filter_complex '[0:v]scale=320:260,pad=2*320:260[left];[1:v]scale=320:260[right];[left][right]overlay=main_w/2:0' -y out4.flv */ if (pods[i] == null) { shortest = true; args.add("-loop"); args.add("1"); args.add("-i"); args.add(defaultInterviewImageFile.getCanonicalPath()); } else { args.add("-i"); args.add(pods[i]); } } args.add("-i"); args.add(outputFullWav); args.add("-ar"); args.add("22050"); args.add("-ab"); args.add("32k"); args.add("-filter_complex"); args.add( String.format( "[0:v]scale=%1$d:%2$d,pad=2*%1$d:%2$d[left];[1:v]scale=%1$d:%2$d[right];[left][right]overlay=main_w/2:0%3$s", flvWidth, flvHeight, shortest ? ":shortest=1" : "")); if (shortest) { args.add("-shortest"); } args.add("-map"); args.add("0:0"); args.add("-map"); args.add("1:0"); args.add("-map"); args.add("2:0"); args.add("-r"); args.add("" + frameRate); args.add("-qmax"); args.add("1"); args.add("-qmin"); args.add("1"); args.add("-y"); String hashFileFullNameFlv = "flvRecording_" + flvRecording.getFlvRecordingId() + ".flv"; String outputFullFlv = new File(streamFolderGeneral, hashFileFullNameFlv).getCanonicalPath(); args.add(outputFullFlv); // TODO additional flag to 'quiet' output should be added returnLog.add( ProcessHelper.executeScript("generateFullBySequenceFLV", args.toArray(new String[] {}))); flvRecording.setFlvWidth(2 * flvWidth); flvRecording.setFlvHeight(flvHeight); flvRecording.setFileHash(hashFileFullNameFlv); // Extract first Image for preview purpose // ffmpeg -i movie.flv -vcodec mjpeg -vframes 1 -an -f rawvideo -s // 320x240 movie.jpg String hashFileFullNameJPEG = "flvRecording_" + flvRecording.getFlvRecordingId() + ".jpg"; String outPutJpeg = new File(streamFolderGeneral, hashFileFullNameJPEG).getCanonicalPath(); deleteFileIfExists(outPutJpeg); flvRecording.setPreviewImage(hashFileFullNameJPEG); String[] argv_previewFLV = new String[] { // getPathToFFMPEG(), // "-i", outputFullFlv, // "-vcodec", "mjpeg", // "-vframes", "100", "-an", // "-f", "rawvideo", // "-s", (2 * flvWidth) + "x" + flvHeight, // outPutJpeg }; returnLog.add(ProcessHelper.executeScript("generateFullFLV", argv_previewFLV)); String alternateDownloadName = "flvRecording_" + flvRecording.getFlvRecordingId() + ".avi"; String alternateDownloadFullName = new File(streamFolderGeneral, alternateDownloadName).getCanonicalPath(); deleteFileIfExists(alternateDownloadFullName); String[] argv_alternateDownload = new String[] {getPathToFFMPEG(), "-i", outputFullFlv, alternateDownloadFullName}; returnLog.add(ProcessHelper.executeScript("alternateDownload", argv_alternateDownload)); flvRecording.setAlternateDownload(alternateDownloadName); updateDuration(flvRecording); convertToMp4(flvRecording, returnLog); flvRecording.setStatus(FlvRecording.Status.PROCESSED); logDao.deleteByRecordingId(flvRecording.getFlvRecordingId()); for (ConverterProcessResult returnMap : returnLog) { logDao.addFLVRecordingLog("generateFFMPEG", flvRecording, returnMap); } // Delete Wave Files for (String fileName : listOfFullWaveFiles) { File audio = new File(fileName); if (audio.exists()) { audio.delete(); } } } catch (Exception err) { log.error("[startConversion]", err); flvRecording.setStatus(FlvRecording.Status.ERROR); } recordingDao.update(flvRecording); } public ConverterProcessResult processImageWindows(String file1, String file2, String file3) { return ProcessHelper.executeScriptWindows( "processImageWindows", new String[] {getPathToImageMagick(), file1, file2, "+append", file3}); } }
public class BigBlueButtonApplication extends MultiThreadedApplicationAdapter { private static Logger log = Red5LoggerFactory.getLogger(BigBlueButtonApplication.class, "bigbluebutton"); private ParticipantsApplication participantsApplication; private RecorderApplication recorderApplication; private AbstractApplicationContext appCtx; private String version; @Override public boolean appStart(IScope app) { log.debug("Starting BigBlueButton version " + version); IContext context = app.getContext(); appCtx = (AbstractApplicationContext) context.getApplicationContext(); appCtx.addApplicationListener(new ShutdownHookListener()); appCtx.registerShutdownHook(); return super.appStart(app); } @Override public void appStop(IScope app) { log.debug("Stopping BigBlueButton version " + version); super.appStop(app); } @Override public boolean roomStart(IScope room) { log.debug("Starting room [" + room.getName() + "]."); assert participantsApplication != null; return super.roomStart(room); } @Override public void roomStop(IScope room) { log.debug("Stopping room [" + room.getName() + "]."); super.roomStop(room); assert participantsApplication != null; participantsApplication.destroyRoom(room.getName()); BigBlueButtonSession bbbSession = getBbbSession(); assert bbbSession != null; /** Need to figure out if the next 2 lines should be removed. (ralam nov 25, 2010). */ assert recorderApplication != null; recorderApplication.destroyRecordSession(bbbSession.getSessionName()); log.debug("Stopped room [" + room.getName() + "]."); } @Override public boolean roomConnect(IConnection connection, Object[] params) { String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); String clientId = Red5.getConnectionLocal().getClient().getId(); log.info("[clientid=" + clientId + "] connected from " + remoteHost + ":" + remotePort + "."); String username = ((String) params[0]).toString(); String role = ((String) params[1]).toString(); String conference = ((String) params[2]).toString(); /* * Convert the id to Long because it gets converted to ascii decimal * equivalent (i.e. zero (0) becomes 48) if we don't. */ long userid = Long.parseLong(Red5.getConnectionLocal().getClient().getId()); String sessionName = connection.getScope().getName(); String voiceBridge = ((String) params[4]).toString(); String room = sessionName; assert recorderApplication != null; boolean record = (Boolean) params[5]; log.debug("record value - [" + record + "]"); String externUserID = ((String) params[6]).toString(); if (record == true) { recorderApplication.createRecordSession(sessionName); } BigBlueButtonSession bbbSession = new BigBlueButtonSession( sessionName, userid, username, role, conference, room, voiceBridge, record, externUserID); connection.setAttribute(Constants.SESSION, bbbSession); String debugInfo = "userid=" + userid + ",username="******",role=" + role + ",conference=" + conference + "," + "session=" + sessionName + ",voiceConf=" + voiceBridge + ",room=" + room + ",externsUserid=" + externUserID; log.debug("User [{}] connected to room [{}]", debugInfo, room); participantsApplication.createRoom(room); super.roomConnect(connection, params); return true; } @Override public void roomDisconnect(IConnection conn) { String remoteHost = Red5.getConnectionLocal().getRemoteAddress(); int remotePort = Red5.getConnectionLocal().getRemotePort(); String clientId = Red5.getConnectionLocal().getClient().getId(); log.info( "[clientid=" + clientId + "] disconnnected from " + remoteHost + ":" + remotePort + "."); BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); log.info( "User [" + bbbSession.getUsername() + "] disconnected from room [" + bbbSession.getRoom() + "]"); super.roomDisconnect(conn); } public String getMyUserId() { BigBlueButtonSession bbbSession = (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); assert bbbSession != null; return Long.toString(bbbSession.getUserid()); } public void setParticipantsApplication(ParticipantsApplication a) { participantsApplication = a; } public void setRecorderApplication(RecorderApplication a) { recorderApplication = a; } public void setApplicationListeners(Set<IApplication> listeners) { int count = 0; Iterator<IApplication> iter = listeners.iterator(); while (iter.hasNext()) { super.addListener((IApplication) iter.next()); count++; } } public void setVersion(String v) { version = v; } private BigBlueButtonSession getBbbSession() { return (BigBlueButtonSession) Red5.getConnectionLocal().getAttribute(Constants.SESSION); } private class ShutdownHookListener implements ApplicationListener<ApplicationEvent> { @Override public void onApplicationEvent(ApplicationEvent event) { if (event instanceof org.springframework.context.event.ContextStoppedEvent) { log.info("Received shutdown event. Red5 is shutting down. Destroying all rooms."); participantsApplication.destroyAllRooms(); } } } }
/** * Insert/update/Delete on {@link Configuration}<br> * <br> * It provides basic mechanism to get a Conf Key:<br> * {@link #getConfValue(String, Class, String)} <br> * <br> * <b> {@link #get(String)} is deprecated!</b> * * @author swagner */ @Transactional public class ConfigurationDao implements IDataProviderDao<Configuration> { private static final Logger log = Red5LoggerFactory.getLogger(ConfigurationDao.class, webAppRootKey); public static final long DEFAULT_MAX_UPLOAD_SIZE = 1024 * 1024 * 1024; // 1GB public static final String DEFAULT_APP_NAME = "OpenMeetings"; public static final String[] searchFields = {"conf_key", "conf_value"}; @PersistenceContext private EntityManager em; @Resource(name = "adminUserDao") private AdminUserDao adminUserDao; /** * @deprecated Dao's are not the place to store session variables, also updates to the key won't * update this variable */ @Deprecated private String appName = null; /** * Retrieves Configuration regardless of its deleted status * * @param confKey * @return */ public Configuration forceGet(String confKey) { try { List<Configuration> list = em.createNamedQuery("forceGetConfigurationByKey", Configuration.class) .setParameter("conf_key", confKey) .getResultList(); return list.isEmpty() ? null : list.get(0); } catch (Exception e) { log.error("[forceGet]: ", e); } return null; } public List<Configuration> get(String... keys) { List<Configuration> result = new ArrayList<Configuration>(); for (String key : keys) { // iteration is necessary to fill list with all values List<Configuration> r = em.createNamedQuery("getConfigurationsByKeys", Configuration.class) .setParameter("conf_keys", Arrays.asList(key)) .getResultList(); result.add(r.isEmpty() ? null : r.get(0)); } return result; } /** * Return a object using a custom type and a default value if the key is not present, or value is * not set * * <p>Example: Integer my_key = getConfValue("my_key", Integer.class, "15"); * * @param key * @param type * @param defaultValue * @return */ public <T> T getConfValue(String key, Class<T> type, String defaultValue) { try { List<Configuration> list = get(key); if (list == null || list.isEmpty() || list.get(0) == null) { log.warn("Could not find key in configuration CONF_KEY: " + key); } else { String val = list.get(0).getConf_value(); // Use the custom value as default value if (val != null) { defaultValue = val; } } if (defaultValue == null) { return null; } // Either this can be directly assigned or try to find a constructor // that handles it if (type.isAssignableFrom(defaultValue.getClass())) { return type.cast(defaultValue); } Constructor<T> c = type.getConstructor(defaultValue.getClass()); return c.newInstance(defaultValue); } catch (Exception err) { log.error( "cannot be cast to return type, you have misconfigured your configuration CONF_KEY: " + key, err); return null; } } public List<Configuration> getConfigurations(int start, int max, String orderby, boolean asc) { try { String query = "SELECT c FROM Configuration c " // + "LEFT JOIN FETCH c.user " // + "WHERE c.deleted = false " // + "ORDER BY " + orderby; if (asc) { query += " ASC"; } else { query += " DESC"; } TypedQuery<Configuration> q = em.createQuery(query, Configuration.class); q.setFirstResult(start); q.setMaxResults(max); return q.getResultList(); } catch (Exception ex2) { log.error("[getConfigurations]", ex2); } return null; } /** */ public Configuration add(String key, String value, Long userId, String comment) { Configuration c = new Configuration(); c.setConf_key(key); c.setConf_value(value); c.setComment(comment); return update(c, userId); } /** @deprecated please use {@link ConfigurationDao#update(Configuration, Long)} */ public Long addConfig(Configuration conf) { try { conf = em.merge(conf); Long configuration_id = conf.getConfiguration_id(); return configuration_id; } catch (Exception ex2) { log.error("[updateConfByUID]: ", ex2); } return new Long(-1); } /** * @deprecated please use {@link ConfigurationDao#update(Configuration, Long)} * @param conf * @return */ public Long updateConfig(Configuration conf) { try { if (conf.getConfiguration_id() == null || conf.getConfiguration_id() == 0 || conf.getConfiguration_id() == 0L) { em.persist(conf); } else { if (!em.contains(conf)) { conf = em.merge(conf); } } if (CONFIG_CRYPT_KEY.equals(conf.getConf_key())) { configKeyCryptClassName = conf.getConf_value(); } else if ("show.whiteboard.draw.status".equals(conf.getConf_key())) { whiteboardDrawStatus = "1".equals(conf.getConf_value()); } return conf.getConfiguration_id(); } catch (Exception ex2) { log.error("[updateConfByUID]: ", ex2); } return new Long(-1); } public String getAppName() { if (appName == null) { appName = getConfValue("application.name", String.class, ConfigurationDao.DEFAULT_APP_NAME); } return appName; } public Configuration get(long id) { if (id <= 0) { return null; } return em.createNamedQuery("getConfigurationById", Configuration.class) .setParameter("configuration_id", id) .getSingleResult(); } public List<Configuration> get(int start, int count) { return em.createNamedQuery("getNondeletedConfiguration", Configuration.class) .setFirstResult(start) .setMaxResults(count) .getResultList(); } public List<Configuration> get(String search, int start, int count, String sort) { TypedQuery<Configuration> q = em.createQuery( DaoHelper.getSearchQuery("Configuration", "c", search, true, false, sort, searchFields), Configuration.class); q.setFirstResult(start); q.setMaxResults(count); return q.getResultList(); } public long count() { return em.createNamedQuery("countConfigurations", Long.class).getSingleResult(); } public long count(String search) { TypedQuery<Long> q = em.createQuery( DaoHelper.getSearchQuery("Configuration", "c", search, true, true, null, searchFields), Long.class); return q.getSingleResult(); } public Configuration update(Configuration entity, Long userId) { return update(entity, userId, false); } public Configuration update(Configuration entity, Long userId, boolean deleted) { String key = entity.getConf_key(); String value = entity.getConf_value(); if (entity.getConfiguration_id() == null || entity.getConfiguration_id() <= 0) { entity.setStarttime(new Date()); entity.setDeleted(deleted); em.persist(entity); } else { if (userId != null) { entity.setUser(adminUserDao.get(userId)); } entity.setDeleted(deleted); entity.setUpdatetime(new Date()); entity = em.merge(entity); } if (CONFIG_CRYPT_KEY.equals(key)) { configKeyCryptClassName = value; } else if ("show.whiteboard.draw.status".equals(key)) { whiteboardDrawStatus = "1".equals(value); } else if ("application.name".equals(key)) { appName = value; } // TODO ensure entity returned is updated return entity; } public void delete(Configuration entity, Long userId) { entity.setUpdatetime(new Date()); this.update(entity, userId, true); } /** * returns the max upload size configured by max_upload_size config key * * @param configurationDao * @return */ public final long getMaxUploadSize() { try { return getConfValue(CONFIG_MAX_UPLOAD_SIZE_KEY, Long.class, "" + DEFAULT_MAX_UPLOAD_SIZE); } catch (Exception e) { log.error("Invalid value saved for max_upload_size conf key: ", e); } return DEFAULT_MAX_UPLOAD_SIZE; } public String getCryptKey() { if (configKeyCryptClassName == null) { String cryptClass = getConfValue(CONFIG_CRYPT_KEY, String.class, null); if (cryptClass != null) { configKeyCryptClassName = cryptClass; } } return configKeyCryptClassName; } public boolean getWhiteboardDrawStatus() { if (whiteboardDrawStatus == null) { String drawStatus = getConfValue("show.whiteboard.draw.status", String.class, "0"); whiteboardDrawStatus = "1".equals(drawStatus); } return whiteboardDrawStatus; } }
/** This encapsulates access to ChatRoom and messages. This class must be threadsafe. */ @ThreadSafe public class ChatRoomsManager { private static Logger log = Red5LoggerFactory.getLogger(ChatRoomsManager.class, "bigbluebutton"); private final Map<String, ChatRoom> rooms; public ChatRoomsManager() { log.debug("In ChatRoomsManager constructor"); rooms = new ConcurrentHashMap<String, ChatRoom>(); } public void addRoom(ChatRoom room) { log.debug("In ChatRoomsManager adding room " + room.getName()); rooms.put(room.getName(), room); } public void removeRoom(String name) { log.debug("In ChatRoomsManager remove room " + name); rooms.remove(name); } public boolean hasRoom(String name) { log.debug("In ChatRoomsManager has Room " + name); return rooms.containsKey(name); } /** Keeping getRoom private so that all access to ChatRoom goes through here. */ private ChatRoom getRoom(String name) { log.debug("In ChatRoomsManager get room " + name); return rooms.get(name); } public List<ChatMessageVO> getChatMessages(String room) { ChatRoom r = getRoom(room); if (r != null) { return r.getChatMessages(); } log.warn("Getting messages from a non-existing room " + room); return null; } public void sendMessage(String room, ChatMessageVO chatobj) { ChatRoom r = getRoom(room); if (r != null) { r.sendMessage(chatobj); } else { log.warn("Sending message to a non-existing room " + room); } } public void addRoomListener(String roomName, IChatRoomListener listener) { ChatRoom r = getRoom(roomName); if (r != null) { r.addRoomListener(listener); return; } log.warn("Adding listener to a non-existing room " + roomName); } // TODO: roomName? // public void removeRoomListener(IChatRoomListener listener) { // ChatRoom r = getRoom(roomName); // if (r != null) { // r.removeRoomListener(listener); // return; // } // log.warn("Removing listener from a non-existing room ${roomName}"); // } }
/** * Servlet to tunnel to the AMF gateway servlet. * * @author The Red5 Project * @author Paul Gregoire ([email protected]) */ public class AMFTunnelServlet extends HttpServlet { private static final long serialVersionUID = -35436145164322090L; protected Logger log = Red5LoggerFactory.getLogger(AMFTunnelServlet.class); private static final String REQUEST_TYPE = "application/x-amf"; private static String postAcceptorURL = "http://localhost:8080/gateway"; private static int connectionTimeout = 30000; @Override public void init(ServletConfig config) throws ServletException { super.init(config); // get the url for posting if (config.getInitParameter("tunnel.acceptor.url") != null) { postAcceptorURL = config.getInitParameter("tunnel.acceptor.url"); } log.debug("POST acceptor URL: {}", postAcceptorURL); // get the connection timeout if (config.getInitParameter("tunnel.timeout") != null) { connectionTimeout = Integer.valueOf(config.getInitParameter("tunnel.timeout")); } log.debug("POST connection timeout: {}", postAcceptorURL); } /** Redirect to HTTP port. */ @Override protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { HttpClient client = HttpConnectionUtil.getClient(connectionTimeout); // setup POST HttpPost post = null; try { post = new HttpPost(postAcceptorURL); String path = req.getContextPath(); if (path == null) { path = ""; } log.debug("Path: {}", path); if (req.getPathInfo() != null) { path += req.getPathInfo(); } log.debug("Path 2: {}", path); int reqContentLength = req.getContentLength(); if (reqContentLength > 0) { log.debug("Request content length: {}", reqContentLength); IoBuffer reqBuffer = IoBuffer.allocate(reqContentLength); ServletUtils.copy(req, reqBuffer.asOutputStream()); reqBuffer.flip(); post.setEntity(new InputStreamEntity(reqBuffer.asInputStream(), reqContentLength)); post.addHeader("Content-Type", REQUEST_TYPE); // get.setPath(path); post.addHeader("Tunnel-request", path); // execute the method HttpResponse response = client.execute(post); int code = response.getStatusLine().getStatusCode(); log.debug("HTTP response code: {}", code); if (code == HttpStatus.SC_OK) { HttpEntity entity = response.getEntity(); if (entity != null) { resp.setContentType(REQUEST_TYPE); // get the response as bytes byte[] bytes = EntityUtils.toByteArray(entity); IoBuffer resultBuffer = IoBuffer.wrap(bytes); resultBuffer.flip(); ServletUtils.copy(resultBuffer.asInputStream(), resp.getOutputStream()); resp.flushBuffer(); } } else { resp.sendError(code); } } else { resp.sendError(HttpStatus.SC_BAD_REQUEST); } } catch (Exception ex) { log.error("", ex); if (post != null) { post.abort(); } } } }
public class LayoutHandler extends ApplicationAdapter implements IApplication { private static Logger log = Red5LoggerFactory.getLogger(LayoutHandler.class, "bigbluebutton"); private static final String APP = "LAYOUT"; private static final String LAYOUT_SO = "layoutSO"; private LayoutApplication layoutApplication; @Override public boolean appConnect(IConnection conn, Object[] params) { log.debug(APP + ":appConnect"); return true; } @Override public void appDisconnect(IConnection conn) { log.debug(APP + ":appDisconnect"); } @Override public boolean appJoin(IClient client, IScope scope) { log.debug(APP + ":appJoin " + scope.getName()); return true; } @Override public void appLeave(IClient client, IScope scope) { log.debug(APP + ":appLeave " + scope.getName()); } @Override public boolean appStart(IScope scope) { log.debug(APP + ":appStart " + scope.getName()); return true; } @Override public void appStop(IScope scope) { log.debug(APP + ":appStop " + scope.getName()); } @Override public boolean roomConnect(IConnection connection, Object[] params) { log.debug(APP + ":roomConnect"); ISharedObject so = getSharedObject(connection.getScope(), LAYOUT_SO); log.debug("Setting up Listener"); LayoutSender sender = new LayoutSender(so); String room = connection.getScope().getName(); log.debug("Adding event listener to " + room); log.debug("Adding room listener"); layoutApplication.addRoomListener(room, sender); log.debug("Done setting up listener"); return true; } @Override public void roomDisconnect(IConnection connection) { log.debug(APP + ":roomDisconnect"); } @Override public boolean roomJoin(IClient client, IScope scope) { log.debug(APP + ":roomJoin " + scope.getName() + " - " + scope.getParent().getName()); return true; } @Override public void roomLeave(IClient client, IScope scope) { log.debug(APP + ":roomLeave " + scope.getName()); } @Override public boolean roomStart(IScope scope) { log.debug(APP + ":roomStart " + scope.getName()); layoutApplication.createRoom(scope.getName()); if (!hasSharedObject(scope, LAYOUT_SO)) { if (createSharedObject(scope, LAYOUT_SO, false)) { return true; } } log.error("Failed to start room " + scope.getName()); return false; } @Override public void roomStop(IScope scope) { log.debug(APP + ":roomStop " + scope.getName()); layoutApplication.destroyRoom(scope.getName()); if (!hasSharedObject(scope, LAYOUT_SO)) { clearSharedObjects(scope, LAYOUT_SO); } } public void setLayoutApplication(LayoutApplication a) { log.debug("Setting layout application"); layoutApplication = a; layoutApplication.handler = this; } }
public class GeneratePDF { private static final Logger log = Red5LoggerFactory.getLogger(GeneratePDF.class, OpenmeetingsVariables.webAppRootKey); @Autowired private GenerateThumbs generateThumbs; @Autowired private GenerateSWF generateSWF; @Autowired private ConfigurationDao configurationDao; public ConverterProcessResultList convertPDF( String fileName, String roomName, boolean fullProcessing, File inFile) throws Exception { String inFileName = inFile.getName(); ConverterProcessResultList returnError = new ConverterProcessResultList(); File fileFullPath = new File(OmFileHelper.getUploadTempRoomDir(roomName), inFileName); File destinationFolder = OmFileHelper.getNewDir(OmFileHelper.getUploadRoomDir(roomName), fileName); log.debug("fullProcessing: " + fullProcessing); if (fullProcessing) { ConverterProcessResult processOpenOffice = doJodConvert(fileFullPath, destinationFolder, fileName); returnError.addItem("processOpenOffice", processOpenOffice); ConverterProcessResult processThumb = generateThumbs.generateBatchThumb( new File(destinationFolder, fileName + ".pdf"), destinationFolder, 80, "thumb"); returnError.addItem("processThumb", processThumb); ConverterProcessResult processSWF = generateSWF.generateSwf(destinationFolder, destinationFolder, fileName); returnError.addItem("processSWF", processSWF); } else { log.debug("-- generateBatchThumb --"); ConverterProcessResult processThumb = generateThumbs.generateBatchThumb(fileFullPath, destinationFolder, 80, "thumb"); returnError.addItem("processThumb", processThumb); ConverterProcessResult processSWF = generateSWF.generateSwf(fileFullPath.getParentFile(), destinationFolder, fileName); returnError.addItem("processSWF", processSWF); } // now it should be completed so copy that file to the expected location File fileWhereToMove = new File(destinationFolder, inFileName); fileWhereToMove.createNewFile(); FileHelper.moveRec(inFile, fileWhereToMove); if (fullProcessing) { ConverterProcessResult processXML = CreateLibraryPresentation.generateXMLDocument( destinationFolder, inFileName, fileName + ".pdf", fileName + ".swf"); returnError.addItem("processXML", processXML); } else { ConverterProcessResult processXML = CreateLibraryPresentation.generateXMLDocument( destinationFolder, inFileName, null, fileName + ".swf"); returnError.addItem("processXML", processXML); } return returnError; } /** Generates PDF using JOD Library (external library) */ public ConverterProcessResult doJodConvert( File fileFullPath, File destinationFolder, String outputfile) { try { String jodPath = configurationDao.getConfValue("jod.path", String.class, "./jod"); String officePath = configurationDao.getConfValue("office.path", String.class, ""); File jodFolder = new File(jodPath); if (!jodFolder.exists() || !jodFolder.isDirectory()) { throw new Exception("Path to JOD Library folder does not exist"); } ArrayList<String> argv = new ArrayList<String>(); argv.add("java"); if (officePath.trim().length() > 0) { argv.add("-Doffice.home=" + officePath); } String jodConverterJar = ""; for (String jar : jodFolder.list( new FilenameFilter() { public boolean accept(File file1, String name) { return name.endsWith(".jar"); } })) { argv.add("-cp"); if (jar.startsWith("jodconverter")) { jodConverterJar = jar; } argv.add(new File(jodFolder, jar).getCanonicalPath()); } if (jodConverterJar.length() == 0) { throw new Exception("Could not find jodConverter JAR file in JOD folder"); } argv.add("-jar"); argv.add(new File(jodFolder, jodConverterJar).getCanonicalPath()); argv.add(fileFullPath.getCanonicalPath()); argv.add(new File(destinationFolder, outputfile + ".pdf").getCanonicalPath()); return ProcessHelper.executeScript("doJodConvert", argv.toArray(new String[argv.size()])); } catch (Exception ex) { log.error("doJodConvert", ex); return new ConverterProcessResult("doJodConvert", ex.getMessage(), ex); } } }
@Transactional public class MeetingMemberDao { private static final Logger log = Red5LoggerFactory.getLogger(MeetingMemberDao.class, OpenmeetingsVariables.webAppRootKey); @PersistenceContext private EntityManager em; @Autowired private AppointmentDao appointmentDao; @Autowired private UsersDao usersDao; public MeetingMember getMeetingMemberById(Long meetingMemberId) { try { log.debug("getMeetingMemberById: " + meetingMemberId); String hql = "select app from MeetingMember app " + "WHERE app.deleted <> :deleted " + "AND app.meetingMemberId = :meetingMemberId"; TypedQuery<MeetingMember> query = em.createQuery(hql, MeetingMember.class); query.setParameter("deleted", true); query.setParameter("meetingMemberId", meetingMemberId); MeetingMember meetingMember = null; try { meetingMember = query.getSingleResult(); } catch (NoResultException ex) { } return meetingMember; } catch (Exception ex2) { log.error("[getMeetingMemberById]: ", ex2); } return null; } public List<MeetingMember> getMeetingMembers() { try { String hql = "select app from MeetingMember app"; TypedQuery<MeetingMember> query = em.createQuery(hql, MeetingMember.class); List<MeetingMember> meetingMembers = query.getResultList(); return meetingMembers; } catch (Exception ex2) { log.error("[getMeetingMembers]: ", ex2); } return null; } public List<MeetingMember> getMeetingMemberByAppointmentId(Long appointmentId) { try { log.debug("getMeetingMemberByAppointmentId: " + appointmentId); String hql = "select app from MeetingMember app " + "WHERE app.deleted <> :deleted " + "AND app.appointment.appointmentId = :appointmentId"; TypedQuery<MeetingMember> query = em.createQuery(hql, MeetingMember.class); query.setParameter("deleted", true); query.setParameter("appointmentId", appointmentId); List<MeetingMember> listmeetingMember = query.getResultList(); return listmeetingMember; } catch (Exception ex2) { log.error("[getMeetingMemberByAppointmentId]: ", ex2); } return null; } /** Updating MeetingMember */ // ------------------------------------------------------------------------------- public MeetingMember updateMeetingMember(MeetingMember meetingMember) { log.debug(""); if (meetingMember.getMeetingMemberId() > 0) { try { if (meetingMember.getMeetingMemberId() == null) { em.persist(meetingMember); } else { if (!em.contains(meetingMember)) { meetingMember = em.merge(meetingMember); } } return meetingMember; } catch (Exception ex2) { log.error("[updateMeetingMember] ", ex2); } } else { log.error("[updateUser] " + "Error: No MeetingMemberId given"); } return null; } // ------------------------------------------------------------------------------- public Long updateMeetingMember( Long meetingMemberId, String firstname, String lastname, String memberStatus, String appointmentStatus, Long appointmentId, Long userid, String email, String phone) { try { MeetingMember gm = this.getMeetingMemberById(meetingMemberId); /* * if (gm == null) { log.debug("ALERT Object with ID: "+ * MeetingMemberId +" does not exist yet"); return null; } */ gm.setFirstname(firstname); gm.setLastname(lastname); // gm.setLanguageId(Languagemanagement.getInstance().getFieldLanguageById(languageId)); gm.setMemberStatus(memberStatus); gm.setAppointmentStatus(appointmentStatus); gm.setAppointment(appointmentDao.getAppointmentById(appointmentId)); gm.setDeleted(false); gm.setUpdatetime(new Date()); gm.setUserid(usersDao.get(userid)); gm.setEmail(email); gm.setPhone(phone); if (gm.getMeetingMemberId() == null) { em.persist(gm); } else { if (!em.contains(gm)) { gm = em.merge(gm); } } meetingMemberId = gm.getMeetingMemberId(); return meetingMemberId; } catch (Exception ex2) { log.error("[updateMeetingMember]: ", ex2); } return null; } public Long addMeetingMember( String firstname, String lastname, String memberStatus, String appointmentStatus, Long appointmentId, Long userid, String email, String phone, Boolean moderator, OmTimeZone omTimeZone, Boolean isConnectedEvent) { try { MeetingMember gm = new MeetingMember(); gm.setFirstname(firstname); gm.setLastname(lastname); gm.setMemberStatus(memberStatus); gm.setAppointmentStatus(appointmentStatus); gm.setAppointment(appointmentDao.getAppointmentById(appointmentId)); gm.setUserid(userid == null ? null : usersDao.get(userid)); gm.setEmail(email); gm.setPhone(phone); gm.setStarttime(new Date()); gm.setDeleted(false); gm.setInvitor(moderator); gm.setIsConnectedEvent(isConnectedEvent); gm.setOmTimeZone(omTimeZone); gm = em.merge(gm); Long group_member_id = gm.getMeetingMemberId(); return group_member_id; } catch (Exception ex2) { log.error("[addMeetingMember]: ", ex2); } return null; } public Long addMeetingMemberByObject(MeetingMember gm) { try { gm = em.merge(gm); Long group_member_id = gm.getMeetingMemberId(); return group_member_id; } catch (Exception ex2) { log.error("[addMeetingMember]: ", ex2); } return null; } public Long deleteMeetingMember(Long meetingMemberId) { log.debug("MeetingMemnerDAoImpl.deleteMeetingMember : " + meetingMemberId); try { MeetingMember gm = this.getMeetingMemberById(meetingMemberId); log.debug("ac: " + gm); if (gm == null) { log.debug("Already deleted / Could not find: " + meetingMemberId); return null; } gm.setUpdatetime(new Date()); gm.setDeleted(true); if (gm.getMeetingMemberId() == null) { em.persist(gm); } else { if (!em.contains(gm)) { em.merge(gm); } } return meetingMemberId; } catch (Exception ex2) { log.error("[deleteMeetingMember]: ", ex2); } return null; } }
/** * A <code>ClassLoadHelper</code> that determines the correct class loader to use for a scheduler. * * @see org.quartz.spi.ClassLoadHelper * @author Paul Gregoire ([email protected]) */ public class QuartzClassLoadHelper implements ClassLoadHelper { private static Logger log = Red5LoggerFactory.getLogger(QuartzClassLoadHelper.class); private ClassLoader initClassLoader; /* ClassLoader classLoader = Thread.currentThread().getContextClassLoader(); if (classLoader == null) { classLoader = this.getClass().getClassLoader(); result= classLoader.getResourceAsStream( name ); } else { result= classLoader.getResourceAsStream( name ); if (result == null) { classLoader = this.getClass().getClassLoader(); result= classLoader.getResourceAsStream( name ); } } */ /** * Called to give the ClassLoadHelper a chance to initialize itself, including the opportunity to * "steal" the class loader off of the calling thread, which is the thread that is initializing * Quartz. */ public void initialize() { initClassLoader = Thread.currentThread().getContextClassLoader(); log.debug("Initialized with classloader: {}", initClassLoader); } /** Return the class with the given name. */ public Class<?> loadClass(String name) throws ClassNotFoundException { return getClassLoader().loadClass(name); } /** * Finds a resource with a given name. This method returns null if no resource with this name is * found. * * @param name name of the desired resource * @return a java.net.URL object */ public URL getResource(String name) { return getClassLoader().getResource(name); } /** * Finds a resource with a given name. This method returns null if no resource with this name is * found. * * @param name name of the desired resource * @return a java.io.InputStream object */ public InputStream getResourceAsStream(String name) { return getClassLoader().getResourceAsStream(name); } /** * Enable sharing of the class-loader with 3rd party (e.g. digester). * * @return the class-loader user be the helper. */ public ClassLoader getClassLoader() { log.debug( "Class classloader: {} Thread classloader: {}", this.getClass().getClassLoader(), Thread.currentThread().getContextClassLoader()); return Thread.currentThread().getContextClassLoader(); } }
/** * Admin for Red5 * * @author Paul Gregoire * @author Dan Rossi */ public class AdminPlugin extends Red5Plugin { private static Logger log = Red5LoggerFactory.getLogger(AdminPlugin.class, "admin"); private AdminHandler handler = null; private ApplicationContext adminContext; private String hostName = "localhost"; @Override public void doStart() throws Exception { super.doStart(); // create a handler handler = new AdminHandler(); // create app context adminContext = new FileSystemXmlApplicationContext( new String[] {"classpath:/admin-security.xml"}, true, context); // set the context handler.setContext(adminContext); // get a ref to the "default" global scope GlobalScope global = (GlobalScope) server.getGlobal("default"); // create a scope resolver ScopeResolver scopeResolver = new ScopeResolver(); scopeResolver.setGlobalScope(global); AuthClientRegistry registry = (AuthClientRegistry) adminContext.getBean("authClientRegistry"); // create a context - this takes the place of the previous web context Context ctx = new Context(adminContext, "admin"); ctx.setClientRegistry(registry); ctx.setMappingStrategy(new MappingStrategy()); ctx.setPersistanceStore(global.getStore()); ctx.setScopeResolver(scopeResolver); ctx.setServiceInvoker(new ServiceInvoker()); // create a scope for the admin // Scope scope = new Scope.Builder((IScope) global, "scope", "admin", false).build(); // // scope.setContext(ctx); // scope.setHandler(handler); // // //set the scope on the handler // handler.setScope(scope); server.addMapping(hostName, "admin", "default"); // if (global.addChildScope(scope)) { // log.info("Admin scope was added to global (default) scope"); // // } else { // log.warn("Admin scope was not added to global (default) scope"); // } } @Override public void doStop() throws Exception { super.doStop(); // clean up / unregister everything server.removeMapping(hostName, "admin"); handler.stop(null); } @Override public String getName() { return "adminPlugin"; } @Override public void init() { log.debug("Initializing"); super.init(); } public String getHostName() { return hostName; } public void setHostName(String hostName) { this.hostName = hostName; } }