bakercp / ofxIpVideoGrabber

An openFrameworks addon for MJPEG streams (Axis IP Camera, mjpeg-streamer, etc.).
MIT License
104 stars 28 forks source link

Cannot connect to foscam F18918w w. basic auth or query string #23

Closed ashs-au closed 8 years ago

ashs-au commented 8 years ago

Hi, this could be a camera-compat. issue:

I'm running the test OF code that comes with your library in OF 0.8.4/ Xcode 6.1.1/OSX 10.9.5 - ofxIpVideoGrabber lib is the version aligned with this version of OF. The stock streams.xml work fine.

It's not working for my own IP cam (Foscam F18918w) though. When I try BASIC auth to my webcam, with a line like this: <stream name="ipcam" url="http://x.x.x.x/videostream.cgi" username="myname" password="mypass" /> in bin/streams.xml

Connection is failing with (in XCode debug output):

[ error ] IPVideoGrabber: Exception : [ipcam]: Exception: Invalid HTTP Reponse : Unauthorized

I've tried an alternate approach using a query string (replacing above element in streams.xml): url="http://x.x.x.x/videostream.cgi?user=myname&pwd=mypass"

& get the same error message. I've intercepted the request from the OF app and see that the '&' is being stripped from the query string,so that's a good reason for it to fail.

The above query string is all that's required in a browser etc to get a stream. This cam also works well with mawlib in Max/MSP.

Any advice on this would be greatly appreciated!

thx Ash

bakercp commented 8 years ago

Hey there, I think it's probably because the basic auth is commented out in the example. Your XML should be working ...

Try chancing the example code from:

    // initialize connection
    for (std::size_t i = 0; i < NUM_CAMERAS; i++)
    {
        IPCameraDef& cam = getNextCamera();

        std::shared_ptr<Video::IPVideoGrabber> c = std::make_shared<Video::IPVideoGrabber>();

        // if your camera uses standard web-based authentication, use this
        c->setUsername(cam.getUsername());
        c->setPassword(cam.getPassword());

        // if your camera uses cookies for authentication, use something like this:
        // c->setCookie("user", cam.username);
        // c->setCookie("password", cam.password);

        c->setCameraName(cam.getName());
        c->setURI(cam.getURL());
        c->connect(); // connect immediately

        // if desired, set up a video resize listener
        ofAddListener(c->videoResized, this, &ofApp::videoResized);

        grabbers.push_back(c);

    }

to

    // initialize connection
    for (std::size_t i = 0; i < NUM_CAMERAS; i++)
    {
        IPCameraDef& cam = getNextCamera();

        std::shared_ptr<Video::IPVideoGrabber> c = std::make_shared<Video::IPVideoGrabber>();

        // if your camera uses standard web-based authentication, use this
        // c->setUsername(cam.username);
        // c->setPassword(cam.password);

        // if your camera uses cookies for authentication, use something like this:
        // c->setCookie("user", cam.username);
        // c->setCookie("password", cam.password);

        c->setCameraName(cam.getName());
        c->setURI(cam.getURL());
        c->connect(); // connect immediately

        // if desired, set up a video resize listener
        ofAddListener(c->videoResized, this, &ofApp::videoResized);

        grabbers.push_back(c);

    }

I can't recall why that is commented out, because ... it should optionally add the pass / user from the xml if someone includes it. Right now it is reading in the user pass, but not configuring the camera with it :|

ashs-au commented 8 years ago

awesome - it's working great now - thanks! Although, in the example with the 0.9.3 code (in the zipped download) - the commented code is:

// c->setUsername(cam.username);
// c->setPassword(cam.password);

changing it to:

 c->setUsername(cam.getUsername());
 c->setPassword(cam.getPassword());

instantly works...

thx again Ash

bakercp commented 8 years ago

I cleaned this up a bit in the code. Still not perfect, but it's a little easier.