Skip to content
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

How I reconnect the Webcam MJPEG #214

Closed
henriquem opened this issue May 7, 2014 · 5 comments
Closed

How I reconnect the Webcam MJPEG #214

henriquem opened this issue May 7, 2014 · 5 comments

Comments

@henriquem
Copy link

I'm using the WebcamDiscoveryListener's interface for knows if webcam (ip camera) was disconnected, using the method as example follow:

public void webcamGone(WebcamDiscoveryEvent event) {
System.out.format("Webcam disconnected: %s \n", event.getWebcam().getName());
}
But Before, I registered this camera ip by : IpCamDeviceRegistry.register(deviceIPCam);

Doubt:
When the Webcam disconnect how I can re-connect again ? I need to unregister (IpCamDeviceRegistry.unregister(....)) and register (IpCamDeviceRegistry.register(....) ) again into the method above ?

@sarxos
Copy link
Owner

sarxos commented May 7, 2014

Hi @henriquem,

Discovery service does not work for IP cameras in the same way as it does for UVC devices. The mechanism behind this feature is based on the list of webcam devices returned by the capture driver. For the IP cameras driver returns all devices which has been registered, and thus you will get one WebcamDiscoveryEvent for connection event after the register(..) has been invoked and the second one, for disconnection event after unregister(..).

Drivers which support discovery feature must implement WebcamDiscoverySupport interface. IP camera driver does not implement it since there is no standard mechanism which can be used to control if camera is online.

Because of the above, the IP camera registry automatically triggers discovery mechanism when you register and/or unregister device, so yes - to get the listener methods invoked you will have to invoke register(..) and unregister(..).

You can also try to implement your own mechanism to control if camera is online (e.g. using simple GET/HEAD request to the device URL). The idea would be to modify/extend IpCamDriver to track the status of cameras and filter the list returned by getDevices(..) method to exclude the ones which are offline.

Example:

public class MyIpCamDriver extends IpCamDriver implements WebcamDiscoverySupport, Runnable {

  Map<String, Boolean> online = new HashMap<>();

  // some thread to keep cameras status up-to-date

  public MyIpCamDriver() {
    Thread t = new Thread(this);
    t.setDaemon(true);
    t.start();
  }

  private boolean isOnline(WebcamDevice d) {
    // do something to check if camera is online - e.g. send GET or HEAD request
    return ...;
  }

  @Override
  public void run() {
    Thread.sleep(20 * 1000); // e.g. once per 20 seconds
    for (WebcamDevice d : IpCamDeviceRegistry.getIpCameras()) {
      online.put(d.getName(), isOnline(d));
    }
  }

  @Override
  public List<WebcamDevice> getDevices() {
    List<WebcamDevice> filtered = new ArrayList<>();
    for (WebcamDevice d : super.getDevices()) {
      Boolean ok = online.get(d.getName()); // note that boxed type is used here
      if (ok == null || ok.booleanValue()) {
        // ok is null which means that check has not been invoked for this device yet - assume it's online
        filtered.add(d); 
      }
    }
    return Collections.unmodifiableList(filtered);
  }
}

NOTE1! Please note that I wrote the above code just now, straight from my head and I never tested if it's working nor if it's syntactically correct. Feel free to use/modify it if you think this is the good way to go :)

If this will work fine we can consider adding permanent support for IP camera discovery feature. I'm open for all well written pull requests :D

@sarxos sarxos closed this as completed May 7, 2014
@henriquem
Copy link
Author

Thanks Sarxos!

Bellow I modified something but I follow your example, that was helpfully

I rewrite the IpCamDevice for reuse the method that send http to get the bufferedImage
I just change to public and create the method sendRequest HttpGet().

I don't know if is the good elegance at line:
for (WebcamDevice d : IpCamDeviceRegistry.getIpCameras())
But if you have another suggestion, it will welcome

I keep without know what I write at method getScanInterval and isScanPossible
from WebcamDiscoverySupport's interface. It is necessary ?

private boolean isOnline(WebcamDevice d) {
        List<IpCamDevice> ipCameras = IpCamDeviceRegistry.getIpCameras();
        for (IpCamDevice ipCamDevice : ipCameras) {
            if (ipCamDevice.getName().equalsIgnoreCase(d.getName())) {
                try {
                    ipCamDevice.sendRequestHttpGet();
                    return true;
                } catch (WebcamException webcx) {
                    return false;
                }
            }
        }
        return false;
    }

    @Override
    public void run() {
        while (true) {
            try {
                Thread.sleep(60 * 1000);
                for (WebcamDevice d : IpCamDeviceRegistry.getIpCameras()) {
                    online.put(d.getName(), isOnline(d));
                }
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    @Override
    public List<WebcamDevice> getDevices() {
        List<WebcamDevice> filtered = new ArrayList<>();
        for (WebcamDevice d : super.getDevices()) {
            Boolean ok = online.get(d.getName()); // note that boxed type is
                                                    // used here
            if (ok == null || ok.booleanValue()) {
                filtered.add(d);
            }
        }
        return filtered;
    }

    @Override
    public long getScanInterval() {
        return 0;
    }

    @Override
    public boolean isScanPossible() {
        return false;
    }

@sarxos sarxos reopened this May 18, 2014
@sarxos sarxos closed this as completed in addb80d Jun 11, 2014
@sarxos
Copy link
Owner

sarxos commented Jun 11, 2014

Hi @henriquem,

I added discovery support to IP camera driver. Feel free to test it :) These files needs to be used instead of the old ones:

Discovery support for IP camera is disabled by default (I didn't want to break backward compatibility), so you will have to enable it when setting new driver. This can be done by passing true and one of the arguments in IpCamDriver constructor:

static IpCamStorage storage = new IpCamStorage(...);
static {
  Webcam.setDriver(new IpCamDriver(storage, true)); // true = enable scanning
}

@settaratici
Copy link

Hello Sarxos!

Links are broken. Can you send new links,pls.

@sarxos
Copy link
Owner

sarxos commented Aug 5, 2014

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants