dotfiles

<-- duh.
Log | Files | Refs | LICENSE

commit b63bf587e11b90355a747bac1d66fbaa9d79db0f
parent 0623b4cace16127ab6f4fd075444e9c196a5bec0
Author: hhvn <dev@hhvn.uk>
Date:   Sun, 17 Apr 2022 22:28:00 +0100

Reimplement a/v tagging scripts

Diffstat:
D.scripts/musictag | 8--------
D.scripts/musictaginteractive | 23-----------------------
D.scripts/musictagorder | 16----------------
A.scripts/tag/get | 37+++++++++++++++++++++++++++++++++++++
A.scripts/tag/interactive | 111+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
A.scripts/tag/set | 130+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
6 files changed, 278 insertions(+), 47 deletions(-)

diff --git a/.scripts/musictag b/.scripts/musictag @@ -1,8 +0,0 @@ -#!/bin/sh - -[ -z $1 ] || [ -z $4 ] && echo "usage: musictag <file>.<fileext> <artist> <title> <album> [track]" && exit 1 - -[ ! -z $5 ] && outname="$5." -outname="${outname}$(echo "$2" | tr ' /' '.+').-.$(echo "$3" | tr ' /' '.+').${1##*.}" - -ffmpeg -y -nostdin -i "$1" -map_metadata -1 -vn -c copy -metadata "artist=$2" -metadata "title=$3" -metadata "album=$4" -metadata "track=$5" "$outname" diff --git a/.scripts/musictaginteractive b/.scripts/musictaginteractive @@ -1,23 +0,0 @@ -#!/bin/sh -# -# usage: musictaginteractive [artist] [album] - -[ "$1" != "" ] && sartist=1 && artist="$1" -[ "$2" != "" ] && salbum=1 && album="$2" - -get(){ - printf "$1? " - read $1 </dev/tty -} - -[ ${sartist:-0} -ne 1 ] && get artist -[ ${salbum:-0} -ne 1 ] && get album - -num=0 -for f in * -do - num=$(($num+1)) - echo "$(tput setaf 10)$f:$(tput sgr0)" - get title - musictag "$f" "$artist" "$title" "$album" "$(printf "%02d" "$num")" -done diff --git a/.scripts/musictagorder b/.scripts/musictagorder @@ -1,16 +0,0 @@ -#!/bin/sh -# -# usage: musictagorder -m [f1] [f2] -# -# -m do not prefix filename with track num - -[ "$1" != "-m" ] && move=y || shift - -count=0 -while [ $# -ne 0 ] -do - count=$(($count+1)) - prettycount=$(printf '%02d' $count) - - ffmpeg -y -notdin -i "$1" -map_metadata 0 -vn -c -copy -metadata "track=$prettycount" "$prettycount.$1" -done diff --git a/.scripts/tag/get b/.scripts/tag/get @@ -0,0 +1,37 @@ +#!/bin/rc + +fn usage { + printf 'usage: tag/get files...\n' >[1=2] + exit 2 +} + +if (~ $#* 0 || ~ $1 -h) { + usage +} + +label = '' + +for (f in $*) { + if (!~ $#* 1) { + label = '[' ^ $f ^ '] ' + } + if (!test -f $f) { + printf '%sCould not locate file.\n' $label >[1=2] + continue + } + ffmpeg -i $f -f ffmetadata - >[2]/dev/null | + awk -vlabel=^$label '/=/ { + key = $0; sub(/=.*/, "", key) + pad = key; gsub(/./, " ", pad) + val = $0; sub(/^[^=]*=/, "", val) + printf("%s%s: %s\n", label, key, val); + next + } + + # Print multiline metadata values indented + /^[^;\[]/ { printf("%s%s %s\n", label, pad, $0) } + + # Chapters/streams + /^\[/ { printf("\n%s%s\n", label, $0) }' | + sed -E 's/\\$//g;s/\\([=;#\\])/\1/g' +} diff --git a/.scripts/tag/interactive b/.scripts/tag/interactive @@ -0,0 +1,111 @@ +#!/bin/rc + +usage = ( +'usage: tag/interactive [-n] [-k] [-p metadata] [--artist artist]' +' [--title title] [--album album]' +' [--track track] [--comment comment]' +' files...' +'' +'tag/interactive is an interactive interface to tag/set.' +'' +'-p Metadata to prompt the user for. Usuable multiple times.' +' Can contain: artist, title, album, track, comment' +'-n Dry run. Prints commands to be executed.' +'-k Preserve all metadata this is not specified.' +'' +'--artist, --title, --album, --track, and --comment' +' Specify default metadata to apply to all files.' +) + +targs = () + +fn usage { + for (line in $usage) { + printf '%s\n' $line >[1=2] + } + exit 2 +} + +fn addmd { + if (~ $2 ()) { + usage + } + targs = ($targs $1 $2) + have = ($have `$nl{echo $1 | sed 's/^--//'}) +} + +fn get { + if (~ $want $1) { + tput bold + printf '%s: ' $1 + tput sgr0 + curtargs = ($curtargs --$1 `$nl{head -n 1}) + } +} + +fn printcmd { + whatis $1 >[2=1] | sed 's/^[^=]*=(//;s/)$//' +} + +while (!~ $#* 0) { + switch ($1) { + case --artist + addmd $* + shift + case --title + addmd $* + shift + case --album + addmd $* + shift + case --track + addmd $* + shift + case --comment + addmd $* + shift + case -p + if (~ $2 ()) { + usage + } + if (!~ $2 artist title album track comment) { + printf 'Unsupported prompt: %s\n' $2 >[1=2] + } + want = ($want $2) + shift + case -k + targs = (-k $targs) + case -n + dry = 1 + case -* + printf 'No such option: %s\n' $1 >[1=2] + usage + case * + files = ($files $1) + } + shift +} + +for (w in $want) { + if (~ $have $w) { + printf 'Cannot have both --%s and -p %s\n' $w $w >[1=2] + } +} + +for (f in $files) { + curtargs = $targs + printf '==> %s <==\n' $f + get artist + get title + get album + get track + get comment + cmd = (tag/set $curtargs $f) + if (~ $dry 1) { + printcmd cmd + tag/set -n $curtargs $f >[2=1] + } else { + echo Running `$nl{printcmd cmd} + $cmd + } +} diff --git a/.scripts/tag/set b/.scripts/tag/set @@ -0,0 +1,130 @@ +#!/bin/rc + +usage = ( +'usage: tag/set [-n] [-k] [--artist artist]' +' [--title title] [--album album]' +' [--track track] [--comment comment]' +' files...' +' tag/set [-n] [-d] files...' +'' +'tag/set removes and replaces metadata from audio/video files.' +'' +'-n Dry run. Only print commands to be executed.' +'-d Remove all data without replacing. Cannot be used with other options' +' except -n. This option was added to prevent accidental destruction.' +'-k Preserve all metadata that is not specified' +'' +'--artist, --title, --album, --track, and --comment' +' Specify replacement metadata.' +) + +clear = (-map_metadata -1) +files = () +tmp = () +margs = () + +fn sigexit { + for (f in $tmp) { + rm -f $f >[2]/dev/null >[1=2] + } +} + +fn usage { + for (line in $usage) { + printf '%s\n' $line >[1=2] + } + exit 2 +} + +fn tmp { + if (~ $dry 1) { + echo tmpfile + } else { + location = /tmp/$pid.`$nl{echo $1 | tr / _} { + echo $location + tmp = ($tmp $location) + } + } +} + +fn addmd { + if (~ $2 ()) { + usage + } + margs = ($margs -metadata `$nl{echo $1 | sed 's/^--//'} ^ '=' ^ $2) +} + +fn printcmd { + whatis $1 >[2=1] | sed 's/^[^=]*=(//;s/)$//' +} + +while (!~ $#* 0) { + switch ($1) { + case --artist + addmd $* + shift + case --title + addmd $* + shift + case --album + addmd $* + shift + case --track + addmd $* + shift + case --comment + addmd $* + shift + case -k + clear = () + case -d + delete = 1 + case -n + dry = 1 + case -* + printf 'No such option: %s\n' $1 >[1=2] + usage + case * + files = ($files $1) + } + shift +} + +if (~ $files ()) { + printf 'No files specified\n' >[1=2] + exit 1 +} + +# --delete cannot be specified along with other args +if (~ $delete 1 && {!~ $margs () || ~ $clear ()}) { + printf '--delete cannot be specified along with other args\n' + exit 1 +} + +if (~ $margs () && !~ $delete 1) { + printf 'Nothing to do\n' >[1=2] + exit 1 +} + +for (f in $files) { + out = `$nl{tmp $f} + fcmd = (ffmpeg -y -nostdin -i $f $clear -c copy $margs $out(1)) + mcmd = (mv $out(1) $f) + if (~ $dry 1) { + printcmd fcmd + printcmd mcmd + } else if (!test -f $f) { + printf 'No such file: %s\n' $f >[1=2] + } else { + if (~ $delete 1) { + echo Removing metadata... + } else if (~ $clear ()) { + echo Adding metadata... + } else { + echo Replacing metadata... + } + $fcmd + echo Replacing file... + $mcmd + } +}