当前位置: 首页 > 面试题库 >

如何从Java应用程序中传输实时视频?

拓拔弘扬
2023-03-14
问题内容

我正在尝试找到流式传输Java应用程序中生成的实时视频的方法。该应用程序需要获取其自身的屏幕截图,并将其编码为视频流,然后发布该流。

到目前为止,我一直在使用Xuggler(FFMPEG之上的Java库)将屏幕截图编码为视频文件。这很好。Xuggler声称能够通过RTMP传输实时视频,但是我还没有找到任何有关如何以编程方式进行此操作的文档。

  1. 有谁知道如何以编程方式从Xuggler流式传输RTMP视频?
  2. 有人对我可以用来实现相同结果的其他库有建议吗?我希望通过RTP以MPEG2格式传输视频。

我确实在这里的Xuggler论坛上发现其他人在问一个非常类似的问题,但没有任何回应。

我研究了JMF,由于其他原因,它不是一个选择。


问题答案:
老实说,不要在JMF上浪费时间,您可以认为这已经死了。这是使用h.264对rtmp流进行屏幕截图的方法(此示例感谢tyreus@gmail.com)。如果代码未显示,请单击此处的pastebin: 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();
        }
    }


 类似资料:
  • 我有一个EXE,用python编写,然后将其转换为exe,当我运行exe direclty时,我可以在控制台实时看到输出,但当我在java中运行exe时,我看不到输出,直到exe完成过程。 我有在线搜索,但没有什么是工作,这里是示例代码。 公共类FaceAnalysis实现了AILibrary{私有静态最终记录器log=LoggerFactory.getLogger(FaceAnalysis.cl

  • 问题内容: 是否有使用Java直播视频的良好库?理想情况下,管道的两端都应使用Java编写,但我最关心的是视频播放器。您会推荐什么软件? 更新 :似乎VLC引入了1-2秒的延迟。我需要真正的实时视频流。记录到播放的延迟必须小于300ms。 问题答案: 我见过的最好的视频播放/编码库是ffmpeg。它播放您扔给它的所有内容。(它是MPlayer使用的。)它是用C编写的,但是我发现了一些Java包装器

  • 问题内容: 用代码退出Java应用程序的最佳方法是什么? 问题答案: 您可以用于此目的。 根据oracle的Java 8文档: 终止当前正在运行的Java虚拟机。参数用作状态码;按照惯例, 非零状态代码表示异常终止 。 此方法在类Runtime中调用exit方法。此方法永远不会正常返回。 该调用实际上等效于该调用:

  • 我用于处理和文件的一般java代码是: 我必须处理3.0版本的才能使用以下函数: parse-xml-fragment() 预期产出: 谁能提供一个解决方案吗?

  • 问题内容: 如何从Java应用程序中打开和关闭监视器? 如果您想知道为什么,这是一个自助服务终端样式的应用程序,晚上最好关闭显示器。是的,您可以在计算机的屏幕保护程序设置中执行此操作,但是最好以编程方式执行此操作,而不必在每台计算机上进行配置。 问题答案: 假设您在Windows上部署Java应用程序,则可以使用以下WIN32API函数: 然后,为调用上述功能的函数编写一个C-JNI小型包装器,并

  • 问题内容: 我尝试使用下面的代码来运行我从Apple脚本创建的独立实用程序应用程序,但是出现“无文件或目录不存在”错误。 我在项目,dist,父目录中放置了相同的副本(用于测试),但没有帮助。 因此,我的问题是:我对运行该应用程序的调用是否不好(也许是因为它不是Windows exe)?如何从Java运行Mac App? 谢谢 问题答案: Mac App Bunde不是可执行文件,而是具有特殊结构