iterate and remove faulty capture devices on opening qr scan dialog

This commit is contained in:
Craig Raw 2025-05-29 13:58:46 +02:00
parent 4298bfb053
commit 74c298fd93
2 changed files with 32 additions and 17 deletions

View file

@ -122,19 +122,21 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
if(percentComplete.get() <= 0.0) {
Platform.runLater(() -> percentComplete.set(opening ? 0.0 : -1.0));
}
});
if(opening) {
webcamService.openedProperty().addListener((_, _, opened) -> {
if(opened) {
Platform.runLater(() -> {
try {
postOpenUpdate = true;
List<CaptureDevice> newDevices = new ArrayList<>(webcamService.getDevices());
List<CaptureDevice> newDevices = new ArrayList<>(webcamService.getAvailableDevices());
newDevices.removeAll(foundDevices);
foundDevices.addAll(newDevices);
foundDevices.removeIf(device -> !webcamService.getDevices().contains(device));
if(Config.get().getWebcamDevice() != null && webcamDeviceProperty.get() == null) {
if(webcamService.getDevice() != null) {
for(CaptureDevice device : foundDevices) {
if(device.getName().equals(Config.get().getWebcamDevice())) {
if(device.equals(webcamService.getDevice())) {
webcamDeviceProperty.set(device);
}
}
@ -146,10 +148,7 @@ public class QRScanDialog extends Dialog<QRScanDialog.Result> {
postOpenUpdate = false;
}
});
}
});
webcamService.closedProperty().addListener((_, _, closed) -> {
if(closed && webcamResolutionProperty.get() != null) {
} else if(webcamResolutionProperty.get() != null) {
webcamService.setResolution(webcamResolutionProperty.get());
webcamService.setDevice(webcamDeviceProperty.get());
Platform.runLater(() -> {

View file

@ -35,12 +35,13 @@ public class WebcamService extends ScheduledService<Image> {
private static final Logger log = LoggerFactory.getLogger(WebcamService.class);
private List<CaptureDevice> devices;
private List<CaptureDevice> availableDevices;
private Set<WebcamResolution> resolutions;
private WebcamResolution resolution;
private CaptureDevice device;
private final BooleanProperty opening = new SimpleBooleanProperty(false);
private final BooleanProperty closed = new SimpleBooleanProperty(false);
private final BooleanProperty opened = new SimpleBooleanProperty(false);
private final ObjectProperty<Result> resultProperty = new SimpleObjectProperty<>(null);
@ -106,23 +107,26 @@ public class WebcamService extends ScheduledService<Image> {
@Override
protected Image call() throws Exception {
try {
if(stream == null) {
if(devices == null) {
devices = capture.getDevices();
availableDevices = new ArrayList<>(devices);
if(devices.isEmpty()) {
throw new UnsupportedOperationException("No cameras available");
}
}
CaptureDevice selectedDevice = devices.stream().filter(d -> !d.getFormats().isEmpty()).findFirst().orElse(devices.getFirst());
while(stream == null && !availableDevices.isEmpty()) {
CaptureDevice selectedDevice = availableDevices.stream().filter(d -> !d.getFormats().isEmpty()).findFirst().orElse(availableDevices.getFirst());
if(device != null) {
for(CaptureDevice webcam : devices) {
for(CaptureDevice webcam : availableDevices) {
if(webcam.getName().equals(device.getName())) {
selectedDevice = webcam;
}
}
} else if(Config.get().getWebcamDevice() != null) {
for(CaptureDevice webcam : devices) {
for(CaptureDevice webcam : availableDevices) {
if(webcam.getName().equals(Config.get().getWebcamDevice())) {
selectedDevice = webcam;
}
@ -170,15 +174,23 @@ public class WebcamService extends ScheduledService<Image> {
opening.set(true);
stream = device.openStream(format);
opening.set(false);
closed.set(false);
try {
zoomLimits = stream.getPropertyLimits(CaptureProperty.Zoom);
} catch(Throwable e) {
log.debug("Error getting zoom limits on " + device + ", assuming no zoom function");
}
if(stream == null) {
availableDevices.remove(device);
}
}
if(stream == null) {
throw new UnsupportedOperationException("No usable cameras available, tried " + devices);
}
opened.set(true);
BufferedImage originalImage = stream.capture();
CroppedDimension cropped = getCroppedDimension(originalImage);
BufferedImage croppedImage = originalImage.getSubimage(cropped.x, cropped.y, cropped.length, cropped.length);
@ -211,7 +223,7 @@ public class WebcamService extends ScheduledService<Image> {
public boolean cancel() {
if(stream != null) {
stream.close();
closed.set(true);
opened.set(false);
}
return super.cancel();
@ -336,6 +348,10 @@ public class WebcamService extends ScheduledService<Image> {
return devices;
}
public List<CaptureDevice> getAvailableDevices() {
return availableDevices;
}
public Set<WebcamResolution> getResolutions() {
return resolutions;
}
@ -376,8 +392,8 @@ public class WebcamService extends ScheduledService<Image> {
return opening;
}
public BooleanProperty closedProperty() {
return closed;
public BooleanProperty openedProperty() {
return opened;
}
public static <T extends Enum<T>> T getNearestEnum(T target) {