Implementando um VNC

tenho um colega que implementou uma especie VNC, mas só para mouse…
nada muito sofisticado…

se for open source o programa ele com certeza libera o fonte…

e aí???

Nossa, essa thread mal comecou e ja ta com aquele cheirinho de reinvencao de roda… hmmmmmmm… delicia :mrgreen:

Nao sei nem se a AWT te da esse controle todo a pegar os pixels da tela. Rola fazer isso com o java.awt.Robot e amigos?

Pois é, já tem tudo pronto, e o client do RealVNC é minúsculo (tanto o applet quanto o executável), e foi portado para N arquiteturas, que custa rodar o client e o server? Eu lembro que existe um modo do VNC que lhe permite conectar N clients a um único server, para que você possa mostrar o tal “videozinho”.

Eu acho que o que o Sérgio quer é um VNC muito mais simples e jmais flexível apra embutir em algo (lohis?).

Por que tu não tenta o método mais simples e vê se dá galho? Eu acho que se a área monitorada for pequena não deve ter muitos problemas.

Shoes

O programinha abaixo já te permite brincar de fazer um codec VNC.

Ele te fala quantos pixels estão mudando conforme vc brinca com a tela.

Se alguem fizer um codec de brincadeira, tipo um MPEG da vida e quiser me doar eu aceito. :stuck_out_tongue:

O objetivo e compremir esses bytes que estão mudando para eu poder jogar isso na rede.


import java.awt.*;
import java.awt.image.*;
import java.awt.event.*;
import javax.swing.*;
import java.io.*;

public class ScreenVideo extends JPanel implements Runnable {
	
	private int x, y, w, h;
	private float fps;
	private Robot robot;	
	private Rectangle rect;
	private Thread thread;
	private volatile boolean bThread;
	private int sleeptime;
	private Dimension size;
	private int [] imageBytes;
	private int [] lastFrame;
	
	public ScreenVideo(int x, int y, int w, int h, float fps) throws AWTException {
		this.x = x;
		this.y = y;
		this.w = w;
		this.h = h;
		this.fps = fps;
		this.rect = new Rectangle(x, y, w, h);
		this.size = new Dimension(w, h);
		this.robot = new Robot();
		this.sleeptime = (int) ((1 / fps) * 1000);
		this.imageBytes = new int[w * h];
		this.lastFrame = new int[w * h];
	}
	
	public void start() {
		startThread();
	}
	
	public void stop() {
		stopThread();
	}
	
	public Dimension getPreferredSize() {
		return size;
	}
	
	private void startThread() {
		bThread = true;
		thread = new Thread(this);
		thread.start();
	}
	
	private void stopThread() {
		bThread = false;
		thread.interrupt();
		thread = null;
	}
	
	public void run() {
		try {
			while(bThread) {
				BufferedImage bi = robot.createScreenCapture(rect);
				Graphics g = getGraphics();
				g.drawImage(bi, 0, 0, this);
				
				// veja o que mudou...
				bi.getRGB(0, 0, w, h, imageBytes, 0, w);
				int changed = 0;
				for(int i=0;i<imageBytes.length;i++) {
					if (imageBytes[i] != lastFrame[i]) {
						changed++;
						lastFrame[i] = imageBytes[i];
					}
				}
				System.out.println("Mudou: " + changed);
				
				Thread.sleep(sleeptime);
			}
		} catch(InterruptedException e) {
			// bye
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void main(String [] args) throws Exception {
		JFrame frame = new JFrame("Minha Tela");
		final ScreenVideo sv = new ScreenVideo(0, 0, 1024, 768, 1);
		frame.setContentPane(sv);
		
		frame.addWindowListener(new WindowAdapter() {
			public void windowClosing(WindowEvent evt) {
				sv.stop();
				System.exit(0);
			}
		});
		
		frame.pack();
		sv.start();
		frame.setVisible(true);
	}
}
				
			
	
	

>

Sergio, qual a performance disso?

Uma merda como o thingol falou, mas o P4 aqui tá aguentando tranquilo… :slight_smile:

Não há nada que um pentium não resolva hoje em dia, né? :stuck_out_tongue:

PS: Gostou do volatile no bThread ??? :thumbup:

Nao rodei o codigo, mas se eu entendi ele desenha um JFrame de 1024x768 na tela, e poe ele como visivel em cima de tudo, capturando o que estiver ali. Se for pra capturar soh coisas que acontecem dentro de uma janela AWT que vc tem controle, eh mais facil escutar a EventQueue - e tirar o screenshot sempre que um evento passar por ali :wink:

Acho que o legal seria vc minimizar esse JFrame e começar a mexer no Eclipse por exemplo. Daí o frame vai pegando tudo.

Mas concordo contigo, esse JFrame ficou sem utilidade. Não faz sentido para a pessoa que está capturando ver o que ela está capturando. Se não acaba virando espelho infinito.

Pô, tentei comprimir com ZIP e ficou ruim. Picos de 10 k por segundo. Fica muito pesado em termos de banda.

Vou dar uma olhada no VNC. Reinventar a roda dessa vez vai ser realmente loucura. :cry:

Acabei de ver tb que para cada pixel vc tem que enviar a posição e o valor, ou seja, o dobro de informações. :cry:

Que pena que o Swing não tem um esquema de permitir você amarrar um “hook” nas rotinas que você está chamando - ou teria se você mexesse em javax.swing.DebugGraphics?
(O fonte do Swing está disponível, mas você tem coragem de mexer nele?).
Senão dava para fazer uma coisa parecida com o RealVNC (ou o TightVNC usando um driver especial). Ou seja, em vez de ler a tela (uma operação lenta), a cada vez que o server executasse um comando do tipo drawString ou drawOval, por exemplo, enviasse para seus clientes (talvez usando UDP e multicast :wink: ) o comando drawString codificado, com os parâmetros…

Seria que não rola usar uma Toolkit wrapper?

Se o interesse é em fazer algo só para o Eclipse, já tentou ver se a API dele não oferece algo do gênero?

Queria fazer algo genérico que filmasse qualquer coisa na minha tela e transmitisse pela Internet, por isso que eu acho que esse esquemas de hook não me serve.

Pô, no final das contas eu quero passar um filme pela Internet, e isso é praticamente impossível devido as minhas limitações de banda, tanto no cliente, onde eu não exijo banda larga, tanto no servidor, onde tenho uma banda limitada.

Vou dar uma olhada no VNC de qualquer jeito, e tentar meter um MPEG em cima pra ver o que acontece. O ideal seria MPEG4, mas java ainda não suporta. Tem um tal de ffmpeg, mas está além das minhas forças entender aquilo.

Valeu pessoal pelas dicas!

Para ter uma ideia da qualidade que vai sair usando MPEG2/4, basta assistir matrix e tentar ler o shell quanto a Trinity executa um nmap na matrix http://www.insecure.org/nmap/nmap_inthenews.html.

:shock:
Eu héin?!

[quote=saoj]O programinha abaixo já te permite brincar de fazer um codec VNC.

Ele te fala quantos pixels estão mudando conforme vc brinca com a tela.

Se alguem fizer um codec de brincadeira, tipo um MPEG da vida e quiser me doar eu aceito. :stuck_out_tongue:

O objetivo e compremir esses bytes que estão mudando para eu poder jogar isso na rede.

>[/quote]

Eu fiz dois codecs de compressão de vídeo extremamente primitivos ao meu ver, mas que normalmente funcionam pelo que deu para mim testar.
A versão 1 e a versão 2 não são compatíveis entre si.
Ambos possuem suporte para frames codificados na forma de array de bytes, array de shorts e array de ints, só que usando-se arrays de shorts e arrays de ints, cada elemento do array precisa representar exatamente 1 pixel.
Para usar os codecs, basta chamar encodeFrame passando-se parâmetros e depois decodeFrame passando-se parâmetros.
O tamanho do vídeo e a paleta de cores deve se manter constante ou o codec pára de funcionar sem avisar.
Ambos os codecs também não suportam múltiplas threads.
Uma diferença entre os codecs é que a versão 2 usa compressão via análise de macroblocos 8x8, o que aumenta significativamente a compressão pelo que pude testar.
Ambos codecs não criam qualquer tipo de perda na qualidade da imagem (são “lossless”).
Ambos codecs são parte do código da minha solução de acesso remoto sob licença GPLv3 batizada como “Satan-AnyWhere” que devo lançar em algum momento.
Se der, gostaria de ser alertado caso os codecs apresentem algum erro.

Inté.

Parabéns!!!

Consegui, acho que praticamente implementei um quase-shell-remoto com um quase-VNC e outra coisas. Os meus amigos que testaram o Satan-AnyWhere afirmam que ele poderia se chamar JNetBus ou NetBus4J, devido a algumas funcionalidades remotas existentes nele. Aviso que o código do Satan-AnyWhere começou a ser desenvolvido a um bom tempo atrás, e pode muito bem ter diversas pérolas. Antes de sair usando ele, recomendo uma leitura ao arquivo “readme-pt-br.txt”, que é o único manual do Satan-AnyWhere que disponibilizo. A versão que estou disponibilizando no fórum não é uma versão definitiva de lançamento ainda. Para ligar o “modo VNC”, deve-se procurar no manual instruções sobre como inicializar o modo gráfico.

Por causa do limite de tamanho dos anexos, vou ter que disponibilizar o Satan-AnyWhere na forma de 5 volumes zip no fórum. Espero que esse aplicativo que desenvolvo sirva para alguma coisa.

Editado: Atualizei os anexos, pois haviam bugs em alguns módulos.

Inté.

Parte 2.

Inté.

Parte 3.

Inté.