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的经验,并且第二次将它复制到缩放的图像或任何东西?
答案 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
}
}