Here is a simple code for screen sharing( ofcourse, it just sends one image):Capture screen and send to red5:
import org.red5.server.net.rtmp.*;
import org.red5.server.api.service.*;
import java.io.*;
public class Red5Client {
static byte [] imgbyte = new byte[1000000];
public static void main(String args[]) throws Exception{
final CaptureScreen capture = new CaptureScreen();
final RTMPClient client = new RTMPClient();
client.connect(“localhost”, 1935, “echo”, new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
Object[] param = new Object[1];
try{
capture.capture();
}
catch(Exception e){
e.printStackTrace();
}
param[0]=Red5Client.imgbyte;
System.err.println(“Connected: ” + call.getResult());
client.invoke(“echo”, param,
new IPendingServiceCallback() {
public void resultReceived(IPendingServiceCall call) {
System.err.println(“Received: ” + call.getResult());
}
});
}
});
}
}
import java.net.URLConnection;
import java.net.URL;
import java.awt.image.BufferedImage;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.image.codec.jpeg.JPEGCodec;
import javax.imageio.*;
public class CaptureScreen {
private Date startDate;
public static final int interval = 10;
public CaptureScreen(){
}
public void capture() throws Exception {
// wait for a user-specified time
try {
Thread.sleep(interval);
} catch(NumberFormatException nfe) {
}
// determine current screen size
Toolkit toolkit = Toolkit.getDefaultToolkit();
Dimension screenSize = toolkit.getScreenSize();
Rectangle screenRect = new Rectangle(screenSize);
// create screen shot
Robot robot = new Robot();
BufferedImage image = robot.createScreenCapture(screenRect);
ByteArrayOutputStream out = new ByteArrayOutputStream();
JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
JPEGEncodeParam encpar = encoder.getDefaultJPEGEncodeParam(image);
encoder.setJPEGEncodeParam(encpar);
encoder.encode(image);
System.out.println(out.size());
Viewer.image = Toolkit.getDefaultToolkit().createImage(out.toByteArray());
Red5Client.imgbyte = out.toByteArray();
System.out.println(“Length of image”+out.toByteArray().length);
// use System.exit if the program hangs after writing the file;
// that’s an old bug which got fixed only recently
// System.exit(0);
}
}
Flash Client:
import flash.display.*;
var so:SharedObject = null;
var ldr:Loader = new Loader();
addChild(ldr);
// Current release of FMS only understands AMF0 so tell Flex to
// use AMF0 for all NetConnection objects.
NetConnection.defaultObjectEncoding = flash.net.ObjectEncoding.AMF0;
init();
function init():void{
// Create the NetConnection and listen for NetStatusEvent and SecurityErrorEvent events
nc = new NetConnection();
nc.addEventListener(NetStatusEvent.NET_STATUS, netStatus);
nc.addEventListener(SecurityErrorEvent.SECURITY_ERROR, netSecurityError);
nc.connect(“rtmp://127.0.0.1/echo”);
}
function shared_sync(event:SyncEvent) :void {
trace(“test”);
var list:Object=event.changeList;
for (var n in list) {
so_data=so.data[list[n].name];
var byteArr:ByteArray = new ByteArray();
for(i=0;i<so_data.length;i++){
byteArr[i]=so_data[i];
}
ldr.loadBytes(byteArr);
trace(“Length of shared Object”+so.data[list[n].name].length);
}
};
function netStatus(event:NetStatusEvent):void {
trace(“netStatus: ” + event);
var info:Object = event.info;
trace(info.code);
// lots more code here…
if (info.code == “NetConnection.Connect.Success”) {
trace(“Connect success”);
so = SharedObject.getRemote
(“test”, nc.uri, true);
so.addEventListener(SyncEvent.SYNC, shared_sync);
so.connect(nc);
}
else{
trace(“error”);
}
}
function netSecurityError(event:SecurityErrorEvent):void {
trace(“netSecurityError: ” + event);
}
//nc = new NetConnection();
//nc.onStatus = function(info) {
//}
//nc.connect(“rtmp://127.0.0.1/echo”);
/*
nc.onResult = function(obj) {
trace(“The result is ” + obj);
}
nc.call(“add”, nc, 1, 2);
*/
ZoD said
il doit manquer quelquechose quelque part car Viewer.image est indefini … une idee ?
Anonymous said
Thanks for sharing this
I’ve been having a play with it, and got the java side connecting to red5, sending the bytearray, then receiving it back again.
I’ve also got he flash side connecting to red5, when it connects the shared_sync function is fired.
Problem is, the flash file never receives anything from java. I noticed that flash is trying to sync with a shared object call ‘test’, but I can’t find any reference to ‘test’ in the java code. Am I missing something?
mainichipress said
Hi Anonymous,
Probably I missed something.
Change your echo application in red5 as below,
package org.red5.server.webapp.echo;
/*
* RED5 Open Source Flash Server – http://www.osflash.org/red5
*
* Copyright (c) 2006-2007 by respective authors (see below). All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it under the
* terms of the GNU Lesser General Public License as published by the Free Software
* Foundation; either version 2.1 of the License, or (at your option) any later
* version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT ANY
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
* PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License along
* with this library; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
import org.red5.server.adapter.ApplicationAdapter;
import org.red5.server.api.IClient;
import org.red5.server.api.IScope;
import org.red5.server.api.so.ISharedObject;
/**
* Echo sample application.
*
* @author The Red5 Project (red5@osflash.org)
* @author Joachim Bauch (jojo@struktur.de)
*/
public class Application extends ApplicationAdapter {
IScope scope;
public boolean appJoin(IClient client, IScope app){
scope = app;
System.out.println(“applicatin statrte”);
log.debug(“CURRENT CLIENTS ” + getClients().size());
log.debug(“CLIENT ” + client + ” JOINS APP “+app);
if (!hasSharedObject(app,”test”))
createSharedObject(app,”test”,true);
return true;
}
public Object echo(Object[] param) {
/* for(int i=0;i<param.length;i++){
System.out.println(param[i]);
log.debug(param[i]);
}
*/
System.out.println(hasSharedObject(scope,”test”));
log.debug(hasSharedObject(scope,”test”));
ISharedObject so = getSharedObject(scope, “test”);
so.setAttribute(“test”, param);
return “xyz”;
}
}
Then restart Red5.
Hope it helps.
Thanks,
Mainichipress
mainichipress said
The name of the shared object test.
This shared object is created in echo application and
accessed from flash client.
innvodave said
wow! that was a fast reply
Thanks for posting the server side code, it’s all working now. I have a question tho:
This works well for a single image, but have you got any ideas how to screen share in realtime using java and flash? as this method takes too long for realtime sharing. I guess the grabs would need to be encoded and sent to red5 as a video stream? Any idea where to start with doing that?
Thanks again for your help.
Dave
mainichipress said
Hi,
I think you can some sort of codec with that.
A basic codec will be like some thhreshold of
pixel difference between consecuitve image. Then send the changed portion
of the image to the flash, flash will then refresh with the updated pixel.
I have never done this. I dont know what should be best codec for screen.
You may try somesort of mpeg encoding for this.
Hope it helps.
thanks,
manichipress
Sunil said
Hi mainichipress,
Thanks for such a good article. I have one question. I want to replace the Flash part of your article with Java. It means, there are two java RTMP clients and no Flash.
How to acheive that? Sync method on Java client is possible?
Thanks Again
Sunil
Sunil said
Hey, You did a great job. I got my things.. Thanks buddy.
Anonymous said
Pls i hv a project……for the same application..cn u help me…….,
William said
HI i have a continuous problem when trying this application which is exacly what i need
2009-09-21 15:38:52 org.red5.server.net.rtmp.RTMPMinaIoHandler exceptionCaught
and on the red5 side i get
RTMPMinaConnection from 127.0.0.1 : 3040 to null (in: 0 out 0 ), with id 1638183 due to long handshake
i cannot figure out why it is doing this, my application is working perfectly but i cannot make this thing to work…