2010-07-09 32 views
13

Estoy tratando de encontrar formas de transmitir un video en vivo generado en una aplicación Java. La aplicación necesita tomar capturas de pantalla de sí misma y codificarlas en una transmisión de video y publicar la transmisión.¿Cómo transmitir video en vivo desde una aplicación Java?

Hasta ahora he estado usando Xuggler (una biblioteca de Java encima de FFMPEG) para codificar las capturas de pantalla en un archivo de video. Esto funciona genial Xuggler afirma ser capaz de transmitir video en vivo a través de RTMP, pero no he encontrado ninguna documentación sobre cómo hacerlo mediante programación.

  1. ¿Alguien sabe cómo transmitir video RTMP programáticamente desde Xuggler?
  2. ¿Alguien tiene alguna sugerencia sobre otras bibliotecas que podría utilizar para lograr los mismos resultados? Prefiero transmitir el video en MPEG2 a través de RTP.

Encontré a alguien más haciendo una pregunta muy similar en los foros de Xuggler here sin respuesta.

He investigado sobre JMF y no es una opción por otros motivos.

Respuesta

20

Honestamente, no pierdas tu tiempo con JMF, puedes considerar que ofrecer muertos. Aquí se explica cómo realizar capturas de pantalla en una transmisión rtmp utilizando h.264 (gracias a [email protected] por ejemplo). Si el código no se presenta aquí está Pastebin para ello: http://pastebin.com/sJHwj0nW

import com.xuggle.xuggler.Configuration; 
import com.xuggle.xuggler.ICodec; 
import com.xuggle.xuggler.IContainer; 
import com.xuggle.xuggler.IContainerFormat; 
import com.xuggle.xuggler.IPacket; 
import com.xuggle.xuggler.IPixelFormat; 
import com.xuggle.xuggler.IRational; 
import com.xuggle.xuggler.IStream; 
import com.xuggle.xuggler.IStreamCoder; 
import com.xuggle.xuggler.IVideoPicture; 
import com.xuggle.xuggler.video.ConverterFactory; 
import com.xuggle.xuggler.video.IConverter; 
import java.awt.AWTException; 
import java.awt.Rectangle; 
import java.awt.Robot; 
import java.awt.image.BufferedImage; 
import java.io.IOException; 
import java.io.InputStream; 
import java.util.Properties; 

public class XugglerRtmpReferenceImpl { 

    private static String url = "rtmp://your.test.server/screen/"; 
    private static String fileName = "test/teststream"; 
    private static int framesToEncode = 60; 
    private static int x = 0; 
    private static int y = 0; 
    private static int height = 480; 
    private static int width = 640; 

    public static void main(String[] args) { 
     IContainer container = IContainer.make(); 
     IContainerFormat containerFormat_live = IContainerFormat.make(); 
     containerFormat_live.setOutputFormat("flv", url + fileName, null); 
     container.setInputBufferLength(0); 
     int retVal = container.open(url + fileName, IContainer.Type.WRITE, containerFormat_live); 
     if (retVal < 0) { 
      System.err.println("Could not open output container for live stream"); 
      System.exit(1); 
     } 
     IStream stream = container.addNewStream(0); 
     IStreamCoder coder = stream.getStreamCoder(); 
     ICodec codec = ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_H264); 
     coder.setNumPicturesInGroupOfPictures(5); 
     coder.setCodec(codec); 
     coder.setBitRate(200000); 
     coder.setPixelType(IPixelFormat.Type.YUV420P); 
     coder.setHeight(height); 
     coder.setWidth(width); 
     System.out.println("[ENCODER] video size is " + width + "x" + height); 
     coder.setFlag(IStreamCoder.Flags.FLAG_QSCALE, true); 
     coder.setGlobalQuality(0); 
     IRational frameRate = IRational.make(5, 1); 
     coder.setFrameRate(frameRate); 
     coder.setTimeBase(IRational.make(frameRate.getDenominator(), frameRate.getNumerator())); 
     Properties props = new Properties(); 
     InputStream is = XugglerRtmpReferenceImpl.class.getResourceAsStream("/libx264-normal.ffpreset"); 
     try { 
      props.load(is); 
     } catch (IOException e) { 
      System.err.println("You need the libx264-normal.ffpreset file from the Xuggle distribution in your classpath."); 
      System.exit(1); 
     } 
     Configuration.configure(props, coder); 
     coder.open(); 
     container.writeHeader(); 
     long firstTimeStamp = System.currentTimeMillis(); 
     long lastTimeStamp = -1; 
     int i = 0; 
     try { 
      Robot robot = new Robot(); 
      while (i < framesToEncode) { 
       //long iterationStartTime = System.currentTimeMillis(); 
       long now = System.currentTimeMillis(); 
       //grab the screenshot 
       BufferedImage image = robot.createScreenCapture(new Rectangle(x, y, width, height)); 
       //convert it for Xuggler 
       BufferedImage currentScreenshot = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); 
       currentScreenshot.getGraphics().drawImage(image, 0, 0, null); 
       //start the encoding process 
       IPacket packet = IPacket.make(); 
       IConverter converter = ConverterFactory.createConverter(currentScreenshot, IPixelFormat.Type.YUV420P); 
       long timeStamp = (now - firstTimeStamp) * 1000; 
       IVideoPicture outFrame = converter.toPicture(currentScreenshot, timeStamp); 
       if (i == 0) { 
        //make first frame keyframe 
        outFrame.setKeyFrame(true); 
       } 
       outFrame.setQuality(0); 
       coder.encodeVideo(packet, outFrame, 0); 
       outFrame.delete(); 
       if (packet.isComplete()) { 
        container.writePacket(packet); 
        System.out.println("[ENCODER] writing packet of size " + packet.getSize() + " for elapsed time " + ((timeStamp - lastTimeStamp)/1000)); 
        lastTimeStamp = timeStamp; 
       } 
       System.out.println("[ENCODER] encoded image " + i + " in " + (System.currentTimeMillis() - now)); 
       i++; 
       try { 
        Thread.sleep(Math.max((long) (1000/frameRate.getDouble()) - (System.currentTimeMillis() - now), 0)); 
       } catch (InterruptedException e) { 
        e.printStackTrace(); 
       } 
      } 
     } catch (AWTException e) { 
      e.printStackTrace(); 
     } 
     container.writeTrailer(); 
    } 
} 
+0

mucho que lo intentaba, yo supongo que es demasiado largo para un bloque de código. –

+2

Gracias. Esto me ayudó apuntando en la dirección correcta. – Tansir1

+0

Is xuggler transmite video desde la cámara y el micrófono en vivo –

Cuestiones relacionadas