You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openmeetings.apache.org by so...@apache.org on 2012/05/13 05:38:42 UTC

svn commit: r1337762 - in /incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings: app/remote/red5/ScopeApplicationAdapter.java screen/webstart/CoreScreenShare.java screen/webstart/gui/ScreenSharerFrame.java

Author: solomax
Date: Sun May 13 03:38:42 2012
New Revision: 1337762

URL: http://svn.apache.org/viewvc?rev=1337762&view=rev
Log:
OPENMEETINGS-266 functional changes, stream publishing seems to work as expected

Modified:
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/red5/ScopeApplicationAdapter.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java
    incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/gui/ScreenSharerFrame.java

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/red5/ScopeApplicationAdapter.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/red5/ScopeApplicationAdapter.java?rev=1337762&r1=1337761&r2=1337762&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/red5/ScopeApplicationAdapter.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/app/remote/red5/ScopeApplicationAdapter.java Sun May 13 03:38:42 2012
@@ -53,6 +53,7 @@ import org.openmeetings.app.remote.White
 import org.openmeetings.utils.math.CalendarPatterns;
 import org.red5.logging.Red5LoggerFactory;
 import org.red5.server.adapter.ApplicationAdapter;
+import org.red5.server.api.IBasicScope;
 import org.red5.server.api.IClient;
 import org.red5.server.api.IConnection;
 import org.red5.server.api.IScope;
@@ -61,6 +62,12 @@ import org.red5.server.api.service.IPend
 import org.red5.server.api.service.IPendingServiceCallback;
 import org.red5.server.api.service.IServiceCapableConnection;
 import org.red5.server.api.stream.IBroadcastStream;
+import org.red5.server.api.stream.IStreamListener;
+import org.red5.server.api.stream.IStreamPacket;
+import org.red5.server.net.rtmp.event.IRTMPEvent;
+import org.red5.server.stream.IBroadcastScope;
+import org.red5.server.stream.StreamingProxy;
+import org.red5.server.stream.message.RTMPMessage;
 import org.slf4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -96,6 +103,7 @@ public class ScopeApplicationAdapter ext
 	@Autowired
 	private MeetingMemberDaoImpl meetingMemberDao;
 
+    private Map<String, StreamingProxy> streamingProxyMap = new HashMap<String, StreamingProxy>();
 	// This is the Folder where all executables are written
 	// for windows platform
 	public static String batchFileFir = "webapps" + File.separatorChar + "ROOT"
@@ -120,10 +128,6 @@ public class ScopeApplicationAdapter ext
 	@Override
 	public synchronized boolean appStart(IScope scope) {
 		try {
-			// This System out is for testing SLF4J / LOG4J and custom logging n
-			// Red5
-			// System.out.println("Custom Webapp start UP "+new Date());
-
 			webAppPath = scope.getResource("/").getFile().getAbsolutePath();
 			batchFileFir = webAppPath + File.separatorChar + OpenmeetingsVariables.STREAMS_DIR
 					+ File.separatorChar;
@@ -229,34 +233,23 @@ public class ScopeApplicationAdapter ext
 
 			if (currentClient != null) {
 
-				boolean stopStreaming = Boolean.valueOf(map
-						.get("stopStreaming").toString());
-				boolean stopRecording = Boolean.valueOf(map
-						.get("stopRecording").toString());
-
-				if (stopStreaming) {
-
+				if (Boolean.valueOf(map.get("stopStreaming").toString())) {
 					log.debug("start streamPublishStart Is Screen Sharing -- Stop ");
 					
 					//Send message to all users
 					syncMessageToCurrentScope("stopRed5ScreenSharing", currentClient, false);
 
 					if (currentClient.isStartRecording()) {
-
 						returnMap.put("result", "stopSharingOnly");
-
 					}
 
 					currentClient.setStartStreaming(false);
 					currentClient.setScreenPublishStarted(false);
 
-					this.clientListManager.updateClientByStreamId(
+					clientListManager.updateClientByStreamId(
 							currentClient.getStreamid(), currentClient);
-
 				}
-
-				if (stopRecording) {
-
+				if (Boolean.valueOf(map.get("stopRecording").toString())) {
 					if (currentClient.isStartStreaming()) {
 						returnMap.put("result", "stopRecordingOnly");
 					}
@@ -264,21 +257,23 @@ public class ScopeApplicationAdapter ext
 					//Send message to all users
 					syncMessageToCurrentScope("stopRecordingMessage", currentClient, false);
 
-					this.flvRecorderService.stopRecordAndSave(
+					flvRecorderService.stopRecordAndSave(
 							current.getScope(), currentClient, null);
 
 					currentClient.setStartRecording(false);
 					currentClient.setIsRecording(false);
 
-					this.clientListManager.updateClientByStreamId(
+					clientListManager.updateClientByStreamId(
 							currentClient.getStreamid(), currentClient);
-
 				}
-
+				if (Boolean.valueOf(map.get("stopPublishing").toString())) {
+					streamPublishingStop();
+					if (currentClient.getIsScreenClient() && currentClient.isStartStreaming()) {
+						returnMap.put("result", "stopPublishingOnly");
+					}
+				}
 			}
-
 			return returnMap;
-
 		} catch (Exception err) {
 			log.error("[screenSharerAction]", err);
 		}
@@ -402,27 +397,25 @@ public class ScopeApplicationAdapter ext
 						.getClient().getId(), currentClient);
 
 				if (startStreaming) {
-
 					returnMap.put("modus", "startStreaming");
 
 					log.debug("start streamPublishStart Is Screen Sharing ");
 					
 					//Send message to all users
 					syncMessageToCurrentScope("newRed5ScreenSharing", currentClient, false);
-
-				}
-
-				if (startRecording) {
-
+				} else if (startRecording) {
 					returnMap.put("modus", "startRecording");
 
 					String recordingName = "Recording "
 							+ CalendarPatterns
 									.getDateWithTimeByMiliSeconds(new Date());
 
-					this.flvRecorderService.recordMeetingStream(recordingName,
-							"", false);
-
+					flvRecorderService.recordMeetingStream(recordingName, "", false);
+				} else if (Boolean.valueOf(map.get("startPublishing").toString())) {
+					returnMap.put("modus", "startPublishing");
+					streamPublishingStart("" + map.get("publishingHost")
+						, "" + map.get("publishingApp")
+						, "" + map.get("publishingId"));
 				}
 
 				return returnMap;
@@ -805,6 +798,64 @@ public class ScopeApplicationAdapter ext
 		}
 	}
 
+	public IBroadcastScope getBroadcastScope(IScope scope, String name) {
+		IBasicScope basicScope = scope.getBasicScope(IBroadcastScope.TYPE, name);
+		if (!(basicScope instanceof IBroadcastScope)) {
+			return null;
+		} else {
+			return (IBroadcastScope) basicScope;
+		}
+	}
+
+    public void streamPublishingStart(String host, String app, String id) {
+		IConnection current = Red5.getConnectionLocal();
+		RoomClient rc = clientListManager.getClientByStreamId(current.getClient().getId());
+		String publishName = rc.getStreamPublishName();
+		
+		if (rc.getIsScreenClient() && rc.isStartStreaming()) {
+	        IScope scope = current.getScope();
+	        IBroadcastStream stream = getBroadcastStream(scope, publishName);
+	        IBroadcastScope bsScope = getBroadcastScope(scope, publishName);
+	        final StreamingProxy proxy = new StreamingProxy();
+	        proxy.setHost(host);
+	        proxy.setApp(app);
+	        proxy.setPort(1935);
+	        proxy.init();
+	        bsScope.subscribe(proxy, null);
+	        proxy.start(id, StreamingProxy.LIVE, null);
+	        streamingProxyMap.put(publishName, proxy);
+	        stream.addStreamListener(new IStreamListener() {
+				public void packetReceived(IBroadcastStream stream, IStreamPacket packet) {
+					try {
+						RTMPMessage m = RTMPMessage.build((IRTMPEvent)packet, packet.getTimestamp());
+				        proxy.pushMessage(null, m);
+					} catch (IOException ioe) {
+						log.error("Exception while sending proxy message", ioe);
+					}
+				}
+			});
+		}
+    }
+    
+    public void streamPublishingStop() {
+		IConnection current = Red5.getConnectionLocal();
+		RoomClient rc = clientListManager.getClientByStreamId(current.getClient().getId());
+		String publishName = rc.getStreamPublishName();
+		
+		if (rc.getIsScreenClient() && publishName != null) {
+	        IScope scope = current.getScope();
+	        IBroadcastStream stream = getBroadcastStream(scope, publishName);
+			StreamingProxy proxy = streamingProxyMap.remove(publishName);
+			if (proxy != null) {
+				proxy.stop();
+				IBroadcastScope bsScope = getBroadcastScope(scope, stream.getPublishedName());
+				if (bsScope != null) {
+					bsScope.unsubscribe(proxy);
+				}
+			}
+		}
+    }
+    
 	/**
 	 * This method handles the Event after a stream has been removed all
 	 * connected Clients in the same room will get a notification
@@ -819,9 +870,10 @@ public class ScopeApplicationAdapter ext
 		log.debug("start streamBroadcastClose broadcast close: "
 				+ stream.getPublishedName());
 		try {
-			RoomClient rcl = this.clientListManager.getClientByStreamId(Red5
-					.getConnectionLocal().getClient().getId());
-
+			streamPublishingStop();
+			
+			IConnection current = Red5.getConnectionLocal();
+			RoomClient rcl = clientListManager.getClientByStreamId(current.getClient().getId());
 			sendClientBroadcastNotifications(stream, "closeStream", rcl);
 		} catch (Exception e) {
 			log.error("[streamBroadcastClose]", e);

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java?rev=1337762&r1=1337761&r2=1337762&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/CoreScreenShare.java Sun May 13 03:38:42 2012
@@ -69,11 +69,9 @@ public class CoreScreenShare {
 	public Long user_id = null;
 	public Boolean allowRecording = true;
 
-	public boolean startRecording = false;
-	public boolean stopRecording = false;
-
-	public boolean startStreaming = false;
-	public boolean stopStreaming = false;
+	private boolean startStreaming = false;
+	private boolean startRecording = false;
+	private boolean startPublishing = false;
 
 	public String label730 = "Desktop Publisher";
 	public String label731 = "This application will publish your screen";
@@ -225,7 +223,7 @@ public class CoreScreenShare {
 				}
 			});
 			frame.setVisible(true);
-			frame.setTabsEnabled(allowRecording);
+			frame.setRecordingTabEnabled(allowRecording);
 
 			logger.debug("initialized");
 
@@ -279,8 +277,12 @@ public class CoreScreenShare {
 			map.put("screenHeight", scaledHeight);
 
 			map.put("publishName", this.publishName);
-			map.put("startRecording", this.startRecording);
-			map.put("startStreaming", this.startStreaming);
+			map.put("startRecording", startRecording);
+			map.put("startStreaming", startStreaming);
+			map.put("startPublishing", startPublishing);
+			map.put("publishingHost", frame.getPublishHost());
+			map.put("publishingApp", frame.getPublishApp());
+			map.put("publishingId", frame.getPublishId());
 
 			map.put("organization_id", this.organization_id);
 			map.put("user_id", this.user_id);
@@ -293,30 +295,53 @@ public class CoreScreenShare {
 		}
 	}
 
-	public void captureScreenStart() {
+	/**
+	 * @param startStreaming flag denoting the streaming is started
+	 * @param startRecording flag denoting the recording is started
+	 */
+	public void captureScreenStart(boolean startStreaming, boolean startRecording) {
+		captureScreenStart(startStreaming, startRecording, false);
+	}
+	
+	public void captureScreenStart(boolean startStreaming, boolean startRecording, boolean startPublishing) {
 		try {
 			logger.debug("captureScreenStart");
-			startStream(host, app, port, publishName);
+			this.startStreaming = startStreaming;
+			this.startRecording= startRecording;
+			this.startPublishing = startPublishing;
+			
+			if (!isConnected) {
+				instance.connect(host, port, app, instance);
+			} else {
+				setConnectionAsSharingClient();
+			}
 		} catch (Exception err) {
 			logger.error("captureScreenStart Exception: ", err);
 			frame.setStatus("Exception: " + err);
 		}
 	}
 
-	public void captureScreenStop() {
+	public void captureScreenStop(boolean stopStreaming, boolean stopRecording) {
+		captureScreenStop(stopStreaming, stopRecording, false);
+	}
+	
+	public void captureScreenStop(boolean stopStreaming, boolean stopRecording, boolean stopPublishing) {
 		try {
 			logger.debug("INVOKE screenSharerAction" );
 
-			Map<Object, Object> map = new HashMap<Object, Object>();
-			map.put("stopStreaming", this.stopStreaming);
-			map.put("stopRecording", this.stopRecording);
+			Map<String, Object> map = new HashMap<String, Object>();
+			map.put("stopStreaming", stopStreaming);
+			map.put("stopRecording", stopRecording);
+			map.put("stopPublishing", stopPublishing);
 
 			instance.invoke("screenSharerAction", new Object[] { map }, instance);
 
 			if (stopStreaming) {
 				frame.setSharingStatus(false);
-			} else {
+			} else if (stopRecording) {
 				frame.setRecordingStatus(false);
+			} else if (stopPublishing) {
+				frame.setPublishingStatus(false);
 			}
 		} catch (Exception err) {
 			logger.error("captureScreenStop Exception: ", err);
@@ -330,23 +355,6 @@ public class CoreScreenShare {
 	//
 	// ------------------------------------------------------------------------
 
-	public void startStream(String host, String app, int port,
-			String publishName) {
-
-		logger.debug("ScreenShare startStream");
-		this.publishName = publishName;
-
-		try {
-			if (!isConnected) {
-				instance.connect(host, port, app, instance);
-			} else {
-				setConnectionAsSharingClient();
-			}
-		} catch (Exception e) {
-			logger.error("ScreenShare startStream exception " + e);
-		}
-	}
-
 	protected void onInvoke(RTMPConnection conn, Channel channel,
 			Header source, Notify invoke, RTMP rtmp) {
 
@@ -758,35 +766,21 @@ public class CoreScreenShare {
 			logger.debug( "service call result: " + call );
 
 			if (call.getServiceMethodName().equals("connect")) {
-
 				isConnected = true;
 				setConnectionAsSharingClient();
-
 			} else if (call.getServiceMethodName().equals(
 					"setConnectionAsSharingClient")) {
 
-				// logger.debug("call get Method Name "+call.getServiceMethodName());
-
 				Object o = call.getResult();
 
-				// logger.debug("Result Map Type "+o.getClass().getName());
-
 				@SuppressWarnings("rawtypes")
 				Map returnMap = (Map) o;
 
-				// logger.debug("result "+returnMap.get("result"));
-
-				// for (Iterator iter =
-				// returnMap.keySet().iterator();iter.hasNext();) {
-				// logger.debug("key "+iter.next());
-				// }
-
 				if (o == null || !Boolean.valueOf("" + returnMap.get("alreadyPublished")).booleanValue()) {
 					logger.debug("Stream not yet started - do it ");
 
 					instance.createStream(instance);
 				} else {
-
 					if (this.capture != null) {
 						this.capture.resetBuffer();
 					}
@@ -794,13 +788,14 @@ public class CoreScreenShare {
 					logger.debug("The Stream was already started ");
 				}
 
-				if (returnMap != null && returnMap.get("modus") != null) {
-					if (returnMap.get("modus").toString()
-							.equals("startStreaming")) {
+				if (returnMap != null) {
+					Object modus = returnMap.get("modus");
+					if ("startStreaming".equals(modus)) {
 						frame.setSharingStatus(true);
-					} else if (returnMap.get("modus").toString()
-							.equals("startRecording")) {
+					} else if ("startRecording".equals(modus)) {
 						frame.setRecordingStatus(true);
+					} else if ("startPublishing".equals(modus)) {
+						frame.setPublishingStatus(true);
 					}
 				} else {
 					throw new Exception(
@@ -817,10 +812,6 @@ public class CoreScreenShare {
 
 				logger.debug("setup capture thread");
 
-				logger.debug("setup capture thread getCanonicalName "
-						+ ScreenDimensions.class.getCanonicalName());
-				logger.debug("setup capture thread getName "
-						+ ScreenDimensions.class.getName());
 				logger.debug("setup capture thread vScreenSpinnerWidth "
 						+ ScreenDimensions.spinnerWidth);
 				logger.debug("setup capture thread vScreenSpinnerHeight "
@@ -835,7 +826,6 @@ public class CoreScreenShare {
 				capture.start();
 
 			} else if (call.getServiceMethodName().equals("screenSharerAction")) {
-
 				logger.debug("call ### get Method Name "
 						+ call.getServiceMethodName());
 
@@ -843,27 +833,19 @@ public class CoreScreenShare {
 
 				logger.debug("Result Map Type " + o.getClass().getName());
 
-				@SuppressWarnings("rawtypes")
-				Map returnMap = (Map) o;
-
-				// logger.debug("result "+returnMap.get("result"));
-
-				// for (Iterator iter =
-				// returnMap.keySet().iterator();iter.hasNext();) {
-				// logger.debug("key "+iter.next());
-				// }
-
-				if (returnMap.get("result").equals("stopAll")) {
-
+				@SuppressWarnings("unchecked")
+				Map<String, Object> returnMap = (Map<String, Object>)o;
+				Object result = returnMap.get("result");
+				if ("stopAll".equals(result)) {
 					logger.debug("Stopping to stream, there is neither a Desktop Sharing nor Recording anymore");
-
 					stopStream();
-
+				} else if ("stopSharingOnly".equals(result)) {
+					//no op
+				} else if ("stopRecordingOnly".equals(result)) {
+					//no op
+				} else if ("stopPublishingOnly".equals(result)) {
+					frame.setPublishingStatus(false);
 				}
-
-				// logger.debug("Stop No Doubt!");
-				// stopStream();
-
 			} else if (call.getServiceMethodName().equals(
 					"setNewCursorPosition")) {
 

Modified: incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/gui/ScreenSharerFrame.java
URL: http://svn.apache.org/viewvc/incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/gui/ScreenSharerFrame.java?rev=1337762&r1=1337761&r2=1337762&view=diff
==============================================================================
--- incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/gui/ScreenSharerFrame.java (original)
+++ incubator/openmeetings/trunk/singlewebapp/src/org/openmeetings/screen/webstart/gui/ScreenSharerFrame.java Sun May 13 03:38:42 2012
@@ -75,6 +75,7 @@ public class ScreenSharerFrame extends J
 	private JButton btnStartPauseSharing;
 	private JButton btnStartRecording;
 	private JButton btnStopRecording;
+	private JButton btnStartPublish;
 	private JButton btnStopPublish;
 	private NumberSpinner spinnerX;
 	private NumberSpinner spinnerY;
@@ -82,7 +83,7 @@ public class ScreenSharerFrame extends J
 	private NumberSpinner spinnerHeight;
 	private JComboBox comboQuality;
 	private JTextField textPublishHost;
-	private JTextField textPublishContext;
+	private JTextField textPublishApp;
 	private JTextField textPublishId;
 	private JLabel lblPublishURL;
 	private boolean sharingStarted = false;
@@ -102,15 +103,15 @@ public class ScreenSharerFrame extends J
 			getDocument().addDocumentListener(
 				new DocumentListener() {
 					public void changedUpdate(DocumentEvent e) {
-						updateLabelURL();
+						updatePublishURL();
 					}
 
 					public void removeUpdate(DocumentEvent e) {
-						updateLabelURL();
+						updatePublishURL();
 					}
 
 					public void insertUpdate(DocumentEvent e) {
-						updateLabelURL();
+						updatePublishURL();
 					}
 				});
 
@@ -230,13 +231,9 @@ public class ScreenSharerFrame extends J
 		btnStartPauseSharing.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent arg0) {
 				if (sharingStarted) {
-					core.stopRecording = false;
-					core.stopStreaming = true;
-					core.captureScreenStop();
+					core.captureScreenStop(true, false);
 				} else {
-					core.startRecording = false;
-					core.startStreaming = true;
-					core.captureScreenStart();
+					core.captureScreenStart(true, false);
 				}
 			}
 		});
@@ -272,9 +269,7 @@ public class ScreenSharerFrame extends J
 		btnStartRecording.setBounds(10, 82, 200, 32);
 		btnStartRecording.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent arg0) {
-				core.startRecording = true;
-				core.startStreaming = false;
-				core.captureScreenStart();
+				core.captureScreenStart(false, true);
 			}
 		});
 		panelRecording.add(btnStartRecording);
@@ -285,9 +280,7 @@ public class ScreenSharerFrame extends J
 		btnStopRecording.setBounds(257, 82, 200, 32);
 		btnStopRecording.addActionListener(new ActionListener() {
 			public void actionPerformed(ActionEvent arg0) {
-				core.stopRecording = true;
-				core.stopStreaming = false;
-				core.captureScreenStop();
+				core.captureScreenStop(false, true);
 			}
 		});
 		panelRecording.add(btnStopRecording);
@@ -298,16 +291,26 @@ public class ScreenSharerFrame extends J
 		panelPublish.setEnabled(false);
 		panelPublish.setLayout(null);
 		
-		JButton btnStartPublish = new JButton(core.label1466);
+		btnStartPublish = new JButton(core.label1466);
 		btnStartPublish.setToolTipText(core.label1466);
 		//btnStartPublish.setIcon(new ImageIcon(ScreenSharerFrame.class.getResource("/org/openmeetings/screen/record.png")));
 		btnStartPublish.setBounds(10, 82, 200, 32);
+		btnStartPublish.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				core.captureScreenStart(false, false, true);
+			}
+		});
 		panelPublish.add(btnStartPublish);
 		
 		btnStopPublish = new JButton(core.label1467);
 		btnStopPublish.setToolTipText(core.label1467);
 		btnStopPublish.setIcon(stopIcon);
 		btnStopPublish.setBounds(257, 82, 200, 32);
+		btnStopPublish.addActionListener(new ActionListener() {
+			public void actionPerformed(ActionEvent arg0) {
+				core.captureScreenStop(false, false, true);
+			}
+		});
 		panelPublish.add(btnStopPublish);
 		
 		JLabel lblPublishHost = new JLabel(core.label1468);
@@ -319,14 +322,14 @@ public class ScreenSharerFrame extends J
 		textPublishHost.setBounds(10, 38, 140, 20);
 		panelPublish.add(textPublishHost);
 		
-		JLabel lblPublishContext = new JLabel(core.label1469);
-		lblPublishContext.setVerticalAlignment(SwingConstants.TOP);
-		lblPublishContext.setBounds(160, 10, 140, 20);
-		panelPublish.add(lblPublishContext);
-		
-		textPublishContext = new PublishTextField();
-		textPublishContext.setBounds(160, 38, 140, 20);
-		panelPublish.add(textPublishContext);
+		JLabel lblPublishApp = new JLabel(core.label1469);
+		lblPublishApp.setVerticalAlignment(SwingConstants.TOP);
+		lblPublishApp.setBounds(160, 10, 140, 20);
+		panelPublish.add(lblPublishApp);
+		
+		textPublishApp = new PublishTextField();
+		textPublishApp.setBounds(160, 38, 140, 20);
+		panelPublish.add(textPublishApp);
 		
 		JLabel lblPublishId = new JLabel(core.label1470);
 		lblPublishId.setVerticalAlignment(SwingConstants.TOP);
@@ -511,20 +514,11 @@ public class ScreenSharerFrame extends J
 		comboQuality.setSelectedIndex(core.defaultQuality);
 		panelScreen.add(comboQuality);
 		
+		setPublishingTabEnabled(false);
 		contentPane.setLayout(gl_contentPane);
 		
-		//
 		// Background Image
-		
 		//We have no logo, that is why we need no background, sebawagner 29.04.2012
-		
-//		Image im_left = ImageIO.read(getClass()
-//				.getResource("/org/openmeetings/screen/background.png"));
-//		ImageIcon iIconBack = new ImageIcon(im_left);
-//
-//		JLabel jLab = new JLabel(iIconBack);
-//		jLab.setBounds(0, 0, 500, 440);
-//		contentPane.add(jLab);
 	}
 
 	public void setSharingStatus(boolean status) {
@@ -533,6 +527,7 @@ public class ScreenSharerFrame extends J
 		btnStartPauseSharing.setIcon(status ? pauseIcon : startIcon);
 		btnStartPauseSharing.setText(status ? pauseLabel : startLabel);
 		btnStartPauseSharing.setToolTipText(status ? pauseLabel : startLabel);
+		setPublishingTabEnabled(status);
 	}
 	
 	public void setRecordingStatus(boolean status) {
@@ -541,18 +536,39 @@ public class ScreenSharerFrame extends J
 		btnStopRecording.setEnabled(status);
 	}
 	
-	public void setTabsEnabled(boolean enabled) {
+	public void setPublishingStatus(boolean status) {
+		panelScreen.setEnabled(!status);
+		btnStartPublish.setEnabled(!status);
+		btnStopPublish.setEnabled(status);
+	}
+	
+	public void setRecordingTabEnabled(boolean enabled) {
 		panelRecording.setEnabled(enabled);
 		btnStopRecording.setEnabled(false);
 		tabbedPane.setEnabledAt(0, enabled);
+	}
+	
+	private void setPublishingTabEnabled(boolean enabled) {
 		panelPublish.setEnabled(enabled);
 		btnStopPublish.setEnabled(false);
 		tabbedPane.setEnabledAt(1, enabled);
 	}
 	
-	private void updateLabelURL() {
+	public String getPublishHost() {
+		return textPublishHost.getText();
+	}
+	
+	public String getPublishApp() {
+		return textPublishApp.getText();
+	}
+	
+	public String getPublishId() {
+		return textPublishId.getText();
+	}
+	
+	private void updatePublishURL() {
 		lblPublishURL.setText("rtmp://" + textPublishHost.getText() + ":1935/"
-				+ textPublishContext.getText() + "/" + textPublishId.getText());
+				+ textPublishApp.getText() + "/" + textPublishId.getText());
 	}
 	
 	public void setShowWarning(boolean showWarning) {