如何将FFmpeg ffplay帧放入我自己的Java应用程序中



我正在从Parrot AR.Drone 2.0获得实时视频反馈。我能够从无人机(使用command-ffplay tcp://192.168.1.1:5555)获得传入视频流,并成功地为我输出实时视频。我注意到ffplay将显示自己的帧和直播视频。

那么,在应用程序中有可能"直接"或将框架放入我们自己的Java框架中吗?如果我想在我自己的JCheckBox中实现该功能,我该如何实现呢?例如,如果我点击JCheckBox,它应该自动从无人机获得实时视频流,并在应用程序中显示,而不是使用ffplay帧?

这个问题很老了,但是我刚刚发现它,所以我决定为其他用户写一个可能的解决方案。

有两种方法可以解决这个问题:为Java包装自己的FFmpeg CLI或使用包装的FFmpeg库。前者需要相当长的时间和努力才能实现。而后者更实用。

例如,一个很好的库是JavaCV。您只需要使用pom.xml文件将maven存储库添加到项目中:

<dependency>
  <groupId>org.bytedeco</groupId>
  <artifactId>javacv-platform</artifactId>
  <version>1.4.3</version>
</dependency>

然后你可以创建一个SimplePlayer类,并使用FFmpegFrameGrabber类解码一个帧,转换成一个图像,并显示在你的Java应用程序。

public class SimplePlayer
{
    private static volatile Thread playThread;
    private AnimationTimer timer;
    private int counter;
    public SimplePlayer(String source, GrabberListener grabberListener)
    {
        if (grabberListener == null) return;
        if (source.isEmpty()) return;
        counter = 0;
        playThread = new Thread(() -> {
            try {
                FFmpegFrameGrabber grabber = new FFmpegFrameGrabber(source);
                grabber.start();
                grabberListener.onMediaGrabbed(grabber.getImageWidth(), grabber.getImageHeight());

                Java2DFrameConverter converter = new Java2DFrameConverter();
                while (!Thread.interrupted()) {
                    Frame frame = grabber.grab();
                    if (frame == null) {
                        break;
                    }
                    if (frame.image != null) {
                        Image image = SwingFXUtils.toFXImage(converter.convert(frame), null);
                        Platform.runLater(() -> {
                            grabberListener.onImageProcessed(image);
                        });
                    }
                grabber.stop();
                grabber.release();
                Platform.exit();
            } catch (Exception exception) {
                System.exit(1);
            }
        });
        playThread.start();
    }
    public void stop()
    {
        playThread.interrupt();
    }
}

你可以在这个GitHub仓库中找到完整的实现。

您需要解码AR.Drone使用的几乎但不完全是H264视频格式。要做到这一点,您需要做两件事:

  1. 处理AR.Drone的自定义视频帧,它使用标题在他们的PaVE格式。该格式在AR.Drone开发者指南的7.3节中有文档记录,但是几乎所有现有的AR.Drone库都有处理PaVE头文件的代码。

  2. 解码剩余的H264视频帧。Xuggler用Java封装了本地库,这可能是解码H264的最好、最快的方法。另一种选择是h264j库,它是纯Java的,但速度较慢,并且有一些解码故障。

有关更多信息,请参阅以下相关问题:

Xuggler and playing from live stream

https://stackoverflow.com/questions/30307003/use-a-xuggler-videostream-in-javacv

相关内容

  • 没有找到相关文章

最新更新