Smack/jingle/extension/source/org/jivesoftware/smackx/jingle/mediaimpl/sshare/ScreenShareSession.java

207 lines
6.9 KiB
Java
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

/**
* $RCSfile: ScreenShareSession.java,v $
* $Revision: 1.2 $
* $Date: 08/11/2006
* <p/>
* Copyright 2003-2006 Jive Software.
* <p/>
* All rights reserved. Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* <p/>
* http://www.apache.org/licenses/LICENSE-2.0
* <p/>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jivesoftware.smackx.jingle.mediaimpl.sshare;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.UnknownHostException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import org.jivesoftware.smackx.jingle.JingleSession;
import org.jivesoftware.smackx.jingle.SmackLogger;
import org.jivesoftware.smackx.jingle.media.JingleMediaSession;
import org.jivesoftware.smackx.jingle.media.PayloadType;
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageDecoder;
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageEncoder;
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageReceiver;
import org.jivesoftware.smackx.jingle.mediaimpl.sshare.api.ImageTransmitter;
import org.jivesoftware.smackx.jingle.nat.TransportCandidate;
/**
* This Class implements a complete JingleMediaSession.
* It sould be used to transmit and receive captured images from the Display.
* This Class should be automaticly controlled by JingleSession.
* For better NAT Traversal support this implementation don´t support only receive or only transmit.
* To receive you MUST transmit. So the only implemented and functionally methods are startTransmit() and stopTransmit()
*
* @author Thiago Camargo
*/
public class ScreenShareSession extends JingleMediaSession {
private static final SmackLogger LOGGER = SmackLogger.getLogger(ScreenShareSession.class);
private ImageTransmitter transmitter = null;
private ImageReceiver receiver = null;
private int width = 600;
private int height = 600;
/**
* Creates a org.jivesoftware.jingleaudio.jmf.AudioMediaSession with defined payload type, remote and local candidates
*
* @param payloadType Payload of the jmf
* @param remote the remote information. The candidate that the jmf will be sent to.
* @param local the local information. The candidate that will receive the jmf
* @param locator media locator
*/
public ScreenShareSession(final PayloadType payloadType, final TransportCandidate remote, final TransportCandidate local,
final String locator, JingleSession jingleSession) {
super(payloadType, remote, local, "Screen", jingleSession);
initialize();
}
/**
* Initialize the screen share channels.
*/
public void initialize() {
JingleSession session = getJingleSession();
if ((session != null) && (session.getInitiator().equals(session.getConnection().getUser()))) {
// If the initiator of the jingle session is us then we transmit a screen share.
try {
InetAddress remote = InetAddress.getByName(getRemote().getIp());
transmitter = new ImageTransmitter(new DatagramSocket(getLocal().getPort()), remote, getRemote().getPort(),
new Rectangle(0, 0, width, height));
} catch (Exception e) {
e.printStackTrace();
}
} else {
// Otherwise we receive a screen share.
JFrame window = new JFrame();
JPanel jp = new JPanel();
window.add(jp);
window.setLocation(0, 0);
window.setSize(600, 600);
window.addWindowListener(new WindowAdapter() {
public void windowClosed(WindowEvent e) {
receiver.stop();
}
});
try {
receiver = new ImageReceiver(InetAddress.getByName("0.0.0.0"), getRemote().getPort(), getLocal().getPort(), width,
height);
LOGGER.debug("Receiving on:" + receiver.getLocalPort());
} catch (UnknownHostException e) {
e.printStackTrace();
}
jp.add(receiver);
receiver.setVisible(true);
window.setAlwaysOnTop(true);
window.setVisible(true);
}
}
/**
* Starts transmission and for NAT Traversal reasons start receiving also.
*/
public void startTrasmit() {
new Thread(transmitter).start();
}
/**
* Set transmit activity. If the active is true, the instance should trasmit.
* If it is set to false, the instance should pause transmit.
*
* @param active active state
*/
public void setTrasmit(boolean active) {
transmitter.setTransmit(true);
}
/**
* For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
*/
public void startReceive() {
// Do nothing
}
/**
* Stops transmission and for NAT Traversal reasons stop receiving also.
*/
public void stopTrasmit() {
if (transmitter != null) {
transmitter.stop();
}
}
/**
* For NAT Reasons this method does nothing. Use startTransmit() to start transmit and receive jmf
*/
public void stopReceive() {
if (receiver != null) {
receiver.stop();
}
}
/**
* Obtain a free port we can use.
*
* @return A free port number.
*/
protected int getFreePort() {
ServerSocket ss;
int freePort = 0;
for (int i = 0; i < 10; i++) {
freePort = (int) (10000 + Math.round(Math.random() * 10000));
freePort = freePort % 2 == 0 ? freePort : freePort + 1;
try {
ss = new ServerSocket(freePort);
freePort = ss.getLocalPort();
ss.close();
return freePort;
} catch (IOException e) {
e.printStackTrace();
}
}
try {
ss = new ServerSocket(0);
freePort = ss.getLocalPort();
ss.close();
} catch (IOException e) {
e.printStackTrace();
}
return freePort;
}
public void setEncoder(ImageEncoder encoder) {
if (encoder != null) {
this.transmitter.setEncoder(encoder);
}
}
public void setDecoder(ImageDecoder decoder) {
if (decoder != null) {
this.receiver.setDecoder(decoder);
}
}
}