-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Receiving EOFException for no reason #131
Comments
Hi, Thank you for the report and your support :) At the first glance I suppose this can be a race between Regarding your code sample I have some suggestions / warnings: Auto-Open ModeTry avoiding auto-open mode whenever this is possible, and especially when you are working in multi-threaded environment (e.g. GUI application, etc). Therefore, I would strongly suggest you to change this: webcam = Webcam.getDefault();
// automatically open if webcam is closed
Webcam.setAutoOpenMode(true);
// set webcam resolution to 320x240
webcam.setViewSize(new Dimension(320, 240)); Into this: webcam = Webcam.getDefault();
webcam.setViewSize(new Dimension(320, 240));
webcam.open(); Unlocking WebcamThe public void start() throws Exception {
if (webcam != null) {
// webcam has already been set, please connect and start it
return;
}
webcam = Webcam.getDefault();
if (webcam.isOpen()) {
// webcam has already been started, ignore call
return;
}
WebcamLock lock = webcam.getLock();
int i = 0;
do {
if (!lock.isLocked()) {
break;
}
Thread.sleep(1000);
} while (i++ < 4); // wait max 4 seconds for lock to be released
if (lock.isLocked()) {
throw new RuntimeException("There is other JVM process using this camera via Webcam Capture API, make sure to close it first");
}
webcam.setViewSize(new Dimension(320, 240));
webcam.open();
} Creating Webcam PanelI see that you are creating new Device NameInstead of setting artificial name, you can use name from camera device (with or without additional modifications): public String getName() throws Exception {
return webcam.getName();
} |
I refined your code a little bit to perform various simplifications. Hope you don't mind. import java.awt.Dimension;
import java.util.concurrent.atomic.AtomicBoolean;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamResolution;
public class WebCamera implements Device {
private String type = "WebCam";
private Webcam webcam;
private Dimension displaySize = WebcamResolution.QQVGA.getSize();
private AtomicBoolean started = new AtomicBoolean(false);
public ValueObject readVariable(String channel) throws Exception {
if (!started.get()) {
throw new RuntimeException("WebCamera has not been started");
}
return new ValueObject(webcam.getImage());
}
public void writeVariable(String channel, ValueObject value) throws Exception {
throw new Exception("Cannot Write To WebCam; Can Only Read");
}
public void start() throws Exception {
if (started.compareAndSet(false, true)) {
if ((webcam = Webcam.getDefault()) == null) {
throw new RuntimeException("No webcam connected to the PC, make sure to connect it first");
}
webcam.setViewSize(displaySize);
webcam.open();
if (!webcam.isOpen()) {
started.set(false);
throw new RuntimeException("Cannot open the webcam, check debug log for details");
}
}
}
public void stop() throws Exception {
if (started.compareAndSet(true, false)) {
webcam.close();
}
}
public String getType() throws Exception {
return type;
}
public String getName() throws Exception {
return webcam.getName();
}
} |
Webcam Capture JAR file with the above fix can be found here: Please replace it with the one you are using currently and let me know if problem still persist. |
Thank for your suggestions regarding my code sarxos. I will try to modify mine according to that soon as I get the webcam working again. For now, do I need to make any code changes for that new jar file to work? Or should it work with the code that I have? It's still not working unfortunately. Same error. So, the problem still persists. Please let me know what else can be done. Thank you,
|
"At the first glance I suppose this can be a race between read() and write() methods of WebcamLock, especially since read() which gives you this exception is not synchronized. I made appropriate code change and will push them to the repository." Actually, I don't think that's what's causing the problem. I just tried removing EVERYTHING from the readVariable(channel) method other than the "image = webcam.getImage();" line and "return new ValueObject(image);" line and the problem still persists. As you can see, I only let the read() part of Webcam stay in there and nothing else and the problem is still there. So I think the problem is something else. And again, I have to mention that the same exact code was working perfectly. This problem cam up all of a sudden for no reason. That's what is most confusing to me. Thanks for trying to help out. |
Here's more information: I ran the "TakePictureExample.java" file as a completely new project by itself and even that gave me the EOF exception at the "BufferedImage image = Webcam.getDefault().getImage();" line. This file was working fine earlier too. So this suggests that the problem is not with the code but something very fundamental. |
Hi, Yes, after you mentioned about this problem appeared suddenly, and everything was fine before than happen, I realised one other possible cause. The webcam lock is created every time when specific webcam is open, but since it resides in system temporary directory, and always have the same name, I thought it's not necessary to remove it. Lock file should contain 8 bytes, but if the actual number of bytes in this file is less, the To confirm above I performed a small experiment. I damaged webcam lock file and tried to start program again. The effect was exactly the same as in your case:
The below code fragment will remove all lock files and fix the problem. Just make sure you have webcam connected to the PC. I tested it on my environment and it fixed the issue, but I'm on Ubuntu Linux, so please let me know if it's working in your case. public static void main(String[] args) throws IOException {
List<Webcam> webcams = Webcam.getWebcams();
File tmp = File.createTempFile("abc", "xyz");
for (Webcam webcam : webcams) {
File lock = new File(tmp.getParentFile(), String.format(".webcam-lock-%d", Math.abs(webcam.getName().hashCode())));
if (lock.exists() && !lock.delete()) {
lock.deleteOnExit();
}
}
if (!tmp.delete()) {
tmp.deleteOnExit();
}
} You can also remove them manually, but this can be harder, so above suggestion is a better approach:
I will fix this in the source code ASAP, so problem with lock file will simply remove it and then re-create, instead of crashing whole application. Thank you for your support and time you spent on this issue! BR |
It's working now. Excellent. Thank you very much. But I would also like to resolve a minor problem.
Then I get this: Webcam Logitech HD Webcam C270 0 has already been locked Clearly the webcam is not being used by any other application. And I even wait for more than 2 seconds but it still keeps giving the same message. When I freshly open up my GUI application and read, it works fine. But when I disconnect..connect and then read it..that's when it keeps giving that message. This is the reason why I used the following code within my readVariable(channel) method: // unlock webcam if it's locked This used to actually unlock the webcam but suddenly, it's not doing the job anymore. So I want to ask you: Could you change anything in the source code (at least just for me) so that the webcam doesn't get locked at all? It's very troubling to my application that I'm working on. It would be very helpful. Thanks again for everything sarxos. |
Sure! I never expected that locking mechanism will introduce such kind of issues, so it's good to have some turn-off switch which will disable it completely. With the newest code from HEAD you can do that for specific webcam by calling: Webcam w = Webcam.getDefault();
w.getLock().disable();
// do other great things Due to my regular job work load I do not have much free time now, but I will try to investigate this locking issues much deeper ASAP. Especially the ones you mentioned:
The newest SNAPSHOT Webcam Capture JAR, which contains fix for you, can be found here: Please let me know if it's working fine. |
It's working fine. But what's happening is: everytime I click the button which runs the readVariable(channel) method, it displays the image that was read from my last click. It's basically an image behind. This seems to be like a side effect of this update (which has successfully helped me disable the lock). Please look into why that's happening. Thank you very much. |
The other jar also did that initially. And when I added "WebcamPanel panel = new WebcamPanel(webcam, displaySize, false);" in between my readVariable(channel) method, it was returning the right image upon the button click. But with this jar, even with that webcampanel line in the middle, it's not returning the right image upon the button click. May be that gives you a hint about why it's happening now. |
I suppose that's because the webcam or native API has some kind of ring buffer which holds 4 last frames. The default driver is very simple and fetch new frame on-demand, when user calls To be honest I was not aware of this issue with default driver till now (I thought that every image is "fresh"). I suppose, but would have to check to be 100% sure, that this specific case is not observable on Windows since DirectShow API is updating buffer in background. Ok, that's should be enough for the explanation - the w/a for this issue is very simple - use non-blocking mode: webcam.open(true); Instead of: webcam.open(); It's much better than instantiating new I will try to find some long term solution for this, but it can be pretty rough when thread-safety must be considered - for Linux / Mac OS only there would be no problem, but the simplest solution (e.g. simple parallel thread) will crash JVM on Windows due to SIGSEGV in native, or it will not be able to fetch image at all. |
I've just pushed small fix to update buffer in background, but will need to verify it on Windows to make sure that natives will not crash JVM. |
The newest Webcam Capture JAR, containing above fix, can be found here: |
Hello,
First off, thank you for this great library. Secondly, before I present to you the problem I'm having, I would just like to say that, if you could help me solve this problem, I promise that I will donate at least $25 through paypal.
I'm pasting my code for a Webcam class I made for my project using your library here. In case the formatting gets messed up, I'm also attaching a notepad file with the class code.
The issue I'm having is this: I'm calling the readVariable(channel) method from a different class. The application is getting tripped up at the parts where the webcam has to read. Specifically, it's throwing an EOFException at the "if (webcam.getLock().isLocked()) " part. I took that part out to see if that code is the problem and then it threw the EOFException at the next piece of code where the webcam has to read, which happens to be the "image = webcam.getImage();" line. The catch is that, the same code was working perfectly up until some arbitrarily random point. The code that is below, I believe is the same code which was working fine. And suddenly, it started throwing these EOFExceptions. Any idea how I could solve this problem? I would immensely appreciate it. Everything was going extremely smooth this happened and the webcam now doesn't seem to be able to read anything at all.
Please feel free to contact me back if you need more details any way you want:
e-mail: parchaashwin@gmail.com
phone: 732-207-6408
or any other way
Here's the error stacktrace in full:
---------------------------------------CODE---------------------------------------------
The text was updated successfully, but these errors were encountered: