Skip to content

Commit 81fd043

Browse files
committed
Add -m renaming files to MXF date/time
Use getopts native unknown method. Add -v for logging of files as they are written.
1 parent dff986e commit 81fd043

File tree

4 files changed

+76
-23
lines changed

4 files changed

+76
-23
lines changed

README.md

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,18 @@ webcam still images and save them to the current directory.
55

66
## Use
77

8-
`node {-t nnn} URL`
8+
```
9+
node [options] URL
910
10-
where `nnn` is the fetch interval (default 5000).
11+
-i nnn, --interval nnn mS between fetches [default: 5000]
12+
-m, --mxf rename files to MXF creation time
13+
-v, --verbose show filenames as they are written
14+
-h, --help show this help
15+
```
1116

1217
If URL ends in a `=` an incrementing integer is appended
1318
to it for each fetch in an attempt to avoid aggressive
1419
request caching.
1520

16-
Files are named for the number of mS past the epoch when the fetch started.
21+
By default, files are named for the number of mS past the
22+
epoch when the fetch started.

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "webstills",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"description": "fetch webcam still images to local disk",
55
"main": "index.js",
66
"scripts": {
@@ -22,10 +22,10 @@
2222
},
2323
"eslintConfig": {
2424
"env": {
25-
"browser": false,
26-
"commonjs": true,
27-
"es6": true,
28-
"node": true
25+
"browser": false,
26+
"commonjs": true,
27+
"es6": true,
28+
"node": true
2929
},
3030
"extends": "eslint:recommended",
3131
"parser": "typescript-eslint-parser",
@@ -36,7 +36,11 @@
3636
}
3737
},
3838
"rules": {
39-
"no-console": "off"
39+
"no-console": "off"
4040
}
41+
},
42+
"repository": {
43+
"type": "git",
44+
"url": "git+https://github.com/jimt/webstills"
4145
}
4246
}

src/index.ts

Lines changed: 56 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,37 @@ const DEFAULT_MS = 5000; // time between fetches
66
const fs = require("fs");
77
const got = require("got");
88
const getopts = require("getopts");
9+
910
var count = 0;
1011
var start = 0;
1112
var dup = 0;
1213
var filename;
1314
var lastImage;
1415

15-
const options = getopts(process.argv.slice(2), {
16-
boolean: ["h"],
17-
string: ["t"],
16+
var invalidOption = false;
17+
const OPTIONSDOC = {
18+
boolean: ["m", "v", "h"],
19+
string: ["i"],
1820
alias: {
19-
interval: ["t"],
21+
mxf: ["m"],
22+
interval: ["i"],
23+
verbose: ["v"],
2024
help: ["h"]
25+
},
26+
unknown: option => {
27+
invalidOption = true;
28+
console.error(`Unknown option: ${option}`);
29+
return false;
2130
}
22-
});
31+
};
32+
const options = getopts(process.argv.slice(2), OPTIONSDOC);
2333

2434
function usage() {
2535
console.log(`
2636
Usage: webstills [options] URL
27-
-t nnn, --interval nnn mS between fetches [default: 5000]
37+
-i nnn, --interval nnn mS between fetches [default: 5000]
38+
-m, --mxf rename files to MXF creation time
39+
-v, --verbose show filenames as they are written
2840
-h, --help show this help
2941
N.B. If URL ends with =, an incrementing counter is added to
3042
the URL to improve cache busting.
@@ -36,23 +48,53 @@ N.B. If URL ends with =, an incrementing counter is added to
3648
}
3749
}
3850

51+
function mxfdtname(d) {
52+
let daterxarr = /DAT=(\d{4}-\d\d-\d\d)[\r\n]/.exec(d);
53+
let timerxarr = /TIM=(\d\d:\d\d:\d\d\.\d{3})[\r\n]/.exec(d);
54+
if (daterxarr && timerxarr) {
55+
return `${daterxarr[1].replace(/-/g, "")}-${timerxarr[1].replace(
56+
/:/g,
57+
""
58+
)}.jpg`;
59+
}
60+
return null;
61+
}
62+
3963
function writeImage(filename, data) {
40-
fs.writeFile(filename + ".jpg", data, err => {
41-
if (err) console.log(`${count}: error writing: ${filename}.jpg`);
64+
let newname;
65+
filename = `${filename}.jpg`;
66+
fs.writeFile(filename, data, err => {
67+
if (err) {
68+
console.error(`${count}: error writing: ${filename}.jpg`);
69+
} else {
70+
if (options.m) {
71+
newname = mxfdtname(data.toString("binary", 0, 2047));
72+
if (newname) {
73+
fs.rename(filename, newname, err => {
74+
if (err) {
75+
console.error(`error renaming ${filename} to ${newname}`);
76+
}
77+
});
78+
}
79+
}
80+
}
81+
if (options.v) {
82+
console.log(newname ? newname : filename);
83+
}
4284
});
4385
}
4486

4587
function writeDup(filename, data) {
4688
let dupstr = ("0000" + dup).slice(-5);
47-
console.log(`Write ${filename}.${dupstr}`);
89+
console.log(`Write duplicate ${filename}.${dupstr}`);
4890
writeImage(`${filename}.${dupstr}`, data);
4991
dup++;
5092
}
5193

5294
async function fetcher() {
5395
let gotOptions = {
5496
retries: 0,
55-
timeout: Math.min(1000, options.t),
97+
timeout: Math.min(1200, options.i),
5698
encoding: null,
5799
headers: {
58100
"user-agent":
@@ -91,10 +133,11 @@ async function fetcher() {
91133

92134
if (
93135
options._.length !== 1 ||
94-
(options.t.length && isNaN(parseInt(options.t, 10)))
136+
invalidOption ||
137+
(options.i.length && isNaN(parseInt(options.i, 10)))
95138
) {
96139
usage();
97140
} else {
98-
options.t = parseInt(options.t, 10) || DEFAULT_MS;
99-
setInterval(fetcher, options.t);
141+
options.i = parseInt(options.i, 10) || DEFAULT_MS;
142+
setInterval(fetcher, options.i);
100143
}

0 commit comments

Comments
 (0)