Skip to content

Instantly share code, notes, and snippets.

@jl2
Last active December 16, 2015 14:29
Show Gist options
  • Select an option

  • Save jl2/5449387 to your computer and use it in GitHub Desktop.

Select an option

Save jl2/5449387 to your computer and use it in GitHub Desktop.
Create movie files from Arapahoe Basin's webcams.
/*
* basincam.cpp
* Copyright (c) 2013, Jeremiah LaRocco [email protected]
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <string>
#include <thread>
#include <chrono>
namespace sc = std::chrono;
#include <curl/curl.h>
bool download_to_file(CURL *curl, const char *url, const char *fname) {
CURLcode res;
if (curl == NULL) return false;
// Set the URL
curl_easy_setopt(curl, CURLOPT_URL, url);
FILE *outf = std::fopen(fname, "wb");
// Set the userp parameter used for grab_data
curl_easy_setopt(curl, CURLOPT_WRITEDATA, outf);
// Tell libcurl to call fwrite when it has new data
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, std::fwrite);
// Do the download
res = curl_easy_perform(curl);
if (res != 0) {
std::cerr << "An error occured while downloading \"" << url << "\"!\nres = " << res << std::endl;
return false;
}
std::fclose(outf);
return true;
}
void initializeLibs(CURL **curl) {
// Initialize curl
curl_global_init(CURL_GLOBAL_DEFAULT);
*curl = curl_easy_init();
}
void cleanupLibs(CURL *curl) {
// Cleanup curl
curl_easy_cleanup(curl);
curl_global_cleanup();
}
std::time_t setHHMMSS(int hour, int min, int sec, std::time_t current) {
auto t = std::localtime(&current);
t->tm_hour = hour;
t->tm_min = min;
t->tm_sec = sec;
return std::mktime(t);
}
bool isBetween(int shour, int sminute, int ssecond, int ehour, int eminute, int esecond) {
std::time_t right_now = sc::system_clock::to_time_t(sc::system_clock::now());
auto starttime = setHHMMSS(shour, sminute, ssecond, right_now);
auto endtime = setHHMMSS(ehour, eminute, esecond, right_now);
return ((right_now >= starttime) && (right_now <= endtime));
}
sc::system_clock::time_point tomorrowAtSeven() {
// Reset to 7:01 this morning
std::time_t right_now = sc::system_clock::to_time_t(sc::system_clock::now());
auto t = std::localtime(&right_now);
t->tm_hour = 7;
t->tm_min = 1;
t->tm_sec = 0;
std::time_t tmp = std::mktime(t);
// Return 24 hours from 7:01 this morning
const std::chrono::hours oneDay( 24 );
return oneDay + sc::system_clock::from_time_t(tmp);
}
int main(int argc, char *argv[]) {
CURL *curl = NULL;
initializeLibs(&curl);
int count = 1;
char imageFile[512];
char imageUrl[512];
const std::chrono::minutes fiveMin( 5 );
while (true) {
for (auto i=1;i<=5;++i) {
snprintf(imageFile, sizeof(imageFile), "images/cam%dimage%06d.jpg", i, count);
snprintf(imageUrl, sizeof(imageUrl), "http://www.arapahoebasin.com/ABasin/assets/images/webcams/webcam%d/abasincam%d.jpg", i, i);
download_to_file(curl, imageUrl, imageFile);
}
count += 1;
if (isBetween(7,0,0, 17,0,0)) {
std::this_thread::sleep_for(fiveMin);
} else {
std::time_t tmp = std::time(0);
char formattedDate[100] = "";
std::strftime(formattedDate, 100, "%F", std::localtime(&tmp));
char movieCommand[512] = "";
for (auto i=1;i<=5;++i) {
snprintf(movieCommand, sizeof(movieCommand), "ffmpeg -i images/cam%dimage%%6d.jpg -r 30 -b:v 8000k images/cam%d-%s.mp4", i, i, formattedDate);
std::cout << "Running command:\n\t" << movieCommand << "\n";
std::system(movieCommand);
}
std::this_thread::sleep_until(tomorrowAtSeven());
}
}
cleanupLibs(curl);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment