调整VLCJ PixelWriter的大小

时间:2014-12-31 05:26:06

标签: java javafx vlcj

VLCJ的标准问题是如何获得JavaFX的可调整大小的视频....没有这个功能的原因是什么。我一直在为DAYS工作,任何帮助都将非常感谢....

            @Override
            public void display(DirectMediaPlayer mp, Memory[] memory, final BufferFormat bufferFormat) {
                final int renderFrameNumber = frameNumber.incrementAndGet();
                currentByteBuffer.set(memory[0].getByteBuffer(0,memory[0].size()));
                Platform.runLater(new Runnable() {
                    @Override
                    public void run() {
                        ByteBuffer byteBuffer = currentByteBuffer.get();
                        int actualFrameNumber = frameNumber.get();
                        if (renderFrameNumber == actualFrameNumber) {
                            canvas.getPixelWriter().setPixels(0, 0,
                                    bufferFormat.getWidth(),
                                    bufferFormat.getHeight(),
                                    byteBgraInstance, byteBuffer,
                                    bufferFormat.getPitches()[0]);
                        } else {
                            System.out.println("[FINE] "
                                    + " - Skipped late frame "
                                    + renderFrameNumber
                                    + " (actual = "
                                    + actualFrameNumber + ")");
                        }
                    }
                });
            }

我几乎可以获得原始大小的视频,但不能缩放或缩放以适应其他任何内容。有没有人有PixelWriter的经验,并且第二次将它复制到缩放的图像或任何东西?

2 个答案:

答案 0 :(得分:1)

不幸的是,使用vlcj的JavaFX方法需要所谓的"直接渲染"媒体播放器(正如您在问题中使用的那样)。

这个直接渲染媒体播放器使用LibVLC的视频渲染回调来为您的应用提供每帧视频,以便以任何合适的方式呈现。

本机API的工作方式是您必须首先提供回调以设置所需的视频缓冲区格式 - 这包括图片格式,但也包括视频缓冲区所需的宽度和高度。

视频开始播放之前调用此本机回调,并且再也不会(除非您停止视频播放并再次启动)。

显然,这意味着一旦播放开始,原生视频缓冲区尺寸就会固定,无法动态调整大小。

这回答了问题的第一部分,说明为什么功能不存在 - 基础本机库根本不支持它。

vlcj给你的是访问' raw'原生视频缓冲区,无论你使用BufferedImage,OGL Texture还是PixelWriter,它都取决于你想要渲染它的方式。如果您需要支持,您也可以自行决定如何扩展它。软件中的扩展当然会增加CPU负载。

关于你问题的第二部分,我不能提供更多建议。

与您的具体问题无关......但在查看您发布的代码后,我不确定您在那里的同步语义 - 在您的" run()"方法,没有什么我可以看到防止原生视频缓冲区被覆盖。 Java8所需的最新版本的vlcj-javafx演示项目使用新的本机缓冲区锁定/解锁方法,这些方法应该用于提供正确的同步。

答案 1 :(得分:0)

我一直在寻找这个问题,甚至尝试在我的代码中手动调整rgbBuffer的大小。但现在我有一种适合我的方法。

我没有使用Canvas,而是使用了ImageView,它更适合调整大小,因为它具有本机实现方式。我看到人们对图像上的PixelWriter的评论很慢,但那是很久以前或者他们的电脑只是很慢。我似乎没有任何问题(然而;));它对我来说足够快。

创建一个普通的Pane(或者最好是它的子类,然后在其中添加其余的代码)。可以使用常规代码调整此窗格的大小。

Pane内,添加ImageView并将其绑定到父窗格的宽度和高度。将WritableImage分配给ImageView,然后使用PixelWriter中的WritableImage为您的图片写入像素。

以下课程演示可调整大小的图像并获取PixelWriter

import javafx.scene.image.ImageView;
import javafx.scene.image.PixelWriter;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.Pane;

public class ResizableVlcPlayer extends Pane {

    private ImageView mImageView;
    private WritableImage mWritableImage;
    private PixelWriter mPixelWriter;

    public ResizableVlcPlayer() {
        mImageView = new ImageView();

        // this auto resizes the image when the pane resizes
        mImageView.fitWidthProperty().bind(widthProperty());
        mImageView.fitHeightProperty().bind(heightProperty());

        getChildren().add(mImageView);

        mWritableImage = new WritableImage(1280,720);
        mImageView.setImage(mWritableImage);

        mPixelWriter = mWritableImage.getPixelWriter();

        // Continue normal implementation by writing to the PixelWriter
    }
}