不同分辨率的JavaFx应用程序中闪烁的白色屏幕
我们正在使用JavaFx和JavaCv开发视频流应用程序。 我们有8X8的网格窗格,每个单元格包含窗格布局和每个窗格 包含ImageView 每次我调用play函数时,只要用户将url拖到特定位置 牢房。 我们有64个url,所以我们调用play函数64次(所有64个url都在播放) 在后台线程中)不同分辨率的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(…)时,图像视图有很多工作要做(它必须调整图像的大小)。由于您有很多这样的情况发生,可能每个脉冲都
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();
}