不同分辨率的JavaFx应用程序中闪烁的白色屏幕

不同分辨率的JavaFx应用程序中闪烁的白色屏幕,java,multithreading,javafx,fxml,javacv,Java,Multithreading,Javafx,Fxml,Javacv,我们正在使用JavaFx和JavaCv开发视频流应用程序。 我们有8X8的网格窗格,每个单元格包含窗格布局和每个窗格 包含ImageView 每次我调用play函数时,只要用户将url拖到特定位置 牢房。 我们有64个url,所以我们调用play函数64次(所有64个url都在播放) 在后台线程中) for(int i=0;i这里只是一个猜测,但是当图像视图的大小与图像不同时,调用setImage(…)时,图像视图有很多工作要做(它必须调整图像的大小)。由于您有很多这样的情况发生,可能每个脉冲都

我们正在使用JavaFx和JavaCv开发视频流应用程序。 我们有8X8的网格窗格,每个单元格包含窗格布局和每个窗格 包含ImageView

每次我调用play函数时,只要用户将url拖到特定位置 牢房。 我们有64个url,所以我们调用play函数64次(所有64个url都在播放) 在后台线程中)


for(int i=0;i这里只是一个猜测,但是当图像视图的大小与图像不同时,调用
setImage(…)
时,图像视图有很多工作要做(它必须调整图像的大小)。由于您有很多这样的情况发生,可能每个脉冲都会发生,因此您可能会向
平台提交更多的Runnable。runLater(…)
无法处理(即,在从同一线程提交的上一个
平台完成之前,您提交另一个
平台。runLater(…)
)。这将导致渲染问题,因为渲染系统无法跟上

我无法对此进行测试,因此我不确定它是否能解决问题,但最好只在前一个调用完成后提交一个新调用到
Platform.runLater(…)
(即,即使不是问题的原因,也应该这样做)

你可以用它来做这个

void play(ImageView im,String Url){
    new Thread(() -> {
        frameGrabber = new FFmpegFrameGrabber(Url);
        frameGrabber.setVideoOption("preset","ultrafast");
        frameGrabber.setOption("rtsp_transport","tcp");
        frameGrabber.setOption("stimeout" , "60000");
        frameGrabber.setAudioChannels(0);
        frameGrabber.setAudioCodec(0);
        try {
            frameGrabber.start();
            start=true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        JavaFXFrameConverter jconverter=new JavaFXFrameConverter();

        AtomicReference<Image> imageHolder = new AtomicReference<>(null);
        while(true){
            Frame frame = frameGrabber.grabImage();
            Image image=jconverter.convert(frame);
            if (imageHolder.getAndSet(image) == null) {
                Platform.runLater(() -> im.setImage(imageHolder.getAndSet(null)));
            }
        }
    }).start();  
}

void play(ImageView im、原子引用边界、字符串Url){
新线程(()->{
frameGrabber=新的FFmpegFrameGrabber(Url);
frameGrabber.setVideoOption(“预设”、“超快”);
frameGrabber.setOption(“rtsp_传输”、“tcp”);
frameGrabber.setOption(“刺激”、“60000”);
frameGrabber.SetAudioChannel(0);
frameGrabber.setAudioCodec(0);
试一试{
frameGrabber.start();
开始=真;
}捕获(例外e){
e、 printStackTrace();
}
JavaFXFrameConverter jconverter=新的JavaFXFrameConverter();
AtomicReference imageHolder=新的AtomicReference(空);
while(true){
Frame Frame=frameGrabber.grabImage();
Bounds imgBounds=Bounds.get();
double width=imgBounds.getWidth();
double height=imgBounds.getHeight();
//将框架调整为宽度、高度。。。。
Image=jconverter.convert(帧);
if(imageHolder.getAndSet(image)==null){
Platform.runLater(()->im.setImage(imageHolder.getAndSet(null));
}
}
}).start();
}

<代码> 1。您可以修复代码以便编译它吗?2。您还可以检查调用“<代码>框架抓取器.Stand())/代码> 3时是否没有任何异常。当它处于“自然”分辨率(即图像视图与图像大小相同)时,是否看到空白屏幕?
void play(ImageView im,String Url){
    new Thread(() -> {
        frameGrabber = new FFmpegFrameGrabber(Url);
        frameGrabber.setVideoOption("preset","ultrafast");
        frameGrabber.setOption("rtsp_transport","tcp");
        frameGrabber.setOption("stimeout" , "60000");
        frameGrabber.setAudioChannels(0);
        frameGrabber.setAudioCodec(0);
        try {
            frameGrabber.start();
            start=true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        JavaFXFrameConverter jconverter=new JavaFXFrameConverter();

        AtomicReference<Image> imageHolder = new AtomicReference<>(null);
        while(true){
            Frame frame = frameGrabber.grabImage();
            Image image=jconverter.convert(frame);
            if (imageHolder.getAndSet(image) == null) {
                Platform.runLater(() -> im.setImage(imageHolder.getAndSet(null)));
            }
        }
    }).start();  
}
for(int i=0;i<8;i++){
    for(int j=0;j<8;j++){
        //grid08(8X8)
        Pane p=new Pane();
        AtomicReference<Bounds> bounds = new AtomicReference<>(p.getBoundsInLocal());
        p.boundsInLocalProperty().addListener((obs, oldBounds, newBounds) -> bounds.set(newBounds));
        ImageView im=new ImageView();
        Label l=new Label("");
        im.fitWidthProperty().bind(p.widthProperty());
        im.fitHeightProperty().bind(p.heightProperty());
        l.prefWidthProperty().bind(p.widthProperty());
        l.prefHeightProperty().bind(p.heightProperty());
        p.getChildren().addAll(im,l);
        l.setVisible(false);
        l.setStyle("-fx-text-fill: #fff; -fx-font-size: 12px");
        l.setAlignment(Pos.CENTER);
        p.setStyle("-fx-background-color: black;");
        grid.add(p,j,i);//grid->instance of gridPane
        p.setOnDragOver(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
                if(!l.isVisible()){
                    event.acceptTransferModes(TransferMode.ANY);
                }
            }
        });
        p.setOnDragDropped(new EventHandler<DragEvent>() {
            @Override
            public void handle(DragEvent event) {
               play(im,bounds,event.getDragboard().getString());
            }
        });
     }
 }
void play(ImageView im, AtomicReference<Bounds> bounds, String Url){
    new Thread(() -> {
        frameGrabber = new FFmpegFrameGrabber(Url);
        frameGrabber.setVideoOption("preset","ultrafast");
        frameGrabber.setOption("rtsp_transport","tcp");
        frameGrabber.setOption("stimeout" , "60000");
        frameGrabber.setAudioChannels(0);
        frameGrabber.setAudioCodec(0);
        try {
            frameGrabber.start();
            start=true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        JavaFXFrameConverter jconverter=new JavaFXFrameConverter();

        AtomicReference<Image> imageHolder = new AtomicReference<>(null);
        while(true){
            Frame frame = frameGrabber.grabImage();

            Bounds imgBounds = bounds.get();
            double width = imgBounds.getWidth();
            double height = imgBounds.getHeight();

            // resize frame to width, height....

            Image image=jconverter.convert(frame);

            if (imageHolder.getAndSet(image) == null) {
                Platform.runLater(() -> im.setImage(imageHolder.getAndSet(null)));
            }
        }
    }).start();  
}