Как-то воскресным вечером я смотрел картинки, передаваемые с веб-камер, расположенных на Фарерских островах. Я слежу за погодой в этих местах, так как мы планируем семейную поездку по Фарерским островам, Исландии и Ирландии.
.
Сценарий GetWebJPG.vbs запускается с помощью хост-среды CScript WSH. Он создает выходную папку для хранения изображений с веб-камеры (если она еще не существует). После того как папка создана, сценарий посылает в веб-сервер запрос HTTP GET, чтобы получить очередной jpg-файл из камеры и сохранить его локально. Затем GetWebJPG.vbs ожидает следующего изображения. Каждому локально сохраненному файлу присваивается последовательный номер.
GetWebJPG.vbs обращается к веб-серверу через заданные интервалы времени, пока количество обращений не достигнет максимального значения, установленного константой MAXLOOP. Выполнение сценария останавливается, если происходит «фатальный» сбой (например, нарушается связь веб-сервера с Интернетом). Если перезапустить сценарий, выполнение возобновляется с последнего сохраненного файла.
Существует возможность распознавать или исключить из GetWebJPG.vbs ошибки различных типов. Например, выполнение сценария продолжается при распространенной ошибке 404 «not found», которая может быть следствием мелкого сбоя на сервере. Совсем ни к чему завершать работу сценария из-за единственного пропущенного файла. Меры для проверки ошибок в сценарии минимальны, но их можно расширить в зависимости от конкретных требований, игнорируя одни ошибки и останавливая сценарий при возникновении других.
Чтобы углубиться в GetWebJPG.vbs, просмотрите код в листинге 1. В сценарии указана рабочая веб-камера, и вы сможете получить jpg-файлы из единственного аэропорта на Фарерских островах. Как показано в листинге 2, сценарий получает копии jpg-файлов с веб-камеры, формируемые по адресу http://212.55.50.150/webcam/image.jpg. Новые jpg-файлы поступают через каждые 15 секунд в течение более 40 часов (10 000 циклов) и сохраняются в папке C:\WebShots. Каждому файлу присваивается последовательный номер начиная с FAE000001.jpg; поэтому следующие файлы будут иметь имена FAE000001.jpg, FAE000002.jpg, FAE000003.jpg и т. д.
Можно запустить несколько сценариев для веб-сервера и получать изображения с различных камер на нем. Например, чтобы запустить второй сценарий для сбора снимков со второй веб-камеры в аэропорту Фарерских островов, следует изменить значение константы WEBFILE на «webcam/image31.jpg», а константы PREFIX на «FAE2». Префиксы файлов с первой и второй веб-камер разные, поэтому изображения с обеих камер можно хранить в одной папке.
Выполнив в Интернете поиск по ключевым словам webcams или web cameras, можно найти другие сайты с веб-камерами. В частности, можно получить jpg-файлы с камеры на сайте Wiley Coyote (http://www.acmecoyote.com/wiley/cam/roadrunner.jpg). Предположим, нам нужно получать jpg-файл через каждые 30 секунд в течение 24 часов (2880 циклов) и сохранить изображения в папке D:\WebShots. Каждому файлу будет присвоен последовательный номер начиная с RR000001.jpg, поэтому следующие файлы будут иметь имена RR000001.jpg RR000002.jpg, RR000003.jpg и т. д. Для этого требуется изменить константы, показанные в листинге 3, а затем запустить сценарий. Обратите внимание, что сайта http://www.acmecoyote.com/wiley/cam/roadrunner.jpg в действительности не существует, поэтому запуская сценарий, необходимо заменить веб-камеру или использовать GetWebJPG.vbs в первоначальном виде.
Спустя 24 часа можно проверить изображения и выбрать все или некоторые из них для анимационного видеофильма. Обрезать изображения, вставляемые в фильм,
позволяет Microsoft Office Picture Manager (он входит в состав Microsoft Office).
- Откройте Microsoft Office Picture Manager и выберите команду Add Picture Shortcut из меню File. Перейдите к папке, содержащей jpg-файлы, выделите ее и нажмите кнопку Add.
- Выберите пункт Thumbnails в меню View, а затем Select All в меню Edit.
- Щелкните Edit Pictures, а затем выберите Crop в области Edit Pictures.
- Обрежьте первое изображение так, как нужно обрезать все изображения. Нажмите OK.
- Сохраните все изображения для анимационного видеофильма, выбрав пункт Save All в меню File.
Готовые файлы можно объединить в фильм с помощью привычного редактора изображений или видеоредактора. Я загрузил изображения и подготовил два фильма с использованием Windows Live Movie Maker (explore.live.com/windows-live-moviemaker).
В первом видеофильме события, произошедшие в аэропорту почти за три часа, сжаты в 18 секунд. В другом фильме показано, каким пустынным был аэропорт после извержения вулкана в Исландии весной 2010 г. Он также показывает, насколько переменчивой может быть погода в течение трех часов, сжатых до 23 секунд.
Сейчас на моем компьютере функционирует несколько сценариев, сохраняющих снимки с веб-камер на жестком диске. Нагрузка на процессор и оперативную память невелика, а результаты подчас потрясающие.
Харри Вердж — старший технолог крупной телекоммуникационной компании в Калгари. Отвечает за групповые политики Active Directory (AD), написание сценариев для большого количества компьютеров и поиск неисправностей
‘ ----------------------------------------------------------- ' HARRY VERGE - APR 2010 ' Scrape WebCam JPG picture to local computer. Gets JPG image file ' from web server and saves incremental copies to local computer. ' Tested on XPSP3 and Windows 7. ' To use with a proxy, you must first set the proxy connection. ' For more information, at a CMD prompt: ' In WINXP type 'PROXYCFG' ' In WIN7 type 'NETSH WINHTTP SET PROXY' ' ----------------------------------------------------------- ' You First need to modify the script so it knows what JPG to get ' from the web. ' For example, if the Web Cam image is generated at the URL ' http://www.acme-coyote.com/wiley/webcam/roadrunner.jpg then modify ' the following to reflect this: ' WEBROOT = "www.acme-coyote.com" ' WEBFILE = "wiley/webcam/roadrunner.jpg" ' Next, to save them to the local folder "D:\WebShots" with a new ' subfolder based on the WEBROOT shown above, modify the local ' computer save location as follows: ' DRIVE = "D:" ' DOWNLOADS = "WebShots" ' To specify a 30-second interval between each new file, modify ' the following: ' MAXSECONDS = 30 ' And last, to force a maximum number of times the script will loop ' before it exits, modify the following to your desired number. This ' example assumes 2 shots per minute for 24 hours: ' MAXLOOP = 2880 ' ----------------------------------------------------------- Option Explicit On Error Resume Next Const SCRIPTNAME = "Get WebCam Picture" Const SUCCESS = 0 Const ERROR = 1 Const MAXSECONDS = 15 ' Max seconds between picture copies. Const MAXLOOP = 10000 ' Max times to loop & copy picture. Const PREFIX = "FAE" ' Start saved pictures with this prefix. Const DRIVE = "C:" ' Drive letter forfolder. Const DOWNLOADS = "WebShots" ' Name of root folder. Const WEBROOT = "212.55.50.150" ' IP or DNS for Web Root. Const WEBFILE = "webcam/image.jpg" ' Path and name of image file on web server. Dim strFullWebURL, strMsgHead, strComputer, strLastOne, strMsgEvent, strNewFile Dim GetURLBinary Dim i, iCounter Dim objShell, objFSO, objWMIService, objFile, objHTTP, objStream, colFiles strFullWebURL = "http://" & WEBROOT & "/" & WEBFILE Set objFSO = CreateObject("Scripting.FileSystemObject") Set objShell = CreateObject("WScript.Shell") ' ----------------------------------------------------------- ' Force VBS to use Cscript instead of Wscript if not using it already: ' ----------------------------------------------------------- If Instr(1, WScript.FullName, «CScript», vbTextCompare) = 0 Then objShell.Run "cscript //nologo """ & WScript.ScriptFullName & """", 1, False WScript.Quit End If ' ----------------------------------------------------------- ' Build standard message header for event log and error message boxes: ' ----------------------------------------------------------- strMsgHead = vbcrlf & vbcrlf &_ "Script Name: " & vbtab & Wscript.ScriptName & vbcrlf &_ "Script Path: " & vbtab &_ Replace(Wscript.ScriptFullName, "\" & Wscript.ScriptName, "") & vbcrlf &_ "Get JPG From:" & vbtab & strFullWebURL & vbcrlf &_ "Save JPG to:" & vbtab & DRIVE & "\" & DOWNLOADS & "\" & WEBROOT & vbcrlf &_ "Save Interval:" & vbtab & "Every " & MAXSECONDS & " seconds." & vbcrlf & vbcrlf ' ----------------------------------------------------------- ' Create saved picture directory structure if not already there: ' ----------------------------------------------------------- If Not objFSO.FolderExists(DRIVE & "\" & DOWNLOADS) Then _ objFSO.CreateFolder(DRIVE & "\" & DOWNLOADS) If Err.Number <> 0 Then ErrorCheck If Not objFSO.FolderExists(DRIVE & "\" & DOWNLOADS & "\" & WEBROOT) Then _ objFSO.CreateFolder(DRIVE & "\" & DOWNLOADS & "\" & WEBROOT) If Err.Number <> 0 Then ErrorCheck ' ----------------------------------------------------------- ' Grab last picture saved in folder so we can build counter start value: ' ----------------------------------------------------------- strComputer = "." Set objWMIService = GetObject("winmgmts:" _ & "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2") Set colFiles = objWMIService. _ ExecQuery("Select * from CIM_DataFile where " &_ "Drive = '" & DRIVE & "' and " &_ "Path = '\\" & DOWNLOADS & "\\" & WEBROOT & "\\' and " &_ "FileName like '" & PREFIX & "%' ") For Each objFile in colFiles strLastOne = Mid(objFile.FileName, Len(PREFIX)+1, Len(objFile.FileName)-Len(PREFIX)) Next If strLastOne = "" Then iCounter = 0 strMsgEvent = "Script Started at " & Now() & "." Else iCounter = strLastOne strMsgEvent = "Script Started at " & Now() & ". Continuing from picture " &_ PREFIX & iCounter & ".JPG." End If ' ----------------------------------------------------------- ' Show start, write to App Event Log, then begin main processing loop: ' ----------------------------------------------------------- Wscript.Echo SCRIPTNAME & vbcrlf &_ "Script Started at " & Now() &_ ". Saving picture every " & MAXSECONDS & " seconds." & vbcrlf objShell.LogEvent SUCCESS, SCRIPTNAME & strMsgHead & strMsgEvent For i = 1 to MAXLOOP ' --------------------------------------------------------- ' Send off web request: ' --------------------------------------------------------- Set objHTTP = CreateObject("WinHttp.WinHttpRequest.5.1") objHTTP.Open "GET", strFullWebURL, False Err.Clear objHTTP.Send If Err.Number <> 0 Then ErrorCheck GetURLBinary = objHTTP.ResponseBody If Not objHTTP.Status = 200 Then ErrorHTTP ‘ --------------------------------------------------------- ' Save download as JPG binary: ' --------------------------------------------------------- Err.Clear iCounter = iCounter + 1 iCounter = Right("000000" & iCounter, 6) ' Build in leading zeroes. Increase mask if needed. strNewFile = DRIVE & "\" & DOWNLOADS & "\" & WEBROOT & "\" & PREFIX & iCounter & ".JPG" Set objStream = CreateObject("ADODB.Stream") objStream.Type = 1 ' Set ADODB Stream as binary objStream.Open objStream.Write GetURLBinary objStream.SaveToFile strNewFile, 2 ' Overwrite file if it exists objStream.Close If Err.Number <> 0 Then ErrorCheck ' --------------------------------------------------------- ' Show progress in console window, then sleep until next interval: ' --------------------------------------------------------- Wscript.Echo Now() & ": Wrote " & strNewFile Set objStream = Nothing Set objHTTP = Nothing If i = MAXLOOP Then Exit For WScript.Sleep(MAXSECONDS * 1000) Next ' ----------------------------------------------------------- ' Outside loop? Then the MAXLOOP limit was reached: ' ----------------------------------------------------------- strMsgEvent = "Maximum [" & MAXLOOP & "] reached. End of script. " &_ "Last picture was " & PREFIX & iCounter & ".JPG" objShell.LogEvent SUCCESS, SCRIPTNAME & strMsgHead & strMsgEvent Wscript.Echo vbcrlf & Now() & ": Maximum [" & MAXLOOP & "] reached. End of script." ‘ ----------------------------------------------------------- ‘ Error Handlers: ' ----------------------------------------------------------- Sub ErrorCheck() strMsgEvent = "ERROR:" & vbcrlf & vbcrlf &_ "Number:" & vbtab & vbtab & Err.Number & vbcrlf &_ "Description:" & vbtab & Err.Description If Err.Number = 71 Then strMsgEvent = strMsgEvent & vbcrlf & vbcrlf &_ "Most likely reason is you do not have a '" & DRIVE & "' drive. " ShowError Wscript.Quit End If If Err.Number = -2147012867 Then strMsgEvent = strMsgEvent & vbcrlf & vbcrlf &_ "Most likely reason(s): Server is down, or you are using a proxy connection. " ShowError Wscript.Quit End If ShowError End Sub Sub ErrorHTTP() strMsgEvent = vbcrlf & vbcrlf &_ "Error getting file." & vbcrlf & vbcrlf &_ "Web URL:" & vbtab & strFullWebURL & vbcrlf &_ "Server Response:" & vbtab & objHTTP.status &_ " [" & objHTTP.StatusText & "]" If objHTTP.status = 404 Then strMsgEvent = strMsgEvent & vbcrlf & vbcrlf &_ "Likely reason is Web Server is working, but URL could not be found. " End If ShowError End Sub Sub ShowError() objShell.LogEvent ERROR, SCRIPTNAME & strMsgHead & strMsgEvent Wscript.Echo Now() & ": ERROR " & strMsgEvent ' --------------------------------------------------------- ' Modify/Enable/Disable this optional escape from script: ' --------------------------------------------------------- ' If Not Err.Number = 3001 Then ' MsgBox SCRIPTNAME & vbcrlf & vbcrlf & strMsgEvent, vbCritical, "ERROR" ' Wscript.Quit ' End If End Sub
Const WEBFILE = "webcam/image.jpg" Const MAXSECONDS = 15 Const MAXLOOP = 10000 Const DRIVE = "C:" Const DOWNLOADS = "WebShots" Const PREFIX = "FAE"
Const WEBROOT = "www.acmecoyote.com" Const WEBFILE = "wiley/cam/roadrunner.jpg" Const MAXSECONDS = 30 Const MAXLOOP = 2880 Const DRIVE = "D:" Const DOWNLOADS = "WebShots" Const PREFIX = "RR"