Package: camgrab
Python library to download images from network accessible webcams.FeaturesOut of the box, handles any webcam which provides a publically accessible URL
to a JPG snapshot of their current image.Easily swap in different downloaders to handle cams which expose their
snapshots in a more complex way.Highly configurable.Provides a simple base for more advanced functionality, such as motion
detection, CCTV systems, image analysis, etc.InstallationpipinstallcamgrabQuick startTo simply grabbing images from a webcam every 2 seconds and start saving them
to the defaultgrabbed_imagesdirectory:fromcamgrabimportGrabbergrabber=Grabber('http://www.masconcable.ca/webcams/chase.jpg')grabber.begin()ExamplesQuickly add a custom result handlerHere we create a custom result handler which will simply print the
dimensions of the grabbed image.The default result handlers (e.g.do_save_image()) will still be used.fromcamgrabimportGrabberurl='http://www.masconcable.ca/webcams/chase.jpg'defprint_dimensions(result,grabber):ifnotresult.get('image',None):returnwidth,height=result['image'].sizeprint('{width}pixels wide,{height}pixels high!'.format(width=width,height=height))grabber=Grabber(url,every=5,extra_result_handlers=(print_dimensions,))grabber.begin()More complex result handlingIn this example, we’ll take full control of the result handling, creating a
chain of result handlers to:resize the image to 320x200rotate the image by 90 degreessave the imageprint the final result dictionary to the terminalfromcamgrabimportGrabberfromcamgrab.camgrabimportdo_save_imageurl='http://www.masconcable.ca/webcams/chase.jpg'defresize_image(result,grabber):ifnotresult.get('image',None):returnresult['image']=result['image'].resize((320,200))defrotate_image(result,grabber):ifnotresult.get('image',None):returnresult['image']=result['image'].rotate(90)defprint_result(result,grabber):print(result)# Setting result_handlers attribute completely overrides any default result# handlers previously set. Hence making sure `do_save_image` (which is normally# a default handler) is in this tuple:result_handlers=(resize_image,rotate_image,do_save_image,print_result)grabber=Grabber(url,every=5)grabber.result_handlers=result_handlersgrabber.begin()Take control of the main loopIf the the main loop created by thebegin()method is too simple for your
needs, then either override thebegin()method or simply calltick()from
your own consumer.In this example, we consume a Grabber but define our own (not terribly useful)
main loop which waits a random amount of time between ticks:fromrandomimportrandomfromtimeimportsleepfromcamgrabimportGrabberurl='http://www.masconcable.ca/webcams/chase.jpg'grabber=Grabber(url)whileTrue:grabber.tick()# Wait somewhere between 0 and 10 secondssleep(random()*10)Error handlingGrabbing images from webcams is a messy business… They go offline loads, send
corrupted images, sometimes they randomly start sending Server 500 errors, etc.Because of all this, camgrab’s default settings make it pretty tolerant of
common errors which occur when grabbing an image. But this can be configured
easily enough.When an unhandled exception is raised during atick()which causes a crash,
the exception which caused the crash can be found in thefailed_exceptionattribute.HTTP errorsHTTP errors can be ignored or raised by settingignore_xxxattributes. For
example…By default HTTP 404 errors are not ignored by default. So when a 404 error
occurs the grabber will crash and you can handle the exception in whatever way
you want.fromurllib.errorimportHTTPErrorfromcamgrabimportGrabbergrabber=Grabber('http://www.masconcable.ca/webcams/chase.jpg')try:grabber.begin()exceptHTTPErrorase:ife.code==404:print('Was it something I said?')If you’d rather HTTP 404 errors didn’t cause a crash, then set theignore_404attribute:fromcamgrabimportGrabbergrabber=Grabber('http://www.masconcable.ca/webcams/chase.jpg')grabber.ignore_404=Truegrabber.begin()Now when a 404 error occurs, the Grabber will:add the exception to the result dictionaryset the image in the result dictionary toNoneAnd then continue its normal routine.By default, the following HTTP status codes are ignored:307, 400, 408, 409, 429, 444, 451, 499, 500, 502, 503, 504, 507, 599Network errorscamgrab ignores network errors by default. If you’d rather network timeouts
caused a crash, then just set theignore_timeoutattribute:fromsocketimporttimeoutfromurllib.errorimportURLErrorfromcamgrabimportGrabbergrabber=Grabber('http://www.masconcable.ca/webcams/chase.jpg')grabber.ignore_timeout=Falsetry:grabber.begin()exceptURLErrorase:ifisinstance(e.reason,timeout):print("It's me, not you")Licensecamgrab is free software, distributed under the MIT license.