/* * To change this template, choose Tools | Templates * and open the template in the editor. */ package webcamstudio.media.renderer; import java.io.BufferedOutputStream; import java.io.DataOutputStream; import java.io.IOException; import java.net.ServerSocket; import java.net.Socket; import java.net.SocketException; import java.util.logging.Level; import java.util.logging.Logger; import webcamstudio.mixers.AudioBuffer; import webcamstudio.mixers.Frame; import webcamstudio.mixers.ImageBuffer; import webcamstudio.mixers.MasterMixer; import webcamstudio.streams.Stream; import webcamstudio.util.Tools; /** * * @author patrick (modified by karl) */ public class Exporter implements MasterMixer.SinkListener { static Listener listenerEx = null; public static void setListenerEx(Listener l) { listenerEx = l; } private boolean cancel = false; private ServerSocket videoServer = null; private ServerSocket audioServer = null; private DataOutputStream videoOutput; private DataOutputStream audioOutput; private int aport = 0; private int vport = 0; private ImageBuffer imageBuffer = null; private AudioBuffer audioBuffer = null; private long vCounter = 0; private long aCounter = 0; private Stream stream = null; private Socket vConnection = null; private Socket aConnection = null; @SuppressWarnings("SocketException") public Exporter(Stream s) throws SocketException { this.stream = s; imageBuffer = new ImageBuffer(MasterMixer.getInstance().getWidth(),MasterMixer.getInstance().getHeight()); audioBuffer = new AudioBuffer(MasterMixer.getInstance().getRate()); if (!stream.isOnlyAudio()) { // stream.hasVideo() try { videoServer = new ServerSocket(0); videoServer.setReceiveBufferSize(32768); vport = videoServer.getLocalPort(); } catch (IOException ex) { Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } } if (stream.hasAudio()) { try { audioServer = new ServerSocket(0); audioServer.setReceiveBufferSize(32768); aport = audioServer.getLocalPort(); } catch (IOException ex) { Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } } // System.out.println("Port used is Video:" + vport+"/Audio:" + aport); if (!stream.isOnlyAudio()) { // stream.hasVideo() Thread vExCapture = new Thread(new Runnable() { @Override public void run() { try { vConnection = videoServer.accept(); System.out.println("Video output accepted"); videoOutput = new DataOutputStream(new BufferedOutputStream(vConnection.getOutputStream(), 4096)); imageBuffer.clear(); while (!cancel) { byte[] videoData = imageBuffer.pop().getBytes(); if (videoData == null || videoOutput == null) { Tools.sleep(30); } else { videoOutput.write(videoData); videoOutput.flush(); vCounter++; } } } catch (IOException ex) { cancel = true; if (imageBuffer != null){ imageBuffer.abort(); } stream.stop(); stream.updateStatus(); listenerEx.resetFMECount(); Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("Video output stopped"); } }); vExCapture.setPriority(Thread.MIN_PRIORITY); vExCapture.start(); } if (stream.hasAudio()) { //stream.hasVideo() Thread aExCapture = new Thread(new Runnable() { @Override public void run() { try { aConnection = audioServer.accept(); System.out.println("Audio output accepted"); audioOutput = new DataOutputStream(new BufferedOutputStream(aConnection.getOutputStream(), 4096)); audioBuffer.clear(); while (!cancel) { byte[] audioData = audioBuffer.pop(); if (audioData == null || audioOutput==null) { Tools.sleep(30); } else { audioOutput.write(audioData); if (audioOutput != null) { audioOutput.flush(); } aCounter++; } } } catch (IOException ex) { cancel = true; if (audioBuffer != null){ audioBuffer.abort(); } stream.stop(); stream.updateStatus(); // Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } System.out.println("Audio output stopped"); } }); aExCapture.setPriority(Thread.MIN_PRIORITY); aExCapture.start(); } cancel = false; MasterMixer.getInstance().register(this); } public void abort() { cancel = true; System.out.println("Output aborted..."); MasterMixer.getInstance().unregister(this); if (stream.hasVideo()) { if (imageBuffer != null) { imageBuffer.abort(); imageBuffer = null; // System.out.println("imageBuffer Aborted!"); } } if (stream.hasAudio()) { audioBuffer.abort(); audioBuffer = null; // System.out.println("audioBuffer Aborted!"); } System.out.println("V: " +vCounter); System.out.println("A: " +aCounter); if (videoServer != null && stream.hasVideo()) { try { videoServer.close(); if (videoServer!=null){ videoOutput.close(); videoOutput = null; videoServer = null; // System.out.println("Video Exporter Aborted!"); } } catch (IOException ex) { Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } } if (audioServer != null && stream.hasAudio()) { try { audioServer.close(); if (audioOutput!=null){ audioOutput.close(); audioOutput = null; audioServer = null; // System.out.println("Audio Exporter Aborted!"); } } catch (IOException ex) { Logger.getLogger(Exporter.class.getName()).log(Level.SEVERE, null, ex); } } } public int getAudioPort() { return aport; } public int getVideoPort() { return vport; } @Override public void newFrame(Frame frame) { if (stream.hasVideo()){ imageBuffer.push(frame.getImage()); } if (stream.hasAudio()){ audioBuffer.push(frame.getAudioData()); } } public interface Listener { public void resetFMECount(); } }