nix-configs

Personal NixOS and home-manager configuration files
Log | Files | Refs

taudiobooker.nix (3275B)


      1 { pkgs, ... }:
      2 
      3 {
      4   environment.systemPackages = [
      5     (pkgs.writeShellScriptBin "taudiobooker" ''
      6 		set -euo pipefail
      7 
      8 		# variables
      9 		codec="libopus"
     10 		bitrate="48k"
     11 		compression="10"
     12 		output=""
     13 
     14 		# functions
     15 		strip_chars() { awk '{gsub(/^[ \t-]+|[ \t-]+$/,""); print $0}'; }
     16 
     17 		process_opus_file() {
     18 			local file="$1"
     19 			output="$file"
     20 
     21 			echo "Tagging OPUS file: $file"
     22 
     23 			${pkgs.opustags}/bin/opustags -i -D "$output"
     24 			${pkgs.opustags}/bin/opustags -i -s "GENRE=Audiobook" "$output"
     25 
     26 			artist=$(printf "%s" "$output" |
     27 					 awk -F"-" '{print $1}' |
     28 					 strip_chars)
     29 
     30 			${pkgs.opustags}/bin/opustags -i -s "ARTIST=$artist" "$output"
     31 
     32 			if [[ "$output" == *"#"* ]]; then
     33 				# Series format
     34 				album=$(printf "%s" "$output" |
     35 						awk -F"-" '{print $2}' |
     36 						awk -F"#" '{print $1}' |
     37 						strip_chars)
     38 
     39 				track=$(printf "%s" "$output" |
     40 						awk -F"-" '{print $2}' |
     41 						awk -F"#" '{print $2}' |
     42 						awk '{gsub("^0*",""); print}' |
     43 						strip_chars)
     44 
     45 				title=$(printf "%s" "$output" |
     46 						awk -F"-" '{gsub(".opus",""); print $3}' |
     47 						strip_chars)
     48 
     49 				${pkgs.opustags}/bin/opustags -i -s "ALBUM=$album" "$output"
     50 				${pkgs.opustags}/bin/opustags -i -s "TRACKNUMBER=$track" "$output"
     51 				${pkgs.opustags}/bin/opustags -i -s "TITLE=$title" "$output"
     52 
     53 			else
     54 				# Single file
     55 				title=$(printf "%s" "$output" |
     56 						awk -F"-" '{gsub(".opus",""); print $2}' |
     57 						strip_chars)
     58 
     59 				${pkgs.opustags}/bin/opustags -i -s "TITLE=$title" "$output"
     60 			fi
     61 		}
     62 
     63 		process_other_file() {
     64 			local file="$1"
     65 			local base="''${file%.*}"
     66 			output="''${base}.opus"
     67 
     68 			echo "Encoding file to OPUS: $file → $output"
     69 
     70 			${pkgs.ffmpeg}/bin/ffmpeg -hide_banner -loglevel error -nostats \
     71 				-i "$file" \
     72 				-acodec "$codec" \
     73 				-ac 1 \
     74 				-b:a "$bitrate" \
     75 				-vbr on \
     76 				-compression_level "$compression" \
     77 				"$output"
     78 
     79 			echo "Done: $output"
     80 		}
     81 
     82 		analyze_directory() {
     83 			local dir="$1"
     84 			echo "Analyzing and concatenating directory: $dir"
     85 
     86 			# Find most common extension
     87 			local extension
     88 			extension=$(find "$dir" -type f -printf '%f\n' \
     89 				| sed -E 's/.*\.([^.]+)$/\1/' \
     90 				| sort | uniq -c | sort -nr | awk 'NR==1{print $2}')
     91 
     92 			if [[ -z "''${extension}" ]]; then
     93 				echo "No files found in directory."
     94 				exit 1
     95 			fi
     96 
     97 			echo "Most common filetype: .$extension"
     98 
     99 			# Output filename based on directory name
    100 			local name
    101 			name=$(basename "$dir")
    102 			output="''${name}.opus"
    103 
    104 			echo "Concatenating all .$extension files → $output"
    105 
    106 			${pkgs.ffmpeg}/bin/ffmpeg -f concat -safe 0 \
    107 				-i <(for f in "$dir"/*."$extension"; do
    108 						echo "file '$PWD/$f'"
    109 					  done) \
    110 				-acodec "$codec" \
    111 				-ac 1 \
    112 				-b:a "$bitrate" \
    113 				-vbr on \
    114 				-compression_level "$compression" \
    115 				"$output"
    116 
    117 			echo "Created: $output"
    118 		}
    119 
    120 		# main logic
    121 
    122 		if [[ $# -ne 1 ]]; then
    123 			echo "Usage: $0 <file-or-directory>"
    124 			exit 1
    125 		fi
    126 
    127 		input="$1"
    128 
    129 		if [[ -d "$input" ]]; then
    130 			analyze_directory "$input"
    131 		elif [[ -f "$input" ]]; then
    132 			ext="''${input##*.}"
    133 			shopt -s nocasematch
    134 			if [[ "$ext" == "opus" ]]; then
    135 				process_opus_file "$input"
    136 			else
    137 				process_other_file "$input"
    138 			fi
    139 			shopt -u nocasematch
    140 		else
    141 			echo "Error: '$input' is not a valid file or directory"
    142 			exit 1
    143 		fi
    144     '')
    145   ];
    146 }