tedshepherd[dot]net

Using ffmepg to concatonate audio files

Published:

I’ve been ripping audiobook CDs recently and have been using AudioBookBinder1 and I like that it allows me to create chapters in m4b audiobook files. The issue that I run into is that the app doesn’t have the best UI when it comes to adding and moving chapter markers around. It’s much easier and faster to merge multiple audio files into one file so that each audio file is one chapter. This is easier because AudioBookBinder’s default chapter configuration is that each file is it’s own chapter.

My system:

When ripping disc I use the title naming convention “Chapter ##” for the first file for a chapter and then every file after that is called “Chapter ## - pt#”. 1-03 Chapter 01.m4a, 01-04 Chapter 01 - pt2.m4a, etc.

Once all of the discs are ripped, copy them to the same folder outside of the Music Library. For our example, it files look like this:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
1-01 Introduction.m4a
1-02 Dedication.m4a
1-03 Chapter 01.m4a
1-04 Chapter 01 - pt2.m4a
1-05 Chapter 02.m4a
1-06 Chapter 03.m4a
1-07 Chapter 04.m4a
1-08 Chapter 05.m4a
1-09 Chapter 06.m4a
1-10 Chapter 07.m4a
1-11 Chapter 07 - pt2.m4a
1-12 Chapter 08.m4a
1-13 Chapter 08 - pt2.m4a
1-14 Chapter 09.m4a
2-01 Chapter 09 - pt2.m4a
2-02 Chapter 09 - pt3.m4a
2-03 Chapter 10.m4a
2-04 Chapter 11.m4a
2-05 Chapter 11 - pt2.m4a
2-06 Chapter 11 - pt3.m4a
2-07 Chapter 12.m4a
2-08 Chapter 13.m4a
2-09 Chapter 13 - pt2.m4a
2-10 Chapter 14.m4a
2-11 Chapter 14 - pt2.m4a
2-12 Chapter 14 - pt3.m4a
3-01 Chaptr 15.m4a
3-02 Chapter 15 - pt2.m4a
3-03 Chapter 16.m4a
3-04 Chapter 16 - pt2.m4a
3-05 Chapter 17.m4a
3-06 Chapter 17 - pt2.m4a
3-07 Chapter 18.m4a
3-08 Chapter 18 - pt2.m4a
3-09 Chapter 18 - pt3.m4a
3-10 Chapter 19.m4a
3-11 Chapter 19 - pt2.m4a
4-01 Chapter 20.m4a
4-02 Chapter 20 - pt2.m4a
4-03 Chapter 21.m4a
4-04 Chapter 21 - pt2.m4a
4-05 Chapter 21 - pt3.m4a
4-06 Chapter 21 - pt4.m4a
4-07 Chapter 22.m4a
4-08 Chapter 22 - pt2.m4a
4-09 Chapter 23.m4a
4-10 Chapter 23 - pt2.m4a
4-11 Chapter 23 - pt3.m4a
4-12 Chapter 24.m4a
4-13 Chapter 24 - pt2.m4a
5-01 Chapter 25.m4a
5-02 Chapter 25 - pt2.m4a
5-03 Chapter 25 - pt3.m4a
5-04 Chapter 26.m4a
5-05 Chapter 26 - pt2.m4a
5-06 Chapter 26 - pt3.m4a
5-07 Chapter 26 - pt4.m4a
5-08 Chapter 27.m4a
5-09 Chapter 27 - pt2.m4a
5-10 Chapter 27 - pt3.m4a
5-11 Chapter 28.m4a
5-12 Chapter 28 - pt2.m4a
5-13 Chapter 28 - pt3.m4a
6-01 Chapter 29.m4a
6-02 Chapter 29 - pt2.m4a
6-03 Chapter 30.m4a
6-04 Chapter 30 - pt2.m4a
6-05 Chapter 30 - pt3.m4a
6-06 Chapter 31.m4a
6-07 Chapter 31 - pt2.m4a
6-08 Chapter 32.m4a
6-09 Chapter 32 - pt2.m4a
6-10 Chapter 32 - pt3.m4a
6-11 Chapter 32 - pt4.m4a
7-01 Chapter 33.m4a
7-02 Chapter 33 - pt2.m4a
7-03 Chapter 33 - pt3.m4a
7-04 Chapter 34.m4a
7-05 Chapter 34 - pt2.m4a
7-06 Chapter 35.m4a
7-07 Chapter 35 - pt2.m4a
7-08 Chapter 36.m4a
7-09 Chapter 36 - pt2.m4a
7-10 Chapter 36 - pt3.m4a
7-11 Chapter 37.m4a
7-12 Chapter 37 - pt2.m4a
8-01 Chapter 38.m4a
8-02 Chapter 38 - pt2.m4a
8-03 Chapter 39.m4a
8-04 Chapter 39 - pt2.m4a
8-05 Chapter 40.m4a
8-06 Chapter 40 - pt2.m4a
8-07 Chapter 40 - pt3.m4a
8-08 Chapter 41.m4a
8-09 Chapter 41 - pt2.m4a
8-10 Chapter 42.m4a
8-11 Chapter 42 - pt2.m4a
9-01 Chapter 42 - pt3.m4a
9-02 Chapter 43.m4a
9-03 Chapter 43 - pt2.m4a
9-04 Chapter 44.m4a
9-05 Chapter 45.m4a
9-06 Chapter 45 - pt2.m4a
9-07 Chapter 45 - pt3.m4a
9-08 Chapter 46.m4a
9-09 Chapter 46 - pt2.m4a
9-10 Chapter 46 - pt3.m4a
9-11 Chapter 46 - pt4.m4a
9-12 Chapter 47.m4a
9-13 Credits.m4a

To make it easier on ourselves we’ll add a leading zero on the disc number. This is less important on audiobooks with less and ten discs but once you get ten or more discs, zsh’s ls will make the file order go 1, 10, 11, 2, 3, 4.

Then we’ll build the concat file that ffmpeg needs to know which files are going to concatonated. This info was found on ffmeg’s trac site, https://trac.ffmpeg.org/wiki/Concatenate.

1
2
3
4
5
6
for ((i=1;i<=47;i++)); do
    j=$(printf "%02d" $i)
    for f in *Chapter\ $j*.m4a; do
        echo "file '$f'" >> "Chapter $j.txt"
    done
done

After running this we’ll get the following files:

ls *.txt | cat
Chapter 01.txt
Chapter 02.txt
Chapter 03.txt
Chapter 04.txt
Chapter 05.txt
Chapter 06.txt
Chapter 07.txt
Chapter 08.txt
Chapter 09.txt
Chapter 10.txt
Chapter 11.txt
Chapter 12.txt
Chapter 13.txt
Chapter 14.txt
Chapter 15.txt
Chapter 16.txt
Chapter 17.txt
Chapter 18.txt
Chapter 19.txt
Chapter 20.txt
Chapter 21.txt
Chapter 22.txt
Chapter 23.txt
Chapter 24.txt
Chapter 25.txt
Chapter 26.txt
Chapter 27.txt
Chapter 28.txt
Chapter 29.txt
Chapter 30.txt
Chapter 31.txt
Chapter 32.txt
Chapter 33.txt
Chapter 34.txt
Chapter 35.txt
Chapter 36.txt
Chapter 37.txt
Chapter 38.txt
Chapter 39.txt
Chapter 40.txt
Chapter 41.txt
Chapter 42.txt
Chapter 43.txt
Chapter 44.txt
Chapter 45.txt
Chapter 46.txt
Chapter 47.txt

And they’ll have contents like this:

for f in *.txt; do
    echo -e $f
    echo -e "$(cat $f)"
    echo -e "\n"
done

Chapter 01.txt
file '1-03 Chapter 01.m4a'
file '1-04 Chapter 01 - pt2.m4a'

Chapter 02.txt
file '1-05 Chapter 02.m4a'

Chapter 03.txt
file '1-06 Chapter 03.m4a'

Chapter 04.txt
file '1-07 Chapter 04.m4a'

Chapter 05.txt
file '1-08 Chapter 05.m4a'

Chapter 06.txt
file '1-09 Chapter 06.m4a'

Chapter 07.txt
file '1-10 Chapter 07.m4a'
file '1-11 Chapter 07 - pt2.m4a'

Chapter 08.txt
file '1-12 Chapter 08.m4a'
file '1-13 Chapter 08 - pt2.m4a'

Chapter 09.txt
file '1-14 Chapter 09.m4a'
file '2-01 Chapter 09 - pt2.m4a'
file '2-02 Chapter 09 - pt3.m4a'

Chapter 10.txt
file '2-03 Chapter 10.m4a'
file '2-03 Chapter 10.m4a'

Chapter 11.txt
file '2-04 Chapter 11.m4a'
file '2-05 Chapter 11 - pt2.m4a'
file '2-06 Chapter 11 - pt3.m4a'

Chapter 12.txt
file '2-07 Chapter 12.m4a'

Chapter 13.txt
file '2-08 Chapter 13.m4a'
file '2-09 Chapter 13 - pt2.m4a'

Chapter 14.txt
file '2-10 Chapter 14.m4a'
file '2-11 Chapter 14 - pt2.m4a'
file '2-12 Chapter 14 - pt3.m4a'

Chapter 15.txt
file '3-02 Chapter 15 - pt2.m4a'

Chapter 16.txt
file '3-03 Chapter 16.m4a'
file '3-04 Chapter 16 - pt2.m4a'

Chapter 17.txt
file '3-05 Chapter 17.m4a'
file '3-06 Chapter 17 - pt2.m4a'

Chapter 18.txt
file '3-07 Chapter 18.m4a'
file '3-08 Chapter 18 - pt2.m4a'
file '3-09 Chapter 18 - pt3.m4a'

Chapter 19.txt
file '3-10 Chapter 19.m4a'
file '3-11 Chapter 19 - pt2.m4a'

Chapter 20.txt
file '4-01 Chapter 20.m4a'
file '4-02 Chapter 20 - pt2.m4a'

Chapter 21.txt
file '4-03 Chapter 21.m4a'
file '4-04 Chapter 21 - pt2.m4a'
file '4-05 Chapter 21 - pt3.m4a'
file '4-06 Chapter 21 - pt4.m4a'

Chapter 22.txt
file '4-07 Chapter 22.m4a'
file '4-08 Chapter 22 - pt2.m4a'

Chapter 23.txt
file '4-09 Chapter 23.m4a'
file '4-10 Chapter 23 - pt2.m4a'
file '4-11 Chapter 23 - pt3.m4a'

Chapter 24.txt
file '4-12 Chapter 24.m4a'
file '4-13 Chapter 24 - pt2.m4a'

Chapter 25.txt
file '5-01 Chapter 25.m4a'
file '5-02 Chapter 25 - pt2.m4a'
file '5-03 Chapter 25 - pt3.m4a'

Chapter 26.txt
file '5-04 Chapter 26.m4a'
file '5-05 Chapter 26 - pt2.m4a'
file '5-06 Chapter 26 - pt3.m4a'
file '5-07 Chapter 26 - pt4.m4a'

Chapter 27.txt
file '5-08 Chapter 27.m4a'
file '5-09 Chapter 27 - pt2.m4a'
file '5-10 Chapter 27 - pt3.m4a'

Chapter 28.txt
file '5-11 Chapter 28.m4a'
file '5-12 Chapter 28 - pt2.m4a'
file '5-13 Chapter 28 - pt3.m4a'

Chapter 29.txt
file '6-01 Chapter 29.m4a'
file '6-02 Chapter 29 - pt2.m4a'

Chapter 30.txt
file '6-03 Chapter 30.m4a'
file '6-04 Chapter 30 - pt2.m4a'
file '6-05 Chapter 30 - pt3.m4a'

Chapter 31.txt
file '6-06 Chapter 31.m4a'
file '6-07 Chapter 31 - pt2.m4a'

Chapter 32.txt
file '6-08 Chapter 32.m4a'
file '6-09 Chapter 32 - pt2.m4a'
file '6-10 Chapter 32 - pt3.m4a'
file '6-11 Chapter 32 - pt4.m4a'

Chapter 33.txt
file '7-01 Chapter 33.m4a'
file '7-02 Chapter 33 - pt2.m4a'
file '7-03 Chapter 33 - pt3.m4a'

Chapter 34.txt
file '7-04 Chapter 34.m4a'
file '7-05 Chapter 34 - pt2.m4a'

Chapter 35.txt
file '7-06 Chapter 35.m4a'
file '7-07 Chapter 35 - pt2.m4a'

Chapter 36.txt
file '7-08 Chapter 36.m4a'
file '7-09 Chapter 36 - pt2.m4a'
file '7-10 Chapter 36 - pt3.m4a'

Chapter 37.txt
file '7-11 Chapter 37.m4a'
file '7-12 Chapter 37 - pt2.m4a'

Chapter 38.txt
file '8-01 Chapter 38.m4a'
file '8-02 Chapter 38 - pt2.m4a'

Chapter 39.txt
file '8-03 Chapter 39.m4a'
file '8-04 Chapter 39 - pt2.m4a'

Chapter 40.txt
file '8-05 Chapter 40.m4a'
file '8-06 Chapter 40 - pt2.m4a'
file '8-07 Chapter 40 - pt3.m4a'

Chapter 41.txt
file '8-08 Chapter 41.m4a'
file '8-09 Chapter 41 - pt2.m4a'

Chapter 42.txt
file '8-10 Chapter 42.m4a'
file '8-11 Chapter 42 - pt2.m4a'
file '9-01 Chapter 42 - pt3.m4a'

Chapter 43.txt
file '9-02 Chapter 43.m4a'
file '9-03 Chapter 43 - pt2.m4a'

Chapter 44.txt
file '9-04 Chapter 44.m4a'

Chapter 45.txt
file '9-05 Chapter 45.m4a'
file '9-06 Chapter 45 - pt2.m4a'
file '9-07 Chapter 45 - pt3.m4a'

Chapter 46.txt
file '9-08 Chapter 46.m4a'
file '9-09 Chapter 46 - pt2.m4a'
file '9-10 Chapter 46 - pt3.m4a'
file '9-11 Chapter 46 - pt4.m4a'

Chapter 47.txt
file '9-12 Chapter 47.m4a'

Now we can use ffmeg to concatonate these files together to make one file per chapter.

1
2
3
4
5
6
7
8
9
# We can run a loop to create a single audio file for each chapter of the audiobook
for ((i=1;i<=47;i++));do
    j=$(printf "%02d" $i)
    ((k=$i + 2))
    ffmpeg -i *Chapter\ $j.m4a -f ffmetadata "Chapter $j.metadata"
    sed -i '' -e "s|track.*|track=${k}|g" "Chapter $j.metadata"
    sed -i '' -e "s|disc.*|disc=|g" "Chapter $j.metadata"
    ffmpeg -f concat -safe 0 -i "Chapter $j.txt" -i "Chapter $j.metadata" -c copy -map_metadata 1 "Chapter $j.m4a"
done

Then we use AudioBookBinder to combine them into one m4b file.

Unfortuneatly, I was unable to get the CLI working for AudioBookBinder, so we have to use the GUI.


  1. Available via the AppStore or HomeBrew. https://github.com/gonzoua/AudiobookBinder ↩︎

: