Bulk-renaming Video Snapshots

For reasons that should be obvious by now, I review the helmet camera video from (some of) our bike rides and extract snapshots of interesting events. VLC auto-names the snapshots along these lines:

-rw-rw-r-- 1 ed ed  4.0M 2016-09-16 16:15 vlcsnap-2016-09-16-16h15m43s49.png
-rw-rw-r-- 1 ed ed  3.2M 2016-09-16 16:15 vlcsnap-2016-09-16-16h15m59s181.png
-rw-rw-r-- 1 ed ed  2.7M 2016-09-16 16:18 vlcsnap-2016-09-16-16h18m58s125.png
-rw-rw-r-- 1 ed ed  3.7M 2016-09-16 18:40 vlcsnap-2016-09-16-18h40m22s7.png
-rw-rw-r-- 1 ed ed  3.5M 2016-09-16 18:40 vlcsnap-2016-09-16-18h40m58s132.png
-rw-rw-r-- 1 ed ed  3.5M 2016-09-16 18:41 vlcsnap-2016-09-16-18h41m29s181.png
-rw-rw-r-- 1 ed ed  3.9M 2016-09-16 18:41 vlcsnap-2016-09-16-18h41m42s60.png
-rw-rw-r-- 1 ed ed  3.8M 2016-09-16 18:41 vlcsnap-2016-09-16-18h41m54s146.png
-rw-rw-r-- 1 ed ed  3.8M 2016-09-16 18:42 vlcsnap-2016-09-16-18h42m22s206.png
-rw-rw-r-- 1 ed ed  3.7M 2016-09-16 18:42 vlcsnap-2016-09-16-18h42m38s58.png

The gap in the timestamp after the first three files reveals a random errand.

First, convert to JPG format, place the results in another directory and, en passant, mash them to a reasonable size:

mkdir /some-useful-directory/Road\ Repair/"Rt 82 and CR 29"
for f in  vlcsnap-2016-09-16* ; do convert $f -density 300 -define jpeg:extent=200KB /some-useful-directory/Road\ Repair/"Rt 82 and CR 29"/${f%%.*}.jpg ; done
cd /some-useful-directory/Road\ Repair/"Rt 82 and CR 29"

Replace the first part of the VLC-generated names with relevant identification:

rename 's/vlcsnap-/Rt 82 - /' vlcsnap-2016-09-16-16*
rename 's/vlcsnap-/CR 29 - /' vlcsnap*

The directory now contains these files:

-rw-rw-r-- 1 ed ed 193K 2016-09-19 11:36 CR 29 - 2016-09-16-18h40m22s7.jpg
-rw-rw-r-- 1 ed ed 192K 2016-09-19 11:36 CR 29 - 2016-09-16-18h40m58s132.jpg
-rw-rw-r-- 1 ed ed 193K 2016-09-19 11:36 CR 29 - 2016-09-16-18h41m29s181.jpg
-rw-rw-r-- 1 ed ed 193K 2016-09-19 11:36 CR 29 - 2016-09-16-18h41m42s60.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 11:36 CR 29 - 2016-09-16-18h41m54s146.jpg
-rw-rw-r-- 1 ed ed 196K 2016-09-19 11:36 CR 29 - 2016-09-16-18h42m22s206.jpg
-rw-rw-r-- 1 ed ed 196K 2016-09-19 11:36 CR 29 - 2016-09-16-18h42m38s58.jpg
-rw-rw-r-- 1 ed ed 195K 2016-09-19 11:36 Rt 82 - 2016-09-16-16h15m43s49.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 11:36 Rt 82 - 2016-09-16-16h15m59s181.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 11:36 Rt 82 - 2016-09-16-16h18m58s125.jpg

These bursts of Perl regex line noise replace the snapshot timestamp on those files with an ascending sequence number, with separate sequences for each group:

i=1 ; for f in CR* ; do rename -v "s/-1[68]h..m..s\d{1,3}/ - $(( i++ ))/" "$f" ; done
i=1 ; for f in Rt* ; do rename -v "s/-1[68]h..m..s\d{1,3}/ - $(( i++ ))/" "$f" ; done

And then the files make sense:

-rw-rw-r-- 1 ed ed 193K 2016-09-19 13:51 CR 29 - 2016-09-16 - 1.jpg
-rw-rw-r-- 1 ed ed 192K 2016-09-19 13:51 CR 29 - 2016-09-16 - 2.jpg
-rw-rw-r-- 1 ed ed 193K 2016-09-19 13:51 CR 29 - 2016-09-16 - 3.jpg
-rw-rw-r-- 1 ed ed 193K 2016-09-19 13:51 CR 29 - 2016-09-16 - 4.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 13:51 CR 29 - 2016-09-16 - 5.jpg
-rw-rw-r-- 1 ed ed 196K 2016-09-19 13:51 CR 29 - 2016-09-16 - 6.jpg
-rw-rw-r-- 1 ed ed 196K 2016-09-19 13:51 CR 29 - 2016-09-16 - 7.jpg
-rw-rw-r-- 1 ed ed 195K 2016-09-19 13:51 Rt 82 - 2016-09-16 - 1.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 13:51 Rt 82 - 2016-09-16 - 2.jpg
-rw-rw-r-- 1 ed ed 194K 2016-09-19 13:51 Rt 82 - 2016-09-16 - 3.jpg

The hard part, this time around, involved figuring a regex for the timestamp. The trick was to specify a single digit for the milliseconds part, with a repetition count allowing for one-to-three digits.

The Perl regex cheat sheet helped.

The double quotes around the rename search parameter allows the shell to expand the $(( i++ )) gibberish. The double quotes around the file name keep the blank-separated parts together.

At some point I must figure out how to produce leading-zero-filled sequence numbers, which will probably involve a printf.

The ride covered some roads with “2 to 4 foot” shoulders, which seems overly optimistic:

Rt 82 - 2016-09-16 - 3

Rt 82 – 2016-09-16 – 3

NYSDOT and DCDPW both believe a homeopathic strip of asphalt will cover faults in the travel lane and don’t care that the right side of the strip puts an abrupt ledge along the middle of the minimal and fissured shoulder:

Rt 82 - 2016-09-16 - 1

Rt 82 – 2016-09-16 – 1

Ah, well, it was a lovely day for a ride …

Advertisements

  1. #1 by tantris on 2016-09-30 - 11:10

    seq produces a sequence of numbers, seq -w produces leading-zero-filled sequence numbers.

    seq 1 10

    seq -w 1 10

  2. #2 by solaandjin on 2016-09-30 - 13:14

    Here you go: rename ‘s:-1[68]h..m..s\d{1,3}:sprintf(“- %03d”, ($i = $i // 1)++):e’ *

    /e modifier says to treat the replacement as a perl expression to be evaluated. The // operator returns the left side if it is defined, and the right side if not, so it serves to initialize $i (so you don’t have to use interpolated shell variables and for loops). The s/// delimiter has been changed to colons so you don’t have to escape the operator slashes. “%03d” is a sprintf format string, zero padded three character digit.

    • #3 by Ed on 2016-09-30 - 13:41

      I grovel, I abase myself, I kiss your feet. [grin]

      I’d used the seq -w trick before, but have trouble combining all the pieces within the proper quote to handle file-names-with-spaces and all that nonsense. I should just use Python and be done with it, even if it seems too much like work.

      As nearly as I can tell, Perl behaves like old-school IBM PL/I: any file that resembles source code will compile into an executable that will do something, but you can’t predict the results with any certainty. Perl relaxes the restriction that the file contents must resemble source code…

  3. #4 by scruss2 on 2016-09-30 - 15:07

    … or learn to eschew creating file names with spaces at all. Stick to names with only a-z, 0-9, hyphen, underscore and period (just one of those, though) and every file system and network will be happy.

    I suspect you could do all the renaming (except for the route bit) in exiftool, which adds all sorts of file metadata munging to regular Perl.

    • #5 by Ed on 2016-09-30 - 15:35

      eschew creating file names with spaces

      The 70s called: they want their 8.3 filenames back…

      Those days are gone and for good reason; that I can’t dependably nest multiple levels of Bash quotes is my own fault. [heavy sigh]

    • #6 by Ed on 2016-10-01 - 09:34

      hyphen, underscore and period

      Which reminds me of the time I managed to finger-fumble a filename with a leading space and a single quote buried inside. Took me a while to figure out the real problem, get the escapes right, then hammer it flush with the surroundings…

  4. #7 by celem on 2016-10-02 - 10:40

    I’m surprised that you left all those spaces in the filenames. Spaces in filenames are frequently problematic for Linux, mandating quotes or backslash escapes, in most cases. Personally, I avoid spaces in filenames for this reason. BTW – have you tried phatch? It’s pretty useful for similar tasks.
    http://photobatch.wikidot.com/

    • #8 by Ed on 2016-10-02 - 12:40

      I put spaces in filenames because I want readable and meaningful names. The fact that some command-line programs (my own fumbling included) blunders those names isn’t a reason to complexify filenames, it’s just motivation to fix the real problem.

      As far as Phatch goes, I’ve outlived far too many special-purpose programs like that and tend to go for simple, general-purpose, somewhat primitive operations that have a good chance of working forever.

      If only I could remember the syntax the next time I need it, that would be even better, but now that I’m recording the successes here, I can appear much more competent. [sigh]