2 # Desc: Converts a directory of mp3s into a single mkv file
3 # Usage: mp3s_to_mkv.sh [DIR in] [DIR out] [BITRATE]
4 # Example: mp3s_to_mkv.sh ./dir_source ./dir_output 48k
5 # Depends: GNU Coretils 8.32 (date)
9 opus_bitrate
="$3"; # e.g. "48k"
10 script_rundate
="$(date +%s)";
12 dir_in
="$(readlink -f "$1")";
13 dir_out
="$(readlink -f "$2")";
14 file_flist
="$dir_tmp"/"$script_rundate"..flist.txt
;
15 file_out_mkv
="$dir_out"/output.mkv
;
16 file_albumart
="$dir_out"/albumart.png
;
18 yell
() { echo "$0: $*" >&2; } # print script path and all args to stderr
19 die
() { yell
"$*"; exit 111; } # same as yell() but non-zero exit status
20 must
() { "$@" || die
"cannot $*"; } # runs args as command, reports args if command fails
22 # Desc: Display script usage information
27 # Depends: GNU-coreutils 8.30 (cat)
30 mp3s_to_mkv.sh [DIR in] [DIR out] [BITRATE]
33 mp3s_to_mkv.sh ./source_dir ./out_dir 48k
35 } # Display information on how to use this script.
37 if ! command -v ffmpeg
; then show_usage
; die
"FATAL:Missing ffmpeg."; fi;
38 }; # check dependencies
40 if [[ $# -ne 3 ]]; then show_usage
; die
"FATAL:Invalid arg count:$#"; fi;
41 if [[ ! -d "$dir_in" ]]; then show_usage
; die
"FATAL:Not a dir:$dir_in"; fi;
42 if [[ ! -d "$dir_out" ]]; then mkdir
-p "$2"; fi;
45 # Depends: var dir_tmp temporary directory
46 # var dir_in input dir
47 # var file_flist path file list
48 # Output: file: $file_flist list of mp3 files for ffmpeg
50 # Change directory to input dir
51 pushd "$dir_in" || die
"FATAL:Directory error:$(pwd)";
53 while read -r line
; do
54 yell
"$(printf "file '%s'\n" "${line#./}")";
55 printf "file '%s'\n" "${line#./}" >> "$file_flist";
56 done < <(find "$dir_in" -type f
-iname "*.mp3" |
sort);
58 # Return to original dir
59 popd || die
"FATAL:Directory error:$(pwd)";
61 }; # build file list for ffmpeg
63 # Depends: var dir_tmp
66 # Input: file $file_flist list of mp3 files for ffmpeg
68 # Change directory to input dir
69 pushd "$dir_in" || die
"FATAL:Directory error:$(pwd)";
71 # Concatenate mp3 files into a single WAV file
72 # # Convert WAV to 48 kbps opus mkv file
73 ffmpeg
-nostdin -f concat
-safe 0 -i "$file_flist" -c:a pcm_s24le
-rf64 auto
-f wav
- | \
74 ffmpeg
-i - -c:a libopus
-b:a
"$opus_bitrate" "$file_out_mkv";
76 # Return to original dir
77 popd || die
"FATAL:Directory error:$(pwd)";
78 }; # convert mp3s to opus mkv via ffmpeg
81 file="$(find "$dir_in" -type f -iname "*.mp3
" | sort | head -n1)";
82 file="$(readlink -f "$file")";
83 ffmpeg
-nostdin -i "$file" -an -vcodec copy
"$file_albumart";
84 }; # save album art from an mp3 to output dir
86 check_depends
&& yell
"DEBUG:check_depends OK";
87 check_plumbing
"$@" && yell
"DEBUG:check_plumbing OK";
88 build_filelist
"$@" && yell
"DEBUG:build_filelist OK";
89 ffmpeg_convert
"$@" && yell
"DEBUG:ffmpeg_convert OK";
90 save_albumart
"$@" && yell
"DEBUG:save_albumart OK";