m4b-tool is a is a wrapper for ffmpeg and mp4v2 to merge, split or and manipulate audiobook files with chapters. Although m4b-tool is designed to handle m4b files, nearly all audio formats should be supported, e.g. mp3, aac, ogg, alac and flac.
merge a set of audio files (e.g. MP3 or AAC) into a single m4b filesplit a single m4b file into several output files by chapters or a flac encoded album into single tracks via cue sheetchapters for an existing m4b file via silence detection or musicbrainzmerge all audio files in directory data/my-audio-book into file data/merged.m4b (tags are retained and data/my-audio-book/cover.jpg and data/my-audio-book/description.txt are embedded, if available)
m4b-tool merge "data/my-audio-book/" --output-file="data/merged.m4b"
split one big m4b file by chapters into multiple mp3 files at data/my-audio-book_splitted/ (tags are retained, data/my-audio-book_splitted/cover.jpg is created, if m4b contains a cover)
m4b-tool split --audio-format mp3 --audio-bitrate 96k --audio-channels 1 --audio-samplerate 22050 "data/my-audio-book.m4b"
chapters can try to adjust existing chapters of an m4b by silence detection
m4b-tool chapters --adjust-by-silence -o "data/destination-with-adjusted-chapters.m4b" "data/source-with-misplaced-chapters.m4b"
Since the most used subcommand of m4b-tool seems to be merge, lets talk about best practice...
Unfortunately m4b-tool has many dependencies. Not only one-liners, if you would like to get the best quality and tagging support, many dependencies have to be compiled manually with extra options. Thats why you should take a look at the docker image, which comes with all the bells and whistles of top audio quality, top tagging support and easy installation and has almost no disadvantages.
Note: If you are on windows, it might be difficult to make it work
When merging audiobooks, you should prepare them - the following directory structure helps a lot, even if you only merge one single audiobook:
input/<main genre>/<author>/<title>
or if it is a series
input/<main genre>/<author>/<series>/<series-part> - <title>
Examples:
input/Fantasy/J.K. Rowling/Quidditch Through the Ages/
input/Fantasy/J.K. Rowling/Harry Potter/1 - Harry Potter and the Philosopher's Stone/
Note: If your audiobook title contains invalid path characters like
/, just replace them with a dash-.
Now, because you almost always want a cover and a description for your audiobook, you should add the following files in the main directory:
cover.jpgdescription.txt (Be sure to use UTF-8 text file encoding for the contents)Examples:
input/Fantasy/J.K. Rowling/Quidditch Through the Ages/cover.jpg
input/Fantasy/J.K. Rowling/Quidditch Through the Ages/description.txt
Note:
m4b-toolwill find and embed these files automatically but does not fail, if they are not present
Chapters are nice to add waypoints for your audiobook. They help to remember the last position and improve the experience in general.
If you would like to adjust chapters manually, you can add a chapters.txt (same location as cover.jpg) with following contents (<chapter-start> <chapter-title>):
00:00:00.000 Intro
00:04:19.153 This is
00:09:24.078 A way to add
00:14:34.500 Chapters manually
If your input files are tagged, these tags will be used to create the chapter metadata by its title. So if you tag your input files with valid chapter names as track title, this will result in a nice and clean m4b-file with valid chapter names.
Another great feature since m4b-tool v.0.4.0 is the --max-chapter-length parameter. Often the individual input files are too big which results in chapters with a very long duration. This can be annoying, if you would like to jump to a certain point, since you have to rewind or fast-forward and hold the button for a long time, instead of just tipping previous or next a few times. To automatically add sub-chapters, you could provide:
--max-chapter-length=300,900
This will cause m4b-tool
Sub-chapters are named like the original and get an additional index. This is a nice way to keep the real names but not having chapters with a too long duration.
If you own an iPod, there might be a problem with too long audiobooks, since iPods only support 32bit sampling rates. If your audiobook is longer than 27 hours with 22050Hz sampling rate, you could provide --adjust-for-ipod, to automatically downsample your audiobook, which results in lower quality, but at least its working on your good old iPod...
m4b-tool supports multiple conversion tasks in parallel with the --jobs parameter (e.g. --jobs=2). If you have to convert more than one file, which is the common case, you nearly double the merge speed by providing the --jobs=2 parameter (or quadruplicate with --jobs=4, if you have a quad core system, etc.). Don't provide a number higher than the number of cores on your system - this will slow down the merge...
Note: If you run the conversion on all your cores, it will result in almost 100% CPU usage, which may lead to slower system performance
--batch-pattern featureIn m4b-tool v.0.4.0 the --batch-pattern feature was added. It can be used to batch-convert multiple audiobooks at once, but also to just convert one single audiobook - because you can create tags from an existing directory structure.
Hint: The
output-fileparameter has to be a directory, when using--batch-pattern.
Even multiple --batch-pattern parameters are supported, while the first match will be used first. So if you created the directory structure as described above, the final command to merge input/Fantasy/Harry Potter/1 - Harry Potter and the Philosopher's Stone/ to output/Fantasy/Harry Potter/1 - Harry Potter and the Philosopher's Stone.m4b would look like this:
m4b-tool merge -v --jobs=2 --output-file="output/" --max-chapter-length=300,900 --adjust-for-ipod --batch-pattern="input/%g/%a/%s/%p - %n/" --batch-pattern="input/%g/%a/%n/" "input/"
In
--batch-patternmode, existing files are skipped by default
If you performed the above steps with the docker image or installed and compiled all dependencies, you should get the following result:
libfdk_aac encodergenre, author, title, sorttitle, etc. from --batch-pattern usagecover.jpg and description.txt exist in the main directories, a cover, a description and a longdesc are embeddedTo use docker with m4b-tool, you first have to build a custom image located in the docker directory. Since this image is compiling every third party library from scratch to get the best possible audio quality, it can take a long time for the first build.
Note: You should know that
builddoes not mean thatm4b-toolis being compiled from source. That indeed is strange, but unlike other projects, them4b-tooldocker image only downloads the latest binary release unless you do some extra work (see below).
# clone m4b-tool repository
git clone https://github.com/sandreas/m4b-tool.git
# change directory
cd m4b-tool
# build docker image - this will take a while
docker build . -t m4b-tool
# create an alias for m4b-tool running docker
alias m4b-tool='docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool'
# testing the command
m4b-tool --version
Note: If you use the alias above, keep in mind that you cannot use absolute paths (e.g.
/tmp/data/audiobooks/harry potter 1) or symlinks. You must change into the directory and use relative paths (e.g.cd /tmp/data && m4b-tool merge "audiobooks/harry potter 1" --output-file harry.m4b)
To build a docker container using a Pre-Release or an older m4b-tool release, it is required to provide an extra parameter for downloading a specific version into the image, e.g. for v.0.4.1:
docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/releases/download/v.0.4.1/m4b-tool.tar.gz -t m4b-tool
Note: You could also just edit the according variable in the
Dockerfile.
Developers or experts might want to run a complete custom build of m4b-tool or build the code themselves (e.g. if you forked the repository and applied some patches). If that is the case, you can store the custom build to dist/m4b-tool.phar relative to the Dockerfile and then do a default build.
# dist/m4b-tool.phar is available
docker build . -t m4b-tool
After this the custom build should be integrated into the docker image.
On MacOS you may use the awesome package manager brew to install m4b-tool.
Getting best audio quality requires some additional effort. You have to recompile ffmpeg with the non-free libfdk_aac codec. This requires uninstalling the default ffmpeg package if installed, since brew dropped the possibility for extra options. There is no official ffmpeg-with-options repository, but a pretty decent tap, that you could use to save time.
# FIRST INSTALL ONLY: if not already done, remove existing ffmpeg with default audio quality options
# check for ffmpeg with libfdk and uninstall if libfdk is not already available
[ -x "$(which ffmpeg)" ] && (ffmpeg -hide_banner -codecs 2>&1 | grep libfdk || brew uninstall ffmpeg)
# tap required repositories
brew tap sandreas/tap
brew tap homebrew-ffmpeg/ffmpeg
# check available ffmpeg options and which you would like to use
brew options homebrew-ffmpeg/ffmpeg/ffmpeg
# install ffmpeg with at least libfdk_aac for best audio quality
brew install homebrew-ffmpeg/ffmpeg/ffmpeg --with-fdk-aac
# install m4b-tool
brew install sandreas/tap/m4b-tool
# check installed m4b-tool version
m4b-tool --version
If the above did not work for you or you would just to checkout m4b-tool before using it in production, you might want to try the quick and easy way. It will work, but you get lower audio quality and there is no support for sort tagging.
# tap m4b-tool repository
brew tap sandreas/tap
# install dependencies
brew install ffmpeg fdk-aac-encoder mp4v2
# install m4b-tool with acceptable audio quality and no sort tagging
brew install --ignore-dependencies sandreas/tap/m4b-tool
# install all dependencies
sudo apt install ffmpeg mp4v2-utils fdkaac php-cli php-intl php-json php-mbstring php-xml
# install / upgrade m4b-tool
sudo wget https://github.com/sandreas/m4b-tool/releases/download/v.0.4.2/m4b-tool.phar -O /usr/local/bin/m4b-tool && sudo chmod +x /usr/local/bin/m4b-tool
# check installed m4b-tool version
m4b-tool --version
Note: If you would like to get the best possible audio quality, you have to compile
ffmpegwith the high quality encoderfdk-aac(--enable-libfdk_aac) - see https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu for a step-by-step guide to compileffmpeg.
m4b-tool is written in PHP and uses ffmpeg, mp4v2 and optionally fdkaac for high efficiency codecs to perform conversions. Therefore you will need the following tools in your %PATH%:
php >= 7.1 with mbstring extension enabled (https://php.net)ffmpeg (https://www.ffmpeg.org)mp4v2 (mp4chaps, mp4art, etc. https://github.com/sandreas/m4b-tool/releases/download/v0.2/mp4v2-windows.zip)fdkaac (optional, only if you need high efficiency for low bitrates <= 32k, http://wlc.io/2015/06/20/fdk-aac/ - caution: not official!)To check the dependencies, running following commands via command line should show similar output:
$ php -v
Copyright (c) 1997-2018 The PHP Group [...]
$ ffmpeg -version
ffmpeg version 4.1.1 Copyright (c) 2000-2019 the FFmpeg developers [...]
$ mp4chaps --version
mp4chaps - MP4v2 2.0.0
$ fdkaac
fdkaac 1.0.0 [...]
If you are sure, all dependencies are installed, the next step is to download the latest release of m4b-tool from
https://github.com/sandreas/m4b-tool/releases
Depending on the operating system, you can rename m4b-tool.phar to m4b-tool and run m4b-tool --version directly from the command line. If you are not sure, you can always use the command php m4b-tool.phar --version to check if the installation was successful. This should work on every system.
If you would like to use the latest source code with all new features and fixes, you could also build from source. The current build might be in unstable and should only be used for testing purposes or if you need a specific feature that has not been released.
mp4v2 for accurate sorting orderMost audiobooks are not released in alphabetical order. A prominent example is Harry Potter. So if you have all the Harry Potter audiobooks, it depends on your player, but probably they are not listed in the correct order... let's see, what the alphabetical order would be:
And the correct order would have been:
Well, there is a solution for this. You have to tag the audiobook with a custom sortname and / or sortalbum. If your player supports these tags, the order is now correct, even when the title is still the original title. To achieve this, i had to build a custom version of mp4v2 (more accurate mp4tags), to add options for these tags and add the pseudo tags --series and --series-part.
So if you do the following:
m4b-tool merge --name="Harry Potter and the Chamber of Secrets" --series="Harry Potter" --series-part="2" --output-file="output/Harry Potter and the Chamber of Secrets.m4b" "input/Harry Potter and the Chamber of Secrets"
It would result in:
Harry Potter and the Chamber of SecretsHarry Potter 2 - Harry Potter and the Chamber of Secretsmp4v2In the docker image, the custom version is already installed
git clone https://github.com/sandreas/mp4v2
cd mp4v2
./configure
make && sudo make install
In m4b-tool all audio conversions are performed with ffmpeg resulting in pretty descent audio quality using its free encoders. However, best quality takes some extra effort, so if you are using the free encoders, m4b-tool might show the following hint:
Your ffmpeg version cannot produce top quality aac using encoder aac instead of libfdk_aac
That's not really a problem, because the difference between the aac and libfdk_aac encoder is hardly noticeable in most cases. But to overcome the hint and get the best audio quality possible, you have to use a non-free encoder, that is not integrated in ffmpeg by default (licensing reasons).
Depending on the operating system you are using, installing the non-free encoder may require a little extra skills, effort and time (see the notes for your operating system above).
You have to decide, if it is worth the additional effort for getting the slightly better quality. If you are using the docker image, you should get the best quality by default.
If you are using very low bitrates (<= 32k), you could also use high efficiency profiles to further improve audio quality (e.g. --audio-profile=aac_he for mono). Unfortunately, ffmpeg's high efficiency implementation produces audio files, that are incompatible with many players (including iTunes). To produce high efficiency files, that are compatible with at least most common players, you will need to install fdkaac for now.
More Details:
You think there is an issue with m4b-tool? First take a look at the Known Issues below. If this does not help, please provide the following information when adding an issue:
m4b-tool merge my-audio-book/ --output-file merged.m4bthe resulting file merged.m4b is only 5kbExample:
Title: m4b-tool does not embed covers
If i run m4b-tool with a folder containing a cover.png, it does not embed the cover and shows an error message.
OS: Ubuntu 16.04 LTS
Command: `m4b-tool merge my-audio-book/ ---output-file merged.m4b`
Error: Cannot embed cover, cover is not a valid image file
Attached files: cover.png
If you are getting PHP Exceptions, it is a configuration issue with PHP in most cases. If are not familiar with PHP configuration, you could follow these instructions, to fix a few known issues:
[Exception]
charset windows-1252 is not supported - use one of these instead: utf-8
This mostly happens on windows, because the mbstring-Extension is used to internally convert charsets, so that special chars like german umlauts
are supported on every platform. To fix this, you need to enable the mbstring-extension:
Run php --ini on the command line:
C:\>php --ini
...
Loaded Configuration File: C:\Program Files\php\php.ini
Open the configuration file (e.g. C:\Program Files\php\php.ini) in a text editor and search for extension=. On Windows there should be an item like this:
;extension=php_mbstring.dll
remove the ; to enable the extension:
extension=php_mbstring.dll
Now everything should work as expected.
The following list contains all possible commands including merge, split and chapters accompanied by the reference of parameters available in every command.
With m4b-tool you can merge a set of audio files to one single m4b audiobook file.
m4b-tool merge "data/my-audio-book" --output-file="data/my-audio-book.m4b"
This merges all Audio-Files in folder data/my-audio-book into my-audio-book.m4b, using
the tag-title of every file for generating chapters.
If there is a file data/my-audio-book/cover.jpg, it will be used as cover for the resulting m4b file.
Note: If you use untagged audio files, you could provide a musicbrainz id to get the correct chapter names, see command chapter for more info.
For all options, see m4b-tool merge --help:
Description:
Merges a set of files to one single file
Usage:
merge [options] [--] <input> [<more-input-files>...]
Arguments:
input Input file or folder
more-input-files Other Input files or folders
Options:
--logfile[=LOGFILE] file to log all output [default: ""]
--debug enable debug mode - sets verbosity to debug, logfile to m4b-tool.log and temporary encoded files are not deleted
-f, --force force overwrite of existing files
--no-cache clear cache completely before doing anything
--ffmpeg-threads[=FFMPEG-THREADS] specify -threads parameter for ffmpeg - you should also consider --jobs when merge is used [default: ""]
--platform-charset[=PLATFORM-CHARSET] Convert from this filesystem charset to utf-8, when tagging files (e.g. Windows-1252, mainly used on Windows Systems) [default: ""]
--ffmpeg-param[=FFMPEG-PARAM] Add argument to every ffmpeg call, append after all other ffmpeg parameters (e.g. --ffmpeg-param="-max_muxing_queue_size" --ffmpeg-param="1000" for ffmpeg [...] -max_muxing_queue_size 1000) (multiple values allowed)
-a, --silence-min-length[=SILENCE-MIN-LENGTH] silence minimum length in milliseconds [default: 1750]
-b, --silence-max-length[=SILENCE-MAX-LENGTH] silence maximum length in milliseconds [default: 0]
--max-chapter-length[=MAX-CHAPTER-LENGTH] maximum chapter length in seconds - its also possible to provide a desired chapter length in form of 300,900 where 300 is desired and 900 is max - if the max chapter length is exceeded, the chapter is placed on the first silence between desired and max chapter length [default: "0"]
--name[=NAME] custom name, otherwise the existing metadata will be used
--sortname[=SORTNAME] custom sortname, that is used only for sorting
--album[=ALBUM] custom album, otherwise the existing metadata for name will be used
--sortalbum[=SORTALBUM] custom sortalbum, that is used only for sorting
--artist[=ARTIST] custom artist, otherwise the existing metadata will be used
--sortartist[=SORTARTIST] custom sortartist, that is used only for sorting
--genre[=GENRE] custom genre, otherwise the existing metadata will be used
--writer[=WRITER] custom writer, otherwise the existing metadata will be used
--albumartist[=ALBUMARTIST] custom albumartist, otherwise the existing metadata will be used
--year[=YEAR] custom year, otherwise the existing metadata will be used
--description[=DESCRIPTION] custom short description, otherwise the existing metadata will be used
--longdesc[=LONGDESC] custom long description, otherwise the existing metadata will be used
--comment[=COMMENT] custom comment, otherwise the existing metadata will be used
--copyright[=COPYRIGHT] custom copyright, otherwise the existing metadata will be used
--encoded-by[=ENCODED-BY] custom encoded-by, otherwise the existing metadata will be used
--cover[=COVER] custom cover, otherwise the existing metadata will be used
--skip-cover skip extracting and embedding covers
--series[=SERIES] custom series, this pseudo tag will be used to auto create sort order (e.g. Harry Potter or The Kingkiller Chronicles)
--series-part[=SERIES-PART] custom series part, this pseudo tag will be used to auto create sort order (e.g. 1 or 2.5)
--audio-format[=AUDIO-FORMAT] output format, that ffmpeg will use to create files [default: "m4b"]
--audio-channels[=AUDIO-CHANNELS] audio channels, e.g. 1, 2 [default: ""]
--audio-bitrate[=AUDIO-BITRATE] audio bitrate, e.g. 64k, 128k, ... [default: ""]
--audio-samplerate[=AUDIO-SAMPLERATE] audio samplerate, e.g. 22050, 44100, ... [default: ""]
--audio-codec[=AUDIO-CODEC] audio codec, e.g. libmp3lame, aac, ... [default: ""]
--audio-profile[=AUDIO-PROFILE] audio profile, when using extra low bitrate - valid values: aac_he, aac_he_v2 [default: ""]
--adjust-for-ipod auto adjust bitrate and sampling rate for ipod, if track is too long (may result in
Content type
Image
Digest
Size
60.8 MB
Last updated
almost 6 years ago
docker pull burkasaurusrex/m4b-tool