m4b-tool is a command line utility to merge, split and chapterize audiobook files such as mp3, ogg, flac, m4a or m4b

Overview

m4b-tool

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.

Important Note

Unfortunately I am pretty busy at the moment, so m4b-tool 0.4.2 is very old. Since it is not planned to release a newer version without having complete documentation, there is only the latest pre-release getting bug fixes. It is already pretty stable, so if you are experiencing bugs with v0.4.2, please try the latest pre-release, if it has been already fixed there.

Thank you, sandreas

https://pilabor.com

Features

  • merge a set of audio files (e.g. MP3 or AAC) into a single m4b file
  • split a single m4b file into several output files by chapters or a flac encoded album into single tracks via cue sheet
  • Add or adjust chapters for an existing m4b file via silence detection or musicbrainz

TL;DR - examples for the most common tasks

Merge multiple files

merge 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 file by chapters

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 adjustment of a file via silence detection

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"

Best practices

Since the most used subcommand of m4b-tool seems to be merge, lets talk about best practice...

Step 0 - Take a look at the docker image

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

Step 1 - Organizing your audiobooks in directories

When merging audiobooks, you should prepare them - the following directory structure helps a lot, even if you only merge one single audiobook:

input/

/ / </code></p>

or if it is a series

input/

/ / / - </code></p>

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 -.

Step 2 - add cover and a description

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.jpg
  • description.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-tool will find and embed these files automatically but does not fail, if they are not present

Step 3 - chapters

Chapters are nice to add waypoints for your audiobook. They help to remember the last position and improve the experience in general.

fixed chapters

If you would like to adjust chapters manually, you can add a chapters.txt (same location as cover.jpg) with following contents ( ):

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

by tag

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.

by length

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

  • Trying to preserve original chapters as long as they are not longer than 15 minutes (900 seconds)
  • If a track is longer than 15 minutes
    • Perform a silence detection and try to add sub-chapters at every silence between 5 minutes (300 seconds) and 15 minutes (900 seconds)
    • If no silence is detected, add a hard cut sub-chapter every 5 minutes

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.

Step 4 (optional) - for iPod owners

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...

Step 5 (optional) - more cpu cores, faster conversion

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

Step 6 - Use the --batch-pattern feature

In 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-file parameter 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-pattern mode, existing files are skipped by default

Result

If you performed the above steps with the docker image or installed and compiled all dependencies, you should get the following result:

  • Top quality audio by using libfdk_aac encoder
  • Series and single audiobooks have valid tags for genre, author, title, sorttitle, etc. from --batch-pattern usage
  • If the files cover.jpg and description.txt exist in the main directories, a cover, a description and a longdesc are embedded
  • If you tagged the input files, real chapter names should appear in your player
  • No more chapters longer than 15 minutes
  • Working iPod versions for audiobooks longer than 27 hours

Installation

Docker

To 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 build does not mean that m4b-tool is being compiled from source. That indeed is strange, but unlike other projects, the m4b-tool docker 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)

Dockerize a Pre-Release or an older release version

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.

Dockerize a custom build, that is not available via download link

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.

MacOS

On MacOS you may use the awesome package manager brew to install m4b-tool.

Recommended: High audio quality, sort tagging

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.

&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 ">
# 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

Stick to defaults (acceptable audio quality, no sort tagging)

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

Ubuntu

# 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 ffmpeg with the high quality encoder fdk-aac (--enable-libfdk_aac) - see https://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu for a step-by-step guide to compile ffmpeg.

Manual installation (only recommended on Windows systems)

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%:

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.

Custom mp4v2 for accurate sorting order

Most 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:

  • Harry Potter and the Chamber of Secrets (Part 2)
  • Harry Potter and the Philosopher's Stone (Part 1)
  • Harry Potter and the Prisoner of Azkaban (Part 3)

And the correct order would have been:

  • Harry Potter and the Philosopher's Stone (Part 1)
  • Harry Potter and the Chamber of Secrets (Part 2)
  • Harry Potter and the Prisoner of Azkaban (Part 3)

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:

  • Name: Harry Potter and the Chamber of Secrets
  • Sortname: Harry Potter 2 - Harry Potter and the Chamber of Secrets

Install custom mp4v2

In the docker image, the custom version is already installed

git clone https://github.com/sandreas/mp4v2
cd mp4v2
./configure
make && sudo make install

About audio quality

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:

Submitting issues

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:

  • the operating system you use
  • the exact command, that you tried, e.g. m4b-tool merge my-audio-book/ --output-file merged.m4b
  • the error message, that occured or the circumstances, e.g. the resulting file merged.m4b is only 5kb
  • other relevant information, e.g. sample files if needed

Example:

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

Known issues

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 not supported

[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.

m4b-tool commands

The following list contains all possible commands including merge, split and chapters accompanied by the reference of parameters available in every command.

merge

With m4b-tool you can merge a set of audio files to one single m4b audiobook file.

Example:

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.

Reference

For all options, see m4b-tool merge --help:

Description:
  Merges a set of files to one single file

Usage:
  merge [options] [--]  [
     
      ...]

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 low audio quality)
      --fix-mime-type                            try to fix MIME-type (e.g. from video/mp4 to audio/mp4) - this is needed for some players to prevent an empty video window
  -o, --output-file=OUTPUT-FILE                  output file
      --include-extensions[=INCLUDE-EXTENSIONS]  comma separated list of file extensions to include (others are skipped) [default: "aac,alac,flac,m4a,m4b,mp3,oga,ogg,wav,wma,mp4"]
  -m, --musicbrainz-id=MUSICBRAINZ-ID            musicbrainz id so load chapters from
      --no-conversion                            skip conversion (destination file uses same encoding as source - all encoding specific options will be ignored)
      --batch-pattern[=BATCH-PATTERN]            multiple batch patterns that can be used to merge all audio books in a directory matching the given patterns (e.g. %a/%t for author/title) - parameter --output-file must be a directory (multiple values allowed)
      --dry-run                                  perform a dry run without converting all the files in batch mode (requires --batch-pattern)
      --jobs[=JOBS]                              Specifies the number of jobs (commands) to run simultaneously [default: 1]
      --use-filenames-as-chapters                Use filenames for chapter titles instead of tag contents
      --no-chapter-reindexing                    Do not perform any reindexing for index-only chapter names (by default m4b-tool will try to detect index-only chapters like Chapter 1, Chapter 2 and reindex it with its numbers only)
  -h, --help                                     Display this help message
  -q, --quiet                                    Do not output any message
  -V, --version                                  Display this application version
      --ansi                                     Force ANSI output
      --no-ansi                                  Disable ANSI output
  -n, --no-interaction                           Do not ask any interactive question
  -v|vv|vvv, --verbose                           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

     

Placeholder reference for --batch-pattern

If you use the --batch-pattern parameter, the following placeholders are supported

  • title / name: %n
  • sort_name: %N
  • album: %m,
  • sort_album: %M,
  • artist: %a,
  • sort_artist: %a,
  • genre: %g,
  • writer: %w,
  • album_artist: %t,
  • year: %y,
  • description: %d,
  • long_description: %d,
  • comment: %c,
  • copyright: %c,
  • encoded_by: %e,
  • series: %s,
  • series_part: %p,

split

m4b-tool can be used to split a single m4b into a file per chapter or a flac encoded album into single tracks via cue sheet.

Example:

m4b-tool split --audio-format mp3 --audio-bitrate 96k --audio-channels 1 --audio-samplerate 22050 "data/my-audio-book.m4b"

This splits the file data/my-audio-book.m4b into an mp3 file for each chapter, writing the files into data/my-audio-book_splitted/.

Cue sheet splitting (experimental)

If you would like to split a flac file containing multiple tracks, a cue sheet with the exact filename of the flac is required (my-album.flac requires my-album.cue):

# my-album.cue is automatically found and used for splitting
m4b-tool split --audio-format=mp3 --audio-bitrate=192k --audio-channels=2 --audio-samplerate=48000 "data/my-album.flac"

Reference

For all options, see m4b-tool split --help:

.chapters.txt instead of embedded chapters for splitting -h, --help Display this help message -q, --quiet Do not output any message -V, --version Display this application version --ansi Force ANSI output --no-ansi Disable ANSI output -n, --no-interaction Do not ask any interactive question -v|vv|vvv, --verbose Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug Help: Split an m4b into multiple m4b or mp3 files by chapter ">
Description:
  Splits an m4b file into parts

Usage:
  split [options] [--] 

Arguments:
  input                                          Input file or folder

Options:
      --logfile[=LOGFILE]                        file to dump all output [default: ""]
      --debug                                    enable debug mode - sets verbosity to debug, logfile to m4b-tool.log and temporary files are not deleted
  -f, --force                                    force overwrite of existing files
      --no-cache                                 do not use cached values and clear cache completely
      --ffmpeg-threads[=FFMPEG-THREADS]          specify -threads parameter for ffmpeg [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"]
      --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 (mono, stereo): aac_he, aac_he_v2  [default: ""]
      --adjust-for-ipod                          auto adjust bitrate and sampling rate for ipod, if track is to long (may lead to poor quality)
      --name[=NAME]                              provide a custom audiobook name, otherwise the existing metadata will be used [default: ""]
      --sortname[=SORTNAME]                      provide a custom audiobook name, that is used only for sorting purposes [default: ""]
      --album[=ALBUM]                            provide a custom audiobook album, otherwise the existing metadata for name will be used [default: ""]
      --sortalbum[=SORTALBUM]                    provide a custom audiobook album, that is used only for sorting purposes [default: ""]
      --artist[=ARTIST]                          provide a custom audiobook artist, otherwise the existing metadata will be used [default: ""]
      --sortartist[=SORTARTIST]                  provide a custom audiobook artist, that is used only for sorting purposes [default: ""]
      --genre[=GENRE]                            provide a custom audiobook genre, otherwise the existing metadata will be used [default: ""]
      --writer[=WRITER]                          provide a custom audiobook writer, otherwise the existing metadata will be used [default: ""]
      --albumartist[=ALBUMARTIST]                provide a custom audiobook albumartist, otherwise the existing metadata will be used [default: ""]
      --year[=YEAR]                              provide a custom audiobook year, otherwise the existing metadata will be used [default: ""]
      --cover[=COVER]                            provide a custom audiobook cover, otherwise the existing metadata will be used
      --description[=DESCRIPTION]                provide a custom audiobook short description, otherwise the existing metadata will be used
      --longdesc[=LONGDESC]                      provide a custom audiobook long description, otherwise the existing metadata will be used
      --comment[=COMMENT]                        provide a custom audiobook comment, otherwise the existing metadata will be used
      --copyright[=COPYRIGHT]                    provide a custom audiobook copyright, otherwise the existing metadata will be used
      --encoded-by[=ENCODED-BY]                  provide a custom audiobook encoded-by, otherwise the existing metadata will be used
      --series[=SERIES]                          provide a custom audiobook series, this pseudo tag will be used to auto create sort order (e.g. Harry Potter or The Kingkiller Chronicles)
      --series-part[=SERIES-PART]                provide a custom audiobook series part, this pseudo tag will be used to auto create sort order (e.g. 1 or 2.5)
      --skip-cover                               skip extracting and embedding covers
      --fix-mime-type                            try to fix MIME-type (e.g. from video/mp4 to audio/mp4) - this is needed for some players to prevent video window
  -o, --output-dir[=OUTPUT-DIR]                  output directory [default: ""]
  -p, --filename-template[=FILENAME-TEMPLATE]    filename twig-template for output file naming [default: "{{\"%03d\"|format(track)}}-{{title|raw}}"]
      --use-existing-chapters-file               use an existing manually edited chapters file 
     
      .chapters.txt instead of embedded chapters for splitting
  -h, --help                                     Display this help message
  -q, --quiet                                    Do not output any message
  -V, --version                                  Display this application version
      --ansi                                     Force ANSI output
      --no-ansi                                  Disable ANSI output
  -n, --no-interaction                           Do not ask any interactive question
  -v|vv|vvv, --verbose                           Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  Split an m4b into multiple m4b or mp3 files by chapter

     

filename-template reference

If you would like to use a custom filename template, the Twig template engine is provided. The following variables are available:

{{encoder}}
{{title}}
{{artist}}
{{genre}}
{{writer}}
{{album}}
{{disk}}
{{disks}}
{{albumArtist}}
{{year}}
{{track}}
{{tracks}}
{{cover}}
{{description}}
{{longDescription}}
{{comment}}
{{copyright}}
{{encodedBy}}
  • You can also use some Twig specific template extensions to pad or reformat these values. The default template is {{\"%03d\"|format(track)}}-{{title}}, which results in filenames like 001-mychapter
  • Slashes are interpreted as directory separators, so if you use a template {{year}}/{{artist}}/{{title}} the resulting directory and file is 2018/Joanne K. Rowling/Harry Potter 1
  • It is not recommended to use {{description}} or {{longdescription}} for filenames but they are also provided, if the field contains other information than intended
  • Special chars, that are forbidden in filenames are removed automatically

chapters

Many m4b audiobook files do not contain valid chapters for different reasons. m4b-tool can handle two cases:

  • Correct misplaced chapters by silence detection
  • Add chapters from an internet source (mostly for well known titles)

Misplaced chapters

In some cases there is a shift between the chapter mark and the real beginning of a chapter. m4b-tool could try to correct that by detecting silences and relocating the chapter to the nearest silence:

m4b-tool chapters --adjust-by-silence -o "data/destination-with-adjusted-chapters.m4b" "data/source-with-misplaced-chapters.m4b"

It won't work, if the shift is to large or if the chapters are strongly misplaced, but since everything is done automatically, it's worth a try, isn't it?

Too long chapters

Sometimes you have a file that contains valid chapters, but they are too long, so you would like to split them into sub-chapters. This is tricky, because the chapters command relays only on metadata and not on track length - so it won't work. BUT: There might be a workaround. In the latest pre-release since July 2020 you can do the following:

  • Put the source file into an empty directory, e.g. input/my-file.m4b (this is important, don't skip this step!)
  • Run m4b-tool merge -v --no-conversion --max-chapter-length=300,900 "input/" -o "output/my-rechaptered-file.m4b"

Because of --no-conversion the chaptering process is lossless, but it takes the existing chapters as input and recalculates it based on the --max-chapter-length parameter and a new silence detection.

No chapters at all

If you have a well known audiobook, like Harry Potter and the Philosopher’s Stone, you might be lucky that it is on musicbrainz.

In this case m4b-tool can try to correct the chapter information using silence detection and the musicbrainz data.

Since this is not a trivial task and prone to error, m4b-tool offers some parameters to correct misplaced chapter positions manually.

A typical workflow

Getting the musicbrainz id

You have to find the exact musicbrainz id:

  • An easy way to find the book is to use the authors name or the readers name to search for it
  • Once you found the book of interest, click on the list entry to show further information
  • To get the musicbrainz id, open the details page and find the MBID (e.g. 8669da33-bf9c-47fe-adc9-23798a37b096)

Example: https://musicbrainz.org/work/8669da33-bf9c-47fe-adc9-23798a37b096

MBID: 8669da33-bf9c-47fe-adc9-23798a37b096

Finding main chapters

After getting the MBID you should find the main chapter points (where the name of the current chapter name is read aloud by the author).

m4b-tool chapters --merge-similar --first-chapter-offset 4000 --last-chapter-offset 3500 -m 8669da33-bf9c-47fe-adc9-23798a37b096 "../data/harry-potter-1.m4b"

Explanation:

  • --merge-similar: merges all similar chapters (e.g. The Boy Who Lived, Part 1 and The Boy Who Lived, Part 2 will be merged to The Boy Who Lived)
  • --first-chapter-offset: creates an start offset chapter called Offset First Chapter with a length of 4 seconds for skipping intros (e.g. audible, etc.)
  • --last-chapter-offset: creates an end offset chapter called Offset Last Chapter with a length of 3,5 seconds for skipping outros (e.g. audible, etc.)
  • -m: MBID

Finding misplaced main chapters

Now listen to the audiobook an go through the chapters. Lets assume, all but 2 chapters were detected correctly. The two misplaced chapters are chapter number 6 and 9.

To find the real position of chapters 6 and 9 invoke:

m4b-tool chapter --find-misplaced-chapters 5,8  --merge-similar --first-chapter-offset 4000 --last-chapter-offset 3500 -m 8669da33-bf9c-47fe-adc9-23798a37b096 "../data/harry-potter-1.m4b"

Explanation: --find-misplaced-chapters: Comma separated list of chapter numbers, that were not detected correctly.

Now m4b-tool will generate a potential chapter for every silence around the used chapter mark to find the right chapter position.

Listen to the audiobook again and find the right chapter position. Note them down.

Manually adjust misplaced chapters

Next run the full chapter detection with the --no-chapter-import option, which prevents writing the chapters directly to the file.

m4b-tool chapter --no-chapter-import --first-chapter-offset 4000 --last-chapter-offset 3500 -m 8669da33-bf9c-47fe-adc9-23798a37b096 "../data/harry-potter-1.m4b"

To Adjust misplaced chapters, do the following:

  • Change the start position of all misplaced chapters manually in the file ../data/harry-potter-1.chapters.txt
  • Import the corrected chapters with mp4chaps -i ../data/harry-potter-1.m4b

Listen to harry-potter-1.m4b again, now the chapters should be at the correct position.

Troubleshooting

If none of the chapters are detected correctly, this can have different reasons:

  • The silence parts of this audiobook are too short for detection. To adjust the minimum silence length, use --silence-min-length 1000 setting the silence length to 1 second.
    • Caution: To low values can lead to misplaced chapters and increased detection time.
  • You provided the wrong MBID
  • There is too much background noise in this specific audiobook, so that silences cannot be detected

Reference

For all options, see m4b-tool chapters --help:

Description:
  Adds chapters to m4b file

Usage:
  chapters [options] [--] 

Arguments:
  input                                                      Input file or folder

Options:
      --logfile[=LOGFILE]                                    file to dump all output [default: ""]
      --debug                                                enable debug mode - sets verbosity to debug, logfile to m4b-tool.log and temporary files are not deleted
  -f, --force                                                force overwrite of existing files
      --no-cache                                             do not use cached values and clear cache completely
      --ffmpeg-threads[=FFMPEG-THREADS]                      specify -threads parameter for ffmpeg [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"]
  -m, --musicbrainz-id=MUSICBRAINZ-ID                        musicbrainz id so load chapters from
  -s, --merge-similar                                        merge similar chapter names
  -o, --output-file[=OUTPUT-FILE]                            write chapters to this output file [default: ""]
      --adjust-by-silence                                    will try to adjust chapters of a file by silence detection and existing chapter marks
      --find-misplaced-chapters[=FIND-MISPLACED-CHAPTERS]    mark silence around chapter numbers that where not detected correctly, e.g. 8,15,18 [default: ""]
      --find-misplaced-offset[=FIND-MISPLACED-OFFSET]        mark silence around chapter numbers with this offset seconds maximum [default: 120]
      --find-misplaced-tolerance[=FIND-MISPLACED-TOLERANCE]  mark another chapter with this offset before each silence to compensate ffmpeg mismatches [default: -4000]
      --no-chapter-numbering                                 do not append chapter number after name, e.g. My Chapter (1)
      --no-chapter-import                                    do not import chapters into m4b-file, just create chapters.txt
      --chapter-pattern[=CHAPTER-PATTERN]                    regular expression for matching chapter name [default: "/^[^:]+[1-9][0-9]*:[\s]*(.*),.*[1-9][0-9]*[\s]*$/i"]
      --chapter-replacement[=CHAPTER-REPLACEMENT]            regular expression replacement for matching chapter name [default: "$1"]
      --chapter-remove-chars[=CHAPTER-REMOVE-CHARS]          remove these chars from chapter name [default: "„“”"]
      --first-chapter-offset[=FIRST-CHAPTER-OFFSET]          milliseconds to add after silence on chapter start [default: 0]
      --last-chapter-offset[=LAST-CHAPTER-OFFSET]            milliseconds to add after silence on chapter start [default: 0]
  -h, --help                                                 Display this help message
  -q, --quiet                                                Do not output any message
  -V, --version                                              Display this application version
      --ansi                                                 Force ANSI output
      --no-ansi                                              Disable ANSI output
  -n, --no-interaction                                       Do not ask any interactive question
  -v|vv|vvv, --verbose                                       Increase the verbosity of messages: 1 for normal output, 2 for more verbose output and 3 for debug

Help:
  Can add Chapters to m4b files via different types of inputs

Latest release

m4b-tool is a one-man-project, so sometimes it evolves quickly and often nothing happens. If you have reported an issue and it is marked as fixed, there might be no stable release for a long time. That's why now there is a latest tag in combination with a Pre-Release for testing purposes. These releases always contain the most recent builds with all available fixes and new features. Mostly untested, there may be new bugs, non-functional features or - pretty unlikely - critical issues with the risk of data loss. Feedback is always welcome, but don't expect that these are fixed quickly.

To get the Pre-Release, go to https://github.com/sandreas/m4b-tool/releases/tag/latest and download the m4b-tool.tar.gz or if using docker rebuild the image with:

docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=
     
       -t m4b-tool

     

Building from source

m4b-tool contains a build script, which will create an executable m4b-tool.phar in the dist folder. Composer for PHP is required, so after installing composer, run following commands in project root folder:

Linux / Unix

Install Dependencies (Ubuntu)

sudo apt install ffmpeg mp4v2-utils fdkaac php-cli composer phpunit php-mbstring

Build

composer install
./build

macOS

Install Dependencies (brew)

brew update
brew install [email protected] phpunit
brew link [email protected]

Build

composer install
./build

Windows

composer install
build

#f03c15 Request for help - especially german users

Right now, I'm experimenting with speech recognition and speech to text using this project

This is for a feature to automatically add chapter names by speech recognition. I'm not sure this will be ever working as expected, but right now I'm pretty confident, it is possible to do the following, if there are enough speech samples in a specific language:

  • Extract chapter names and first sentences of a chapter from an ebook
  • Detect all silences in the audiobook
  • Perform a speech to text for the first 30 seconds after the silence
  • Compare it with the text parts of the ebook, mark the chapter positions and add real chapters names

To do that and improve the german speech recognition, I would really appreciate YOUR help on:

https://voice.mozilla.org/de (german)

No account is needed to help

You can support mozilla DeepSpeech to better support german speech recognition by just verifying sentences after listening or, even more important, reading out loud and uploading sentences. I try to add a few ones every day, its really easy and quite fun. At the moment the german speech recognition is not good enough for the algorithm, but I will check out every now and then - as soon the recognition is working good enough, I'll go on with this feature.

Comments
  • m4b-tool doesn't convert on RPi

    m4b-tool doesn't convert on RPi

    Hello,

    I've been using m4b-tool for some time on my debian VM and it works like a charm. In an effort to move it from my VM and have it online 24/7, I installed it on my RPi 4.

    I used the docker install, I validated the m4b using; docker run -it --rm -u $(id -u):$(id -g) -v "$(pwd)":/mnt m4b-tool --version returns: m4b-tool v.0.4.2

    But when I try to use the merge command, I get this error everytime: `== load input files == reading metadata and streaminfo for file /mnt/test/test.mp3 ffmpeg -hide_banner -i /mnt/test/test.mp3 -f ffmetadata - /usr/local/bin/ffmpeg: line 1: syntax error: unexpected "("

    /usr/local/bin/ffmpeg: line 1: syntax error: unexpected "("

    ffmpeg -hide_banner -i /mnt/test/test.mp3 -f null - /usr/local/bin/ffmpeg: line 1: syntax error: unexpected "("

    /usr/local/bin/ffmpeg: line 1: syntax error: unexpected "("

    cover not found or not specified searching for description.txt in test checking file test/description.txt, realpath: file description.txt not found or too big preparing conversion with 4 simultaneous jobs, please wait... 0 remaining / 1 total, preparing next task | could not convert /mnt/test/test.mp3 to test-tmpfiles/1-test-finished.m4b trace: #0 phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/MergeCommand.php(479): M4bTool\Command\MergeCommand->convertInputFiles() #1 phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/MergeCommand.php(362): M4bTool\Command\MergeCommand->processInputFiles() #2 phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/MergeCommand.php(194): M4bTool\Command\MergeCommand->processFiles() #3 phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Command/Command.php(255): M4bTool\Command\MergeCommand->execute() #4 phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php(908): Symfony\Component\Console\Command\Command->run() #5 phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php(269): Symfony\Component\Console\Application->doRunCommand() #6 phar:///usr/local/bin/m4b-tool/vendor/symfony/console/Application.php(145): Symfony\Component\Console\Application->doRun() #7 phar:///usr/local/bin/m4b-tool/bin/m4b-tool.php(32): Symfony\Component\Console\Application->run() #8 /usr/local/bin/m4b-tool(10): require('phar:///usr/loc...') #9 {main}`

    Any help would be appreciated.

    opened by xtinct101 46
  • Feature Request: Support for Overdrive Chapters (mp3, Tag with XML)

    Feature Request: Support for Overdrive Chapters (mp3, Tag with XML)

    Overdrive Audiobooks are split into multiple part, each part has chapter embedded in them, right now im using inaudible to create chaptalized m4b file, is it possible to use those small chapter instead of part when creating m4b

    opened by cox890 31
  • Docker build fails on M1 Mac

    Docker build fails on M1 Mac

    I recently got a new M1 Macbook Air and tried to run a build on this project. It ended up failing with the following error:

    [+] Building 7.4s (9/14)                                                                                                                                                                                                                                                                                 
     => [internal] load build definition from Dockerfile                                                                                                                                                                                                                                                0.0s
     => => transferring dockerfile: 37B                                                                                                                                                                                                                                                                 0.0s
     => [internal] load .dockerignore                                                                                                                                                                                                                                                                   0.0s
     => => transferring context: 34B                                                                                                                                                                                                                                                                    0.0s
     => [internal] load metadata for docker.io/library/alpine:3.9.2                                                                                                                                                                                                                                     0.2s
     => FROM docker.io/mwader/static-ffmpeg:4.2.2                                                                                                                                                                                                                                                       0.3s
     => => resolve docker.io/mwader/static-ffmpeg:4.2.2                                                                                                                                                                                                                                                 0.3s
     => [internal] load build context                                                                                                                                                                                                                                                                   0.0s
     => => transferring context: 56B                                                                                                                                                                                                                                                                    0.0s
     => CACHED [builder 1/2] FROM docker.io/library/alpine:3.9.2@sha256:644fcb1a676b5165371437feaa922943aaf7afcfa8bfee4472f6860aad1ef2a0                                                                                                                                                                0.0s
     => CACHED [stage-1 2/8] RUN echo "---- INSTALL RUNTIME PACKAGES ----" &&   apk add --no-cache --update --upgrade   libstdc++   php7-cli   php7-dom   php7-json   php7-xml   php7-mbstring   php7-phar   php7-tokenizer   php7-xmlwriter   php7-openssl   && echo "date.timezone = UTC" >> /etc/ph  0.0s
     => CACHED [stage-1 3/8] COPY --from=mwader/static-ffmpeg:4.2.2 /ffmpeg /usr/local/bin/                                                                                                                                                                                                             0.0s
     => ERROR [builder 2/2] RUN echo "---- INSTALL BUILD DEPENDENCIES ----"     && apk add --no-cache --update --upgrade --virtual=build-dependencies     autoconf     libtool     automake     boost-dev     build-base     gcc     git     tar     wget && echo "---- COMPILE SANDREAS MP4V2 (for so  6.9s
    ------                                                                                                                                                                                                                                                                                                   
     > [builder 2/2] RUN echo "---- INSTALL BUILD DEPENDENCIES ----"     && apk add --no-cache --update --upgrade --virtual=build-dependencies     autoconf     libtool     automake     boost-dev     build-base     gcc     git     tar     wget && echo "---- COMPILE SANDREAS MP4V2 (for sort-title, sort-album and sort-author) ----"   && cd /tmp/   && wget https://github.com/sandreas/mp4v2/archive/master.zip   && unzip master.zip   && cd mp4v2-master   && ./configure &&   make -j4 &&   make install && make distclean && echo "---- PREPARE FDKAAC-DEPENDENCIES ----"   && cd /tmp/   && wget -O fdk-aac.tar.gz "https://github.com/mstorsjo/fdk-aac/archive/v2.0.1.tar.gz"   && tar xfz fdk-aac.tar.gz   && cd fdk-aac-* && ./autogen.sh && ./configure --enable-static --disable-shared && make -j$(nproc) install && echo "---- COMPILE FDKAAC ENCODER (executable binary for usage of --audio-profile) ----"     && cd /tmp/     && wget https://github.com/nu774/fdkaac/archive/1.0.0.tar.gz     && tar xzf 1.0.0.tar.gz     && cd fdkaac-1.0.0     && autoreconf -i && ./configure --enable-static --disable-shared && make -j4 && make install && rm -rf /tmp/* && echo "---- REMOVE BUILD DEPENDENCIES (to keep image small) ----"     && apk del --purge build-dependencies && rm -rf /tmp/*:                                                                                                                                                                                                                           
    #8 0.171 ---- INSTALL BUILD DEPENDENCIES ----
    #8 0.173 fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/aarch64/APKINDEX.tar.gz
    #8 0.329 fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/aarch64/APKINDEX.tar.gz
    #8 0.470 (1/79) Upgrading musl (1.1.20-r3 -> 1.1.20-r6)
    #8 0.488 (2/79) Upgrading libcrypto1.1 (1.1.1a-r1 -> 1.1.1k-r0)
    #8 0.523 (3/79) Upgrading libssl1.1 (1.1.1a-r1 -> 1.1.1k-r0)
    #8 0.539 (4/79) Upgrading ca-certificates-cacert (20190108-r0 -> 20191127-r2)
    #8 0.553 (5/79) Installing m4 (1.4.18-r1)
    #8 0.566 (6/79) Installing libbz2 (1.0.6-r7)
    #8 0.577 (7/79) Installing perl (5.26.3-r1)
    #8 0.794 (8/79) Installing autoconf (2.69-r2)
    #8 0.817 (9/79) Installing ncurses-terminfo-base (6.1_p20190105-r0)
    #8 0.829 (10/79) Installing ncurses-terminfo (6.1_p20190105-r0)
    #8 0.946 (11/79) Installing ncurses-libs (6.1_p20190105-r0)
    #8 0.960 (12/79) Installing readline (7.0.003-r1)
    #8 0.972 (13/79) Installing bash (4.4.19-r1)
    #8 0.990 Executing bash-4.4.19-r1.post-install
    #8 0.992 (14/79) Installing libltdl (2.4.6-r5)
    #8 1.005 (15/79) Installing libtool (2.4.6-r5)
    #8 1.030 (16/79) Installing automake (1.16.1-r0)
    #8 1.052 (17/79) Installing linux-headers (4.18.13-r1)
    #8 1.116 (18/79) Installing boost-atomic (1.67.0-r2)
    #8 1.126 (19/79) Installing boost-system (1.67.0-r2)
    #8 1.140 (20/79) Installing libgcc (8.3.0-r0)
    #8 1.151 (21/79) Installing boost-chrono (1.67.0-r2)
    #8 1.165 (22/79) Installing boost-container (1.67.0-r2)
    #8 1.180 (23/79) Installing boost-context (1.67.0-r2)
    #8 1.191 (24/79) Installing boost-contract (1.67.0-r2)
    #8 1.203 (25/79) Installing boost-thread (1.67.0-r2)
    #8 1.217 (26/79) Installing boost-coroutine (1.67.0-r2)
    #8 1.231 (27/79) Installing boost-date_time (1.67.0-r2)
    #8 1.245 (28/79) Installing boost-filesystem (1.67.0-r2)
    #8 1.260 (29/79) Installing boost-fiber (1.67.0-r2)
    #8 1.277 (30/79) Installing boost-regex (1.67.0-r2)
    #8 1.301 (31/79) Installing boost-graph (1.67.0-r2)
    #8 1.314 (32/79) Installing boost-iostreams (1.67.0-r2)
    #8 1.328 (33/79) Installing boost-math (1.67.0-r2)
    #8 1.356 (34/79) Installing boost-prg_exec_monitor (1.67.0-r2)
    #8 1.368 (35/79) Installing boost-program_options (1.67.0-r2)
    #8 1.386 (36/79) Installing expat (2.2.8-r0)
    #8 1.397 (37/79) Installing libffi (3.2.1-r6)
    #8 1.412 (38/79) Installing gdbm (1.13-r1)
    #8 1.424 (39/79) Installing xz-libs (5.2.4-r0)
    #8 1.436 (40/79) Installing sqlite-libs (3.28.0-r3)
    #8 1.456 (41/79) Installing python3 (3.6.9-r3)
    #8 1.881 (42/79) Installing boost-python3 (1.67.0-r2)
    #8 1.895 (43/79) Installing python2 (2.7.18-r0)
    #8 2.194 (44/79) Installing boost-python (1.67.0-r2)
    #8 2.208 (45/79) Installing boost-random (1.67.0-r2)
    #8 2.220 (46/79) Installing boost-serialization (1.67.0-r2)
    #8 2.233 (47/79) Installing boost-signals (1.67.0-r2)
    #8 2.247 (48/79) Installing boost-unit_test_framework (1.67.0-r2)
    #8 2.267 (49/79) Installing boost-wave (1.67.0-r2)
    #8 2.285 (50/79) Installing boost-wserialization (1.67.0-r2)
    #8 2.296 (51/79) Installing libstdc++ (8.3.0-r0)
    #8 2.315 (52/79) Installing boost (1.67.0-r2)
    #8 2.353 (53/79) Installing boost-dev (1.67.0-r2)
    #8 3.233 (54/79) Installing binutils (2.31.1-r2)
    #8 3.302 (55/79) Installing libmagic (5.36-r1)
    #8 3.325 (56/79) Installing file (5.36-r1)
    #8 3.336 (57/79) Installing gmp (6.1.2-r1)
    #8 3.352 (58/79) Installing isl (0.18-r0)
    #8 3.373 (59/79) Installing libgomp (8.3.0-r0)
    #8 3.389 (60/79) Installing libatomic (8.3.0-r0)
    #8 3.402 (61/79) Installing mpfr3 (3.1.5-r1)
    #8 3.413 (62/79) Installing mpc1 (1.0.3-r1)
    #8 3.425 (63/79) Installing gcc (8.3.0-r0)
    #8 3.838 (64/79) Installing musl-dev (1.1.20-r6)
    #8 3.925 (65/79) Installing libc-dev (0.7.1-r0)
    #8 3.936 (66/79) Installing g++ (8.3.0-r0)
    #8 4.287 (67/79) Installing make (4.2.1-r2)
    #8 4.300 (68/79) Installing fortify-headers (1.0-r0)
    #8 4.315 (69/79) Installing build-base (0.5-r1)
    #8 4.329 (70/79) Installing ca-certificates (20191127-r2)
    #8 4.346 (71/79) Installing nghttp2-libs (1.35.1-r2)
    #8 4.357 (72/79) Installing libssh2 (1.9.0-r1)
    #8 4.372 (73/79) Installing libcurl (7.64.0-r5)
    #8 4.387 (74/79) Installing pcre2 (10.32-r1)
    #8 4.401 (75/79) Installing git (2.20.4-r0)
    #8 4.521 (76/79) Installing tar (1.32-r0)
    #8 4.535 (77/79) Installing wget (1.20.3-r0)
    #8 4.552 (78/79) Installing build-dependencies (0)
    #8 4.552 (79/79) Upgrading musl-utils (1.1.20-r3 -> 1.1.20-r6)
    #8 4.569 Executing busybox-1.29.3-r10.trigger
    #8 4.572 Executing ca-certificates-20191127-r2.trigger
    #8 4.600 OK: 494 MiB in 88 packages
    #8 4.611 ---- COMPILE SANDREAS MP4V2 (for sort-title, sort-album and sort-author) ----
    #8 4.612 --2021-05-17 16:17:05--  https://github.com/sandreas/mp4v2/archive/master.zip
    #8 4.618 Resolving github.com... 140.82.114.4
    #8 4.631 Connecting to github.com|140.82.114.4|:443... connected.
    #8 4.681 HTTP request sent, awaiting response... 302 Found
    #8 4.784 Location: https://codeload.github.com/sandreas/mp4v2/zip/master [following]
    #8 4.784 --2021-05-17 16:17:05--  https://codeload.github.com/sandreas/mp4v2/zip/master
    #8 4.784 Resolving codeload.github.com... 140.82.113.9
    #8 4.787 Connecting to codeload.github.com|140.82.113.9|:443... connected.
    #8 4.839 HTTP request sent, awaiting response... 200 OK
    #8 4.867 Length: 2862888 (2.7M) [application/zip]
    #8 4.868 Saving to: 'master.zip'
    #8 4.868 
    #8 4.868      0K .......... .......... .......... .......... ..........  1% 1.02M 3s
    #8 4.916     50K .......... .......... .......... .......... ..........  3% 2.09M 2s
    #8 4.939    100K .......... .......... .......... .......... ..........  5% 20.3M 1s
    #8 4.941    150K .......... .......... .......... .......... ..........  7% 9.78M 1s
    #8 4.961    200K .......... .......... .......... .......... ..........  8% 2.73M 1s
    #8 4.965    250K .......... .......... .......... .......... .......... 10% 16.3M 1s
    #8 4.967    300K .......... .......... .......... .......... .......... 12% 16.9M 1s
    #8 4.970    350K .......... .......... .......... .......... .......... 14% 62.3M 1s
    #8 4.971    400K .......... .......... .......... .......... .......... 16% 3.39M 1s
    #8 4.986    450K .......... .......... .......... .......... .......... 17% 13.2M 1s
    #8 4.989    500K .......... .......... .......... .......... .......... 19% 73.7M 0s
    #8 4.990    550K .......... .......... .......... .......... .......... 21% 16.4M 0s
    #8 4.994    600K .......... .......... .......... .......... .......... 23%  141M 0s
    #8 4.994    650K .......... .......... .......... .......... .......... 25%  145M 0s
    #8 4.994    700K .......... .......... .......... .......... .......... 26% 85.8M 0s
    #8 4.995    750K .......... .......... .......... .......... .......... 28% 35.3M 0s
    #8 4.995    800K .......... .......... .......... .......... .......... 30% 4.22M 0s
    #8 5.007    850K .......... .......... .......... .......... .......... 32% 9.73M 0s
    #8 5.012    900K .......... .......... .......... .......... .......... 33% 45.4M 0s
    #8 5.013    950K .......... .......... .......... .......... .......... 35% 22.0M 0s
    #8 5.015   1000K .......... .......... .......... .......... .......... 37% 30.7M 0s
    #8 5.017   1050K .......... .......... .......... .......... .......... 39%  166M 0s
    #8 5.017   1100K .......... .......... .......... .......... .......... 41% 67.4M 0s
    #8 5.018   1150K .......... .......... .......... .......... .......... 42% 27.3M 0s
    #8 5.020   1200K .......... .......... .......... .......... .......... 44% 70.9M 0s
    #8 5.020   1250K .......... .......... .......... .......... .......... 46% 39.7M 0s
    #8 5.022   1300K .......... .......... .......... .......... .......... 48% 25.5M 0s
    #8 5.024   1350K .......... .......... .......... .......... .......... 50%  121M 0s
    #8 5.024   1400K .......... .......... .......... .......... .......... 51% 49.1M 0s
    #8 5.025   1450K .......... .......... .......... .......... .......... 53% 33.1M 0s
    #8 5.026   1500K .......... .......... .......... .......... .......... 55% 23.7M 0s
    #8 5.028   1550K .......... .......... .......... .......... .......... 57%  161M 0s
    #8 5.029   1600K .......... .......... .......... .......... .......... 59% 37.7M 0s
    #8 5.030   1650K .......... .......... .......... .......... .......... 60% 12.8M 0s
    #8 5.034   1700K .......... .......... .......... .......... .......... 62% 33.2M 0s
    #8 5.035   1750K .......... .......... .......... .......... .......... 64% 27.9M 0s
    #8 5.037   1800K .......... .......... .......... .......... .......... 66% 74.7M 0s
    #8 5.038   1850K .......... .......... .......... .......... .......... 67% 44.6M 0s
    #8 5.039   1900K .......... .......... .......... .......... .......... 69% 45.1M 0s
    #8 5.039   1950K .......... .......... .......... .......... .......... 71%  282M 0s
    #8 5.040   2000K .......... .......... .......... .......... .......... 73% 15.3M 0s
    #8 5.043   2050K .......... .......... .......... .......... .......... 75% 30.3M 0s
    #8 5.045   2100K .......... .......... .......... .......... .......... 76%  188M 0s
    #8 5.045   2150K .......... .......... .......... .......... .......... 78% 56.8M 0s
    #8 5.046   2200K .......... .......... .......... .......... .......... 80%  123M 0s
    #8 5.046   2250K .......... .......... .......... .......... .......... 82% 36.7M 0s
    #8 5.048   2300K .......... .......... .......... .......... .......... 84%  280M 0s
    #8 5.048   2350K .......... .......... .......... .......... .......... 85% 53.9M 0s
    #8 5.048   2400K .......... .......... .......... .......... .......... 87% 45.0M 0s
    #8 5.050   2450K .......... .......... .......... .......... .......... 89% 89.3M 0s
    #8 5.050   2500K .......... .......... .......... .......... .......... 91% 68.8M 0s
    #8 5.051   2550K .......... .......... .......... .......... .......... 92% 55.1M 0s
    #8 5.052   2600K .......... .......... .......... .......... .......... 94% 49.9M 0s
    #8 5.053   2650K .......... .......... .......... .......... .......... 96% 63.0M 0s
    #8 5.053   2700K .......... .......... .......... .......... .......... 98% 81.2M 0s
    #8 5.054   2750K .......... .......... .......... .......... .....     100% 67.5M=0.2s
    #8 5.055 
    #8 5.055 2021-05-17 16:17:05 (14.6 MB/s) - 'master.zip' saved [2862888/2862888]
    #8 5.055 
    #8 5.056 Archive:  master.zip
    #8 5.071    creating: mp4v2-master/
    #8 5.071   inflating: mp4v2-master/.gitignore
    #8 5.071   inflating: mp4v2-master/CHANGES.logging
    #8 5.071   inflating: mp4v2-master/COPYING
    #8 5.071   inflating: mp4v2-master/GNUmakefile
    #8 5.071   inflating: mp4v2-master/GNUmakefile.am
    #8 5.071   inflating: mp4v2-master/GNUmakefile.in
    #8 5.071   inflating: mp4v2-master/INSTALL
    #8 5.071   inflating: mp4v2-master/README.md
    #8 5.071   inflating: mp4v2-master/aclocal.m4
    #8 5.071    creating: mp4v2-master/autoaux/
    #8 5.071   inflating: mp4v2-master/autoaux/config.guess
    #8 5.071   inflating: mp4v2-master/autoaux/config.sub
    #8 5.071   inflating: mp4v2-master/autoaux/depcomp
    #8 5.071   inflating: mp4v2-master/autoaux/install-sh
    #8 5.071   inflating: mp4v2-master/autoaux/ltmain.sh
    #8 5.071   inflating: mp4v2-master/autoaux/missing
    #8 5.071   inflating: mp4v2-master/configure
    #8 5.071   inflating: mp4v2-master/configure.ac
    #8 5.071    creating: mp4v2-master/doc/
    #8 5.071   inflating: mp4v2-master/doc/GNUmakefile.mk
    #8 5.071   inflating: mp4v2-master/doc/MP4.3
    #8 5.071   inflating: mp4v2-master/doc/MP4AddRtpESConfigurationPacket.3
    #8 5.071   inflating: mp4v2-master/doc/MP4AddRtpHint.3
    #8 5.071   inflating: mp4v2-master/doc/MP4AddRtpImmediateData.3
    #8 5.071   inflating: mp4v2-master/doc/MP4AddRtpPacket.3
    #8 5.072   inflating: mp4v2-master/doc/MP4AddRtpSampleData.3
    #8 5.072   inflating: mp4v2-master/doc/MP4AddRtpVideoHint.3
    #8 5.072   inflating: mp4v2-master/doc/MP4AddTrackEdit.3
    #8 5.072   inflating: mp4v2-master/doc/MP4AppendHintTrackSdp.3
    #8 5.072   inflating: mp4v2-master/doc/MP4AppendSessionSdp.3
    #8 5.072   inflating: mp4v2-master/doc/MP4BinaryToBase16.3
    #8 5.072   inflating: mp4v2-master/doc/MP4BinaryToBase64.3
    #8 5.072   inflating: mp4v2-master/doc/MP4CloneTrack.3
    #8 5.072   inflating: mp4v2-master/doc/MP4ConvertFromMovieDuration.3
    #8 5.072   inflating: mp4v2-master/doc/MP4ConvertFromTrackTimestamp.3
    #8 5.072   inflating: mp4v2-master/doc/MP4ConvertToTrackTimestamp.3
    #8 5.072   inflating: mp4v2-master/doc/MP4CopyTrack.3
    #8 5.072   inflating: mp4v2-master/doc/MP4DeleteTrack.3
    #8 5.072   inflating: mp4v2-master/doc/MP4DeleteTrackEdit.3
    #8 5.072   inflating: mp4v2-master/doc/MP4FindTrackId.3
    #8 5.072   inflating: mp4v2-master/doc/MP4FindTrackIndex.3
    #8 5.072   inflating: mp4v2-master/doc/MP4GetAudioProfileLevel.3
    #8 5.072   inflating: mp4v2-master/doc/MP4GetDuration.3
    #8 5.072   inflating: mp4v2-master/doc/MP4GetGraphicsProfileLevel.3
    #8 5.072   inflating: mp4v2-master/doc/MP4GetHintTrackReferenceTrackId.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetHintTrackRtpPayload.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetHintTrackSdp.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetNumberOfTracks.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetODProfileLevel.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetRtpHintNumberOfPackets.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetRtpPacketBFrame.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetRtpPacketTransmitOffset.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetRtpTimestampStart.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetSampleIdFromEditTime.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetSceneProfileLevel.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetSessionSdp.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackAudioMpeg4Type.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackAudioType.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackBitRate.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackDuration.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackESConfiguration.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackEditDuration.3
    #8 5.073   inflating: mp4v2-master/doc/MP4GetTrackEditDwell.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackEditMediaStart.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackEditStart.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackEditTotalDuration.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackFixedSampleDuration.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackNumberOfEdits.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackNumberOfSamples.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackVideoFrameRate.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackVideoHeight.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackVideoType.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetTrackVideoWidth.3
    #8 5.074   inflating: mp4v2-master/doc/MP4GetVideoProfileLevel.3
    #8 5.074   inflating: mp4v2-master/doc/MP4MakeIsmaCompliant.3
    #8 5.074   inflating: mp4v2-master/doc/MP4ReadRtpHint.3
    #8 5.074   inflating: mp4v2-master/doc/MP4ReadRtpPacket.3
    #8 5.074   inflating: mp4v2-master/doc/MP4ReadSampleFromEditTime.3
    #8 5.074   inflating: mp4v2-master/doc/MP4SetAudioProfileLevel.3
    #8 5.074   inflating: mp4v2-master/doc/MP4SetGraphicsProfileLevel.3
    #8 5.074   inflating: mp4v2-master/doc/MP4SetHintTrackRtpPayload.3
    #8 5.074   inflating: mp4v2-master/doc/MP4SetHintTrackSdp.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetODProfileLevel.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetRtpTimestampStart.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetSceneProfileLevel.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetSessionSdp.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetTrackESConfiguration.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetTrackEditDuration.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetTrackEditDwell.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetTrackEditMediaStart.3
    #8 5.076   inflating: mp4v2-master/doc/MP4SetVideoProfileLevel.3
    #8 5.076   inflating: mp4v2-master/doc/MP4WriteRtpHint.3
    #8 5.076    creating: mp4v2-master/doc/doxygen/
    #8 5.076   inflating: mp4v2-master/doc/doxygen/Doxyfile.m4
    #8 5.076   inflating: mp4v2-master/doc/doxygen/banner.png
    #8 5.076   inflating: mp4v2-master/doc/doxygen/footer.html.m4
    #8 5.076   inflating: mp4v2-master/doc/doxygen/header.html.m4
    #8 5.076   inflating: mp4v2-master/doc/doxygen/mainpage.h
    #8 5.076   inflating: mp4v2-master/doc/doxygen/project.css
    #8 5.076    creating: mp4v2-master/doc/html/
    #8 5.076   inflating: mp4v2-master/doc/html/banner.png
    #8 5.076   inflating: mp4v2-master/doc/html/footer.html.m4
    #8 5.076   inflating: mp4v2-master/doc/html/header.html.m4
    #8 5.077   inflating: mp4v2-master/doc/html/project.css
    #8 5.077    creating: mp4v2-master/doc/texi/
    #8 5.077   inflating: mp4v2-master/doc/texi/Authors.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/BuildRepository.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/BuildSource.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/Documentation.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/ReleaseNotes.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/ToolGuide.texi
    #8 5.077    creating: mp4v2-master/doc/texi/base/
    #8 5.077   inflating: mp4v2-master/doc/texi/base/article.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/base/glossary.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/base/guide.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/base/project.texi.m4
    #8 5.077    creating: mp4v2-master/doc/texi/changelog/
    #8 5.077   inflating: mp4v2-master/doc/texi/changelog/version-1.6.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/changelog/version-1.9.texi
    #8 5.077   inflating: mp4v2-master/doc/texi/changelog/version-2.0.texi
    #8 5.077    creating: mp4v2-master/doc/texi/releasenotes/
    #8 5.077   inflating: mp4v2-master/doc/texi/releasenotes/intro.developer.texi
    #8 5.078   inflating: mp4v2-master/doc/texi/releasenotes/intro.stable.texi
    #8 5.078    creating: mp4v2-master/doc/texi/tool/
    #8 5.078   inflating: mp4v2-master/doc/texi/tool/mp4art.texi
    #8 5.078   inflating: mp4v2-master/doc/texi/tool/mp4file.texi
    #8 5.078   inflating: mp4v2-master/doc/texi/tool/mp4track.texi
    #8 5.078    creating: mp4v2-master/example/
    #8 5.078    creating: mp4v2-master/example/itmf/
    #8 5.078   inflating: mp4v2-master/example/itmf/generic.c
    #8 5.078   inflating: mp4v2-master/example/itmf/tags.c
    #8 5.078    creating: mp4v2-master/example/provider/
    #8 5.078   inflating: mp4v2-master/example/provider/provider.c
    #8 5.078    creating: mp4v2-master/hudson/
    #8 5.078   inflating: mp4v2-master/hudson/buildWin.bat
    #8 5.078    creating: mp4v2-master/include/
    #8 5.078    creating: mp4v2-master/include/mp4v2/
    #8 5.078   inflating: mp4v2-master/include/mp4v2/chapter.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/file.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/file_prop.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/general.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/isma.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/itmf_generic.h
    #8 5.078   inflating: mp4v2-master/include/mp4v2/itmf_tags.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/mp4v2.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/platform.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/project.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/project.h.in
    #8 5.134   inflating: mp4v2-master/include/mp4v2/sample.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/streaming.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/track.h
    #8 5.134   inflating: mp4v2-master/include/mp4v2/track_prop.h
    #8 5.134    creating: mp4v2-master/lib/
    #8 5.134    creating: mp4v2-master/lib/mac/
    #8 5.134    creating: mp4v2-master/lib/mac/Release/
    #8 5.134   inflating: mp4v2-master/lib/mac/Release/libmp4v2.a
    #8 5.134    creating: mp4v2-master/libplatform/
    #8 5.134   inflating: mp4v2-master/libplatform/config.h.in
    #8 5.134   inflating: mp4v2-master/libplatform/endian.h
    #8 5.134   inflating: mp4v2-master/libplatform/impl.h
    #8 5.134    creating: mp4v2-master/libplatform/io/
    #8 5.134   inflating: mp4v2-master/libplatform/io/File.cpp
    #8 5.134   inflating: mp4v2-master/libplatform/io/File.h
    #8 5.134   inflating: mp4v2-master/libplatform/io/FileSystem.cpp
    #8 5.134   inflating: mp4v2-master/libplatform/io/FileSystem.h
    #8 5.134   inflating: mp4v2-master/libplatform/io/FileSystem_posix.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/io/FileSystem_win32.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/io/File_posix.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/io/File_win32.cpp
    #8 5.135    creating: mp4v2-master/libplatform/number/
    #8 5.135   inflating: mp4v2-master/libplatform/number/random.h
    #8 5.135   inflating: mp4v2-master/libplatform/number/random_posix.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/number/random_win32.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/platform.h
    #8 5.135   inflating: mp4v2-master/libplatform/platform_base.h
    #8 5.135   inflating: mp4v2-master/libplatform/platform_posix.h
    #8 5.135   inflating: mp4v2-master/libplatform/platform_win32.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/platform_win32.h
    #8 5.135   inflating: mp4v2-master/libplatform/platform_win32_impl.h
    #8 5.135    creating: mp4v2-master/libplatform/process/
    #8 5.135   inflating: mp4v2-master/libplatform/process/process.h
    #8 5.135   inflating: mp4v2-master/libplatform/process/process_posix.cpp
    #8 5.135   inflating: mp4v2-master/libplatform/process/process_win32.cpp
    #8 5.135    creating: mp4v2-master/libplatform/prog/
    #8 5.135   inflating: mp4v2-master/libplatform/prog/option.cpp
    #8 5.136   inflating: mp4v2-master/libplatform/prog/option.h
    #8 5.136    creating: mp4v2-master/libplatform/sys/
    #8 5.136   inflating: mp4v2-master/libplatform/sys/error.cpp
    #8 5.136   inflating: mp4v2-master/libplatform/sys/error.h
    #8 5.136   inflating: mp4v2-master/libplatform/targetver.h
    #8 5.136    creating: mp4v2-master/libplatform/time/
    #8 5.136   inflating: mp4v2-master/libplatform/time/time.cpp
    #8 5.136   inflating: mp4v2-master/libplatform/time/time.h
    #8 5.136   inflating: mp4v2-master/libplatform/time/time_posix.cpp
    #8 5.136   inflating: mp4v2-master/libplatform/time/time_win32.cpp
    #8 5.136   inflating: mp4v2-master/libplatform/warning.h
    #8 5.136    creating: mp4v2-master/libutil/
    #8 5.136   inflating: mp4v2-master/libutil/Database.cpp
    #8 5.136   inflating: mp4v2-master/libutil/Database.h
    #8 5.136   inflating: mp4v2-master/libutil/Timecode.cpp
    #8 5.136   inflating: mp4v2-master/libutil/Timecode.h
    #8 5.136   inflating: mp4v2-master/libutil/TrackModifier.cpp
    #8 5.136   inflating: mp4v2-master/libutil/TrackModifier.h
    #8 5.136   inflating: mp4v2-master/libutil/Utility.cpp
    #8 5.136   inflating: mp4v2-master/libutil/Utility.h
    #8 5.136   inflating: mp4v2-master/libutil/crc.cpp
    #8 5.136   inflating: mp4v2-master/libutil/crc.h
    #8 5.138   inflating: mp4v2-master/libutil/impl.h
    #8 5.138   inflating: mp4v2-master/libutil/other.cpp
    #8 5.138   inflating: mp4v2-master/libutil/other.h
    #8 5.138   inflating: mp4v2-master/libutil/util.h
    #8 5.138   inflating: mp4v2-master/macBuildReleaseLibs.sh
    #8 5.138    creating: mp4v2-master/maintainer/
    #8 5.138   inflating: mp4v2-master/maintainer/HOWTO-ADD_SOURCE.txt
    #8 5.138   inflating: mp4v2-master/maintainer/HOWTO-AUTOTOOLS.txt
    #8 5.138   inflating: mp4v2-master/maintainer/HOWTO-RELEASE.txt
    #8 5.138   inflating: mp4v2-master/maintainer/HOWTO-TEST.txt
    #8 5.138   inflating: mp4v2-master/maintainer/INTERNALS.txt
    #8 5.138   inflating: mp4v2-master/maintainer/LIBPLATFORM.txt
    #8 5.138   inflating: mp4v2-master/maintainer/NAMESPACES.txt
    #8 5.138   inflating: mp4v2-master/maintainer/SOURCE.txt
    #8 5.138    creating: mp4v2-master/mp4v2-Win/
    #8 5.138    creating: mp4v2-master/mp4v2-Win/include/
    #8 5.138    creating: mp4v2-master/mp4v2-Win/include/mp4v2/
    #8 5.138   inflating: mp4v2-master/mp4v2-Win/include/mp4v2/project.h
    #8 5.138    creating: mp4v2-master/mp4v2-Win/libmp4v2/
    #8 5.138   inflating: mp4v2-master/mp4v2-Win/libmp4v2/Version.rc
    #8 5.138   inflating: mp4v2-master/mp4v2-Win/libmp4v2/libmp4v2.vcxproj
    #8 5.139   inflating: mp4v2-master/mp4v2-Win/mp4v2.autopkg
    #8 5.139   inflating: mp4v2-master/mp4v2-Win/mp4v2.sln
    #8 5.139    creating: mp4v2-master/project/
    #8 5.139   inflating: mp4v2-master/project/htmlcombine.py
    #8 5.139   inflating: mp4v2-master/project/project.m4.in
    #8 5.139   inflating: mp4v2-master/project/project.m4sugar
    #8 5.139   inflating: mp4v2-master/project/xml2wiki.py
    #8 5.139    creating: mp4v2-master/src/
    #8 5.139   inflating: mp4v2-master/src/3gp.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_ac3.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_amr.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_avc1.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_avcC.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_chpl.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_colr.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_d263.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_dac3.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_damr.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_dref.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_elst.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_enca.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_encv.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_free.cpp
    #8 5.139   inflating: mp4v2-master/src/atom_ftab.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_ftyp.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_gmin.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_hdlr.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_hinf.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_hnti.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_href.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_mdat.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_mdhd.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_meta.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_mp4s.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_mp4v.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_mvhd.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_nmhd.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_ohdr.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_pasp.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_root.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_rtp.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_s263.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_sdp.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_sdtp.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_smi.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_sound.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_standard.cpp
    #8 5.141   inflating: mp4v2-master/src/atom_stbl.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_stdp.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_stsc.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_stsd.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_stsz.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_stz2.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_text.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_tfhd.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_tkhd.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_treftype.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_trun.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_tx3g.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_udta.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_url.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_urn.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_uuid.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_video.cpp
    #8 5.142   inflating: mp4v2-master/src/atom_vmhd.cpp
    #8 5.142   inflating: mp4v2-master/src/atoms.h
    #8 5.142    creating: mp4v2-master/src/bmff/
    #8 5.142   inflating: mp4v2-master/src/bmff/bmff.h
    #8 5.142   inflating: mp4v2-master/src/bmff/impl.h
    #8 5.142   inflating: mp4v2-master/src/bmff/typebmff.cpp
    #8 5.142   inflating: mp4v2-master/src/bmff/typebmff.h
    #8 5.146   inflating: mp4v2-master/src/cmeta.cpp
    #8 5.146   inflating: mp4v2-master/src/descriptors.cpp
    #8 5.146   inflating: mp4v2-master/src/descriptors.h
    #8 5.146   inflating: mp4v2-master/src/enum.h
    #8 5.146   inflating: mp4v2-master/src/enum.tcc
    #8 5.146   inflating: mp4v2-master/src/exception.cpp
    #8 5.146   inflating: mp4v2-master/src/exception.h
    #8 5.146   inflating: mp4v2-master/src/impl.h
    #8 5.146   inflating: mp4v2-master/src/isma.cpp
    #8 5.146    creating: mp4v2-master/src/itmf/
    #8 5.146   inflating: mp4v2-master/src/itmf/CoverArtBox.cpp
    #8 5.146   inflating: mp4v2-master/src/itmf/CoverArtBox.h
    #8 5.146   inflating: mp4v2-master/src/itmf/Tags.cpp
    #8 5.146   inflating: mp4v2-master/src/itmf/Tags.h
    #8 5.146   inflating: mp4v2-master/src/itmf/generic.cpp
    #8 5.146   inflating: mp4v2-master/src/itmf/generic.h
    #8 5.146   inflating: mp4v2-master/src/itmf/impl.h
    #8 5.146   inflating: mp4v2-master/src/itmf/itmf.h
    #8 5.146   inflating: mp4v2-master/src/itmf/type.cpp
    #8 5.146   inflating: mp4v2-master/src/itmf/type.h
    #8 5.146   inflating: mp4v2-master/src/log.cpp
    #8 5.146   inflating: mp4v2-master/src/log.h
    #8 5.146   inflating: mp4v2-master/src/mp4.cpp
    #8 5.146   inflating: mp4v2-master/src/mp4array.h
    #8 5.146   inflating: mp4v2-master/src/mp4atom.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4atom.h
    #8 5.150   inflating: mp4v2-master/src/mp4container.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4container.h
    #8 5.150   inflating: mp4v2-master/src/mp4descriptor.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4descriptor.h
    #8 5.150   inflating: mp4v2-master/src/mp4file.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4file.h
    #8 5.150   inflating: mp4v2-master/src/mp4file_io.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4info.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4property.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4property.h
    #8 5.150   inflating: mp4v2-master/src/mp4track.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4track.h
    #8 5.150   inflating: mp4v2-master/src/mp4util.cpp
    #8 5.150   inflating: mp4v2-master/src/mp4util.h
    #8 5.150   inflating: mp4v2-master/src/ocidescriptors.cpp
    #8 5.150   inflating: mp4v2-master/src/ocidescriptors.h
    #8 5.150   inflating: mp4v2-master/src/odcommands.cpp
    #8 5.150   inflating: mp4v2-master/src/odcommands.h
    #8 5.150   inflating: mp4v2-master/src/qosqualifiers.cpp
    #8 5.150   inflating: mp4v2-master/src/qosqualifiers.h
    #8 5.150    creating: mp4v2-master/src/qtff/
    #8 5.150   inflating: mp4v2-master/src/qtff/ColorParameterBox.cpp
    #8 5.150   inflating: mp4v2-master/src/qtff/ColorParameterBox.h
    #8 5.151   inflating: mp4v2-master/src/qtff/PictureAspectRatioBox.cpp
    #8 5.151   inflating: mp4v2-master/src/qtff/PictureAspectRatioBox.h
    #8 5.151   inflating: mp4v2-master/src/qtff/coding.cpp
    #8 5.151   inflating: mp4v2-master/src/qtff/coding.h
    #8 5.151   inflating: mp4v2-master/src/qtff/impl.h
    #8 5.151   inflating: mp4v2-master/src/qtff/qtff.h
    #8 5.151   inflating: mp4v2-master/src/rtphint.cpp
    #8 5.151   inflating: mp4v2-master/src/rtphint.h
    #8 5.151   inflating: mp4v2-master/src/src.h
    #8 5.151   inflating: mp4v2-master/src/text.cpp
    #8 5.151   inflating: mp4v2-master/src/text.h
    #8 5.151   inflating: mp4v2-master/src/util.h
    #8 5.151    creating: mp4v2-master/test/
    #8 5.151    creating: mp4v2-master/test/OLD/
    #8 5.151   inflating: mp4v2-master/test/OLD/c_api.c
    #8 5.151   inflating: mp4v2-master/test/OLD/mp4clip.cpp
    #8 5.151   inflating: mp4v2-master/test/OLD/nullcreate.cpp
    #8 5.151   inflating: mp4v2-master/test/OLD/nullvplayer.cpp
    #8 5.151   inflating: mp4v2-master/test/OLD/urltrack.cpp
    #8 5.151    creating: mp4v2-master/testsuite/
    #8 5.151    creating: mp4v2-master/testsuite/config/
    #8 5.151   inflating: mp4v2-master/testsuite/config/unix.exp
    #8 5.151    creating: mp4v2-master/testsuite/lib/
    #8 5.153   inflating: mp4v2-master/testsuite/lib/command.exp
    #8 5.153    creating: mp4v2-master/testsuite/main/
    #8 5.153   inflating: mp4v2-master/testsuite/main/standardUsage.exp
    #8 5.153    creating: mp4v2-master/util/
    #8 5.153   inflating: mp4v2-master/util/impl.h
    #8 5.153   inflating: mp4v2-master/util/mp4art.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4chaps.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4extract.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4file.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4info.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4subtitle.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4tags.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4track.cpp
    #8 5.153   inflating: mp4v2-master/util/mp4trackdump.cpp
    #8 5.153    creating: mp4v2-master/xcodeproj/
    #8 5.153    creating: mp4v2-master/xcodeproj/mp4v2.xcodeproj/
    #8 5.153   inflating: mp4v2-master/xcodeproj/mp4v2.xcodeproj/project.pbxproj
    #8 5.153    creating: mp4v2-master/xcodeproj/mp4v2.xcodeproj/project.xcworkspace/
    #8 5.153   inflating: mp4v2-master/xcodeproj/mp4v2.xcodeproj/project.xcworkspace/contents.xcworkspacedata
    #8 5.182 configure:
    #8 5.182   -->
    #8 5.182   --> Configuring MP4v2 2.0.0
    #8 5.182   -->
    #8 5.182 checking for a BSD-compatible install... /usr/bin/install -c
    #8 5.246 checking whether build environment is sane... yes
    #8 6.264 checking for a thread-safe mkdir -p... autoaux/install-sh -c -d
    #8 6.272 checking for gawk... no
    #8 6.272 checking for mawk... no
    #8 6.272 checking for nawk... no
    #8 6.272 checking for awk... awk
    #8 6.273 checking whether make sets $(MAKE)... yes
    #8 6.297 checking build system type... autoaux/config.guess: unable to guess system type
    #8 6.359 
    #8 6.359 This script, last modified 2009-06-10, has failed to recognize
    #8 6.359 the operating system you are using. It is advised that you
    #8 6.359 download the most up to date version of the config scripts from
    #8 6.359 
    #8 6.359   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
    #8 6.359 and
    #8 6.359   http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
    #8 6.359 
    #8 6.359 If the version you run (autoaux/config.guess) is already up to date, please
    #8 6.359 send the following data and any information you think might be
    #8 6.359 pertinent to <[email protected]> in order to provide the needed
    #8 6.359 information to handle your system.
    #8 6.359 
    #8 6.359 config.guess timestamp = 2009-06-10
    #8 6.359 
    #8 6.359 uname -m = aarch64
    #8 6.359 uname -r = 5.10.25-linuxkit
    #8 6.359 uname -s = Linux
    #8 6.359 uname -v = #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021
    #8 6.359 
    #8 6.359 /usr/bin/uname -p = 
    #8 6.359 /bin/uname -X     = 
    #8 6.359 
    #8 6.359 hostinfo               = 
    #8 6.359 /bin/universe          = 
    #8 6.359 /usr/bin/arch -k       = 
    #8 6.359 /bin/arch              = aarch64
    #8 6.359 /usr/bin/oslevel       = 
    #8 6.359 /usr/convex/getsysinfo = 
    #8 6.359 
    #8 6.359 UNAME_MACHINE = aarch64
    #8 6.359 UNAME_RELEASE = 5.10.25-linuxkit
    #8 6.359 UNAME_SYSTEM  = Linux
    #8 6.359 UNAME_VERSION = #1 SMP PREEMPT Tue Mar 23 09:24:45 UTC 2021
    #8 6.360 configure: error: cannot guess build type; you must specify one
    ------
    executor failed running [/bin/sh -c echo "---- INSTALL BUILD DEPENDENCIES ----"     && apk add --no-cache --update --upgrade --virtual=build-dependencies     autoconf     libtool     automake     boost-dev     build-base     gcc     git     tar     wget && echo "---- COMPILE SANDREAS MP4V2 (for sort-title, sort-album and sort-author) ----"   && cd /tmp/   && wget https://github.com/sandreas/mp4v2/archive/master.zip   && unzip master.zip   && cd mp4v2-master   && ./configure &&   make -j4 &&   make install && make distclean && echo "---- PREPARE FDKAAC-DEPENDENCIES ----"   && cd /tmp/   && wget -O fdk-aac.tar.gz "$FDK_AAC_URL"   && tar xfz fdk-aac.tar.gz   && cd fdk-aac-* && ./autogen.sh && ./configure --enable-static --disable-shared && make -j$(nproc) install && echo "---- COMPILE FDKAAC ENCODER (executable binary for usage of --audio-profile) ----"     && cd /tmp/     && wget https://github.com/nu774/fdkaac/archive/1.0.0.tar.gz     && tar xzf 1.0.0.tar.gz     && cd fdkaac-1.0.0     && autoreconf -i && ./configure --enable-static --disable-shared && make -j4 && make install && rm -rf /tmp/* && echo "---- REMOVE BUILD DEPENDENCIES (to keep image small) ----"     && apk del --purge build-dependencies && rm -rf /tmp/*]: exit code: 1
    
    assume fixed 
    opened by csandman 29
  • [question] Re-use batch-pattern fields

    [question] Re-use batch-pattern fields

    Hello, first of all thanks for maintaining such a great tool! 😄

    I'm trying to convert a bunch of files stored in a directory structure "input/%g/%a/%s/%p - %n/". Each of these directories also contains additional files with narrator, comment, copyright info, etc. I would also like to copy the artist tag into the albumartist tag as well, because the audioplayer I use maps the latter to the book writer.

    I would like to be able to use something like this:

    m4b-tool merge -v "input/" --output-file="output/" \
    --batch-pattern="input/%g/%a/%s/%p - %n/" --albumartist="%a" \
    --writer="input/%g/%a/%s/%p - %n/narrator.txt" \
    --year="input/%g/%a/%s/%p - %n/releasedate.txt" \
    --comment="input/%g/%a/%s/%p - %n/comment.txt" \
    --copyright="input/%g/%a/%s/%p - %n/copyright.txt"
    

    But this command doesn't work as I intend; the files are converted correctly and contain the right genre, artist, author etc fields, i.e. the ones matched by the input pattern, but fields like comment or copyright are just filled with the strings I provide on the command line, without actually expanding the input pattern fields. The albumartist field, for example, just contains the "%a" string and not the actual artist name. I know I could replace "%a" by "%t", and indeed in this way the albumartist gets filled correctly, but I want to keep both artist and albumartist at the same time.

    Another thing I would like to be able to do (not shown above) is to put each output .m4b file in a directory with the same name, i.e. having output files output/%g/%a/%s/%p - %n/%p - %n.m4b instead of the current behavior that generates output files output/%g/%a/%s/%p - %n.m4b.

    Of course I can "bypass" the issue by writing a shell script that, for each input directory, passes options to m4b-tool merge as e.g. --comment="$(cat comment.txt)" (which I tested and works correctly, btw), but then it loses generality, requires extra effort and defies the whole point of the --batch-pattern option.

    Is there a way, that I'm missing, to accomplish what I intend to do? Thanks in advance! 😃

    opened by matteosecli 22
  • Get error

    Get error "Input is not a file" using docker image

    What an amazing project you have put together.

    Issue

    After building the docker image without any issue, I am not able to split an m4b file

    Following error is thrown:

    [maarten@zbook m4b-tool]$ m4b-tool split --audio-format aac data/issue-120.m4b 
    
    In AbstractCommand.php line 525:
                           
      Input is not a file
    

    Issue

    Background, I am adding MP4 chapter support in music-metadata. Which I believe is working. Problem is, it makes most of my MP4 sample useless. I stripped of the MDAT payload of most of the files, and maybe some more, to get to workable size. I was hoping my splitting, trimming and joining, I could shrink the originals, in such a way there are chapters, but the audio content is limited to something like a a second.

    opened by Borewit 19
  • Files cannot be merged - no useful error message

    Files cannot be merged - no useful error message

    I'm having a lot of trouble getting fdkaac to compile. Is there any way this could be written out? It doesn't seem like I can configure the tool to disregard it?

    opened by lincalinca 18
  • Feature Request: Import/export just opf and cover.jpg without merge

    Feature Request: Import/export just opf and cover.jpg without merge

    There may be a way to do this already that I am overlooking. With mp4chaps you can import and export the chapters.txt file without the long merge process (useful if you already have a merged m4b file and need to adjust chapter times/names). It would be cool if you could do the same with the cover and metadata.

    enhancement 
    opened by danrneal 18
  • Out of memory exception with Docker image

    Out of memory exception with Docker image

    I have build the latest docker image and it is working mostly well. I have a few books that it is running out of memory on when processing.

    My command is:

    docker run -it --rm -u $(id -u):$(id -g) -v $(pwd):/mnt m4b-tool merge AUDIOBOOK_DIRECTORY --jobs=4 --audio-bitrate=64k --mark-tracks --audio-format=mp3 --audio-codec=libmp3lame --output-file='book.mp3'
    

    The error I receive is:

    PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 68606456 bytes) in phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php on line 308
    an error occured, that has not been caught:
    Array
    (
        [type] => 1
        [message] => Allowed memory size of 134217728 bytes exhausted (tried to allocate 68606456 bytes)
        [file] => phar:///usr/local/bin/m4b-tool/src/library/M4bTool/Command/AbstractCommand.php
        [line] => 308
    )
    

    I have plenty of memory to throw at this - but I'm not sure if there is a way for me to do so.

    I am on macOS Catalina, using Docker for Mac. I have increased the RAM for the Docker for Mac VM to 4GB and received the same error, so I assume this is from how PHP in the docker image is configured.

    hard to reproduce 
    opened by gubler 17
  • Unsatisfiable Constraints

    Unsatisfiable Constraints

    This error keeps popping up while building. Any clues what might cause this?

    fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/main/armv7/APKINDEX.tar.gz
    WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.9/main/armv7/APKINDEX.tar.gz: temporary error (try again later)
    fetch http://dl-cdn.alpinelinux.org/alpine/v3.9/community/armv7/APKINDEX.tar.gz
    WARNING: Ignoring http://dl-cdn.alpinelinux.org/alpine/v3.9/community/armv7/APKINDEX.tar.gz: temporary error (try again later)
    ERROR: unsatisfiable constraints:
    
    opened by hackmonker 14
  • macOS: Trait 'M4bTool\Audio\Traits\CacheAdapterTrait' not found

    macOS: Trait 'M4bTool\Audio\Traits\CacheAdapterTrait' not found

    I ran into issue #108 on macOS, then created pull request #111, however, can't run the compiled phar:

    % ./build 
    Building...
      adding: m4b-tool.phar (deflated 83%)
    /Users/abc/Downloads/m4b-tool
    % ./dist/m4b-tool.phar 
    PHP Fatal error:  Trait 'M4bTool\Audio\Traits\CacheAdapterTrait' not found in phar:///Users/abc/Downloads/m4b-tool/dist/m4b-tool.phar/src/library/Command/AbstractCommand.php on line 34
    
    Fatal error: Trait 'M4bTool\Audio\Traits\CacheAdapterTrait' not found in phar:///Users/abc/Downloads/m4b-tool/dist/m4b-tool.phar/src/library/Command/AbstractCommand.php on line 34
    an error occured, that has not been caught:
    Array
    (
        [type] => 1
        [message] => Trait 'M4bTool\Audio\Traits\CacheAdapterTrait' not found
        [file] => phar:///Users/abc/Downloads/m4b-tool/dist/m4b-tool.phar/src/library/Command/AbstractCommand.php
        [line] => 34
    )
    
    bug 
    opened by AlexanderWillner 14
  • WIP: Complete overhaul of dockerfile

    WIP: Complete overhaul of dockerfile

    There were a few issues here:

    • Build was done inside the final image, rather than using multi-stage, to run build outside of the final image.
    • fdk-aac was not the official source. (https://github.com/mstorsjo/fdk-aac is the official)
    • FFMPEG was compiled non-statically, which meant a lot of packages had to be installed to the image. This version will grab all it needs from my ffmpeg docker, removing virtually all dependencies
    • For simplicity, this is built with Ubuntu 18.04.
    opened by ordinarygulp 13
  • Support setting `Style` tag

    Support setting `Style` tag

    I am using this tool to combine/adjust the audiobooks in Plex. The Audnexus agent is used to scan the files. As per Audnexus' documentation, the Style tag is used to indicate a narrator. Could you please add support to specify the Style tag? Thank you.

    opened by sigito 5
  • merged flac files result in incorrect Duration

    merged flac files result in incorrect Duration

    Having an "Adventskalender" by ???, with each day a new track, I build every day a new version of the up to date audiobook for my family. I ripped the CD to .flac-files and move the corresponding m4b-file to the nas, so there is every day a complete new version in a clean directory. All chapters are correct so far:

    00:00:00.000                             : Tag 01 Winterwunderland
    00:08:04.009                             : Tag 02 Angriff auf Santa Claus
    00:10:35.005                             : Tag 03 Sabotage
    00:15:50.988                             : Tag 04 Ein Sack voller Geheimnisse
    00:22:22.224                             : Tag 05 36 x Elf
    00:30:05.180                             : Tag 06 Bruder Justus
    00:36:42.696                             : Tag 07 Elf gegen drei
    00:40:48.959                             : Tag 08 Märchenstunde
    00:45:05.395                             : Tag 09 Köder mit Schleife
    00:53:48.138                             : Tag 10 Auf frischer Tat
    00:59:12.627                             : Tag 11 Kurzfinger
    01:03:05.516                             : Tag 12 Der Alligator
    

    But the duration entry gets massive out of sync:

    yesterday ("Tag 11"):
    Duration                                 : 11 h 36 min
    
    today ("Tag 12"):
    Duration                                 : 12 h 48 min
    
    Track 12 is:
    Duration                                 : 6 min 10 s
    
    opened by lduesing 2
  • Allowed memory size exhausted - RuneList.php

    Allowed memory size exhausted - RuneList.php

    Command: m4b-tool merge -vvv --jobs=8 --output-file="output/" --batch-pattern="input/%g/%a/%s/%p - %n/" "input/" --no-chapter-reindexing

    Error:

    ==> trying improver ChaptersFromOverdrive 
    'ffmpeg' '-hide_banner' '-i' 'input/Audiobook/Author/Series/01 - Series 01. Book 01/01-01.mp3' '-f' 'ffmetadata' '-'
    PHP Fatal error:  Allowed memory size of 134217728 bytes exhausted (tried to allocate 16777224 bytes) in phar:///usr/local/bin/m4b-tool-pre/vendor/sandreas/php-strings/src/Sandreas/Strings/RuneList.php on line 247
    an error occured, that has not been caught:
    Array
    (
        [type] => 1
        [message] => Allowed memory size of 134217728 bytes exhausted (tried to allocate 16777224 bytes)
        [file] => phar:///usr/local/bin/m4b-tool-pre/vendor/sandreas/php-strings/src/Sandreas/Strings/RuneList.php
        [line] => 247
    )
    

    Debian 11 Bullseye, m4b-tool latest-178-gaeb8b2b

    log.txt m4b-tool.log

    opened by kodirovshchik 4
  • getting PHP Deprecated error while running m4b-tool version

    getting PHP Deprecated error while running m4b-tool version

    PHP Deprecated:  Return type of Sandreas\Time\TimeUnit::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/local/bin/m4b-tool/vendor/sandreas/php-time/src/Sandreas/Time/TimeUnit.php on line 241
    
    Deprecated: Return type of Sandreas\Time\TimeUnit::jsonSerialize() should either be compatible with JsonSerializable::jsonSerialize(): mixed, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in phar:///usr/local/bin/m4b-tool/vendor/sandreas/php-time/src/Sandreas/Time/TimeUnit.php on line 241
    m4b-tool latest-178-gaeb8b2b
    

    MacBook 14 M1 MacOS Ventura 13.0 (22A380)

    installed php with brew install php

    Okay just realized its working correctly and just showing this deprecated stuff. migth not be so important for you

    opened by dmuiX 2
  • Start chapter at the end of silence?

    Start chapter at the end of silence?

    I used --find-misplaced-chapters to correct the chapters by silence. But now the chapter starts with the last 50 ms or so of the last chapter, so I hear the rest of the last word, then there is 4 seconds silence, then the chapter begins. Is it possible to make the chapter start at the end of the silence?

    opened by rubbishgee 4
  • docker on Windows

    docker on Windows

    In the documentation for using m4b-tool through Docker on Windows, you state "Note: If you are on windows, it might be difficult to make it work".

    I was able to get m4b-tool to work on Windows through docker without too much challenge. There are two things that you must do:

    1. Make sure Docker is running using the Hyper-V engine, not the WSL2 engine,
      • There is a bug in WSL2 that make certain file system enumeration calls fail. Unfortunately, those calls are used by PHP, causing m4b-tool to struggle to see many of the files on the file system during operation.
    2. Replace $(pwd) with ${PWD} in docker commands:
    • Using powershell, the alias command then becomes:
    function m4b-tool { docker run -it --rm -v ${PWD}:/mnt sandreas/m4b-tool:latest $args }
    

    Other than that, it works as you would expect. It might be worth adding a section on this to the docs for Windows users.

    opened by ruoti 2
Releases(latest)
  • latest(Nov 23, 2019)

    Pre-Release: This is a release for the brave...

    • NO stable release - may cause data loss or unexpected behaviour
    • contains always the latest available build with the newest features and fixes
    • made for testers and all others waiting on a specific feature or bugfix

    Install instructions

    Docker

    docker build . --build-arg M4B_TOOL_DOWNLOAD_LINK=https://github.com/sandreas/m4b-tool/files/9721007/m4b-tool.tar.gz -t m4b-tool
    

    Windows

    Just replace the m4b-tool.phar with the one in the latest tar.gz-file.

    MacOS / Linux:

    • Download and extract the latest pre-release: https://github.com/sandreas/m4b-tool/files/9721007/m4b-tool.tar.gz
    • Replace m4b-tool with the extracted m4b-tool.phar:
    # show m4b-tool install path, e.g. /usr/local/bin/m4b-tool
    which m4b-tool
    
    # backup old version
    sudo mv /usr/local/bin/m4b-tool /usr/local/bin/m4b-tool.2020-02-29.phar
    
    # install new version
    sudo mv m4b-tool.phar /usr/local/bin/m4b-tool && sudo chmod +x /usr/local/bin/m4b-tool
    
    # check version
    m4b-tool version
    

    Downloads with build dates

    Source code(tar.gz)
    Source code(zip)
  • v.0.4.2(Aug 11, 2019)

  • v.0.4.1(May 7, 2019)

  • v.0.4.0(May 3, 2019)

    Important notice During the development of v.0.4.0 there were A LOT of changes to prepare performance improvements, some of these are breaking changes or experimental changes. It is likely that there will be some issues, so backup before you update.

    breaking changes

    • By default, m4b-tool is now quiet and provides no output - add -v to restore the old behaviour (-vv and -vvv are also supported for higher verbosity)
    • The parameter --convert-charset has been renamed into --platform-charset
    • Parameter --debug-filename has been removed in favor of --logfile, which also supports logging of non-debug levels

    new features

    • The batch-pattern and dry-run parameters allow to load tags from directory names (see README for details)
    • The jobs parameter should improve merge performance on systems with multiple cores
    • Added an mp4v2 fork to support sortname, sortartist and sortalbum for some players

    improvements

    • reworked all output and logging (colors are now supported for command line output)
    • support for mp3 chapters added
    • improved many things in tagging support
    • added best practices section in the documentation
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(2.66 MB)
    m4b-tool.tar.gz(443.79 KB)
    m4b-tool.zip(445.09 KB)
  • v.0.3.3(Mar 5, 2019)

    This release mainly fixes (critical) issues and improves handling of unicode characters in different commands

    fixes:

    • #27 fixed data loss by deleting or overwriting the wrong files (critical)
    • #26 fixed documentation to show the right setup instructions as a result of brew changes

    improvements:

    • #25 --fix-mime-type changes mimetype (video/mp4 instead of audio/mp4) of files
    • Better unicode handling when embedding descriptions (somethings the 255 byte limit was exceeded when using unicode)
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(2.41 MB)
    m4b-tool.tar.gz(407.47 KB)
    m4b-tool.zip(407.98 KB)
  • v.0.3.2(Feb 5, 2019)

    This release mainly fixes and improves the split command. It includes the following changes:

    split

    • new Parameter output-dir to specify an output directory for the splitted files
    • new Parameter filename-template to specify a twig template for file-naming (see README.md for details)
    • fixed issue #22 - use an existing chapters file that has been manually edited

    merge

    • fixed issue #23 by adding the --no-conversion parameter to merge without the need to re-encode same codec files
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(2.41 MB)
    m4b-tool.tar.gz(406.08 KB)
    m4b-tool.zip(406.51 KB)
  • v.0.3.1(Dec 28, 2018)

    Release v.0.3.1 comes with new features, improvements and bug fixes.

    New:

    • added a small homepage based on the readme.md - http://m4b-tool.fynder.de
    • merge: added --audio-profile parameter for iTunes compatible high efficiency files
    • chapter: added --adjust-by-silence parameter to fix existing chapter shift by silence detection

    Improvements:

    • Updated README.md for better documentation (especially so far undocumented features)
    • Properly set description meta tags (thx @kpumuk)
    • Use converted files to detect chapter timestamps (thx @kpumuk)

    Fixes:

    • Fixed Apple lossless codec alac (#20)
    • Fixed an uncaught php error (#15)
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.82 MB)
    m4b-tool.tar.gz(313.78 KB)
    m4b-tool.zip(314.89 KB)
  • v.0.3(Jun 20, 2018)

    Release v.0.3 comes with a bunch of minor improvements and bug fixes.

    Improvements:

    • Better cover handling - support for png included (cover.jpg is still the preferred cover file)
    • Better audio file handling - more file extensions, case insensitive
    • Better chapter handling - improved chapter sorting and naming
    • Added --auto-split-seconds param to set a max. chapter length in seconds (useful for merging large files)
    • Added new metadata params (e.g. --comment)
    • Added expert option params --threads and --ffmpeg-param to be more flexible with ffmpeg

    Fixes:

    • Fixed handling of german umlauts (Windows only)
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.81 MB)
  • v.0.3-beta5(May 7, 2018)

  • v.0.3-beta4(Apr 25, 2018)

    v.0.3-beta4

    Improvements:

    • restructured cover extraction
    • fixed conversion handling for cover embedding resulting in missing / wrong chapters
    • fixed problem with --auto-split-seconds
    • added possible workaround for #9
    • try to extract cover from input files when merging and no cover is given

    Documentation:

    • Added a sample shell script (multi-merge.sh) to batch convert a directory on POSIX Systems (tested on Ubuntu 16.04 LTS)
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.80 MB)
  • v.0.3-beta3(Apr 23, 2018)

    v.0.3 Beta 3

    • added --auto-split-seconds parameter for merge command to define a maximum track to chapter length in seconds (if chapter/track is longer, it will be splitted in chunks with this amount of seconds)

    This is especially useful if you have only a few very long files, you would like to merge.

    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.80 MB)
  • v.0.3-beta2(Apr 16, 2018)

  • v.0.3-beta1(Mar 30, 2018)

    v.0.3 Beta 1

    • Fixed handling of german umlauts (Windows only)
    • Added new metadata parameters (e.g. --comment)
    • Added better cover handling (now detects all jpg and png images as cover - cover.jpg is preferred)
    • Added threads parameter to be more flexible using ffmpeg
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.75 MB)
  • v0.2(Feb 11, 2018)

    Changelog:

    • Fixed a bug where a missing ini setting date.timezone causes an uncaught exception
    • Added flag --adjust-for-ipod adjusts audiobook bitrate with the calculated maximum sampling rate of an ipod
    • Added flag --album which is used as title of the audiobook in itunes
    • Minor improvements for logging and output

    m4b-tool is a tool to split, merge or modify m4b audiobook files.

    Features:

    • Merge a set of audio files into a single m4b file
    • Split a single m4b-File into several output files by chapters
    • Add chapters to an existing m4b-File via musicbrainz and silence detection
    Source code(tar.gz)
    Source code(zip)
    m4b-tool.phar(1.79 MB)
    mp4v2-windows.zip(324.50 KB)
Owner
Andreas
m4b-tool: 09122019/4342790
Andreas
A collection of command line scripts for Magento 2 code generation, and a PHP module system for organizing command line scripts.

What is Pestle? Pestle is A PHP Framework for creating and organizing command line programs An experiment in implementing python style module imports

Alan Storm 526 Dec 5, 2022
The swiss army knife for Magento developers, sysadmins and devops. The tool provides a huge set of well tested command line commands which save hours of work time. All commands are extendable by a module API.

netz98 magerun CLI tools for Magento 2 The n98 magerun cli tools provides some handy tools to work with Magento from command line. Build Status Latest

netz98 758 Dec 28, 2022
🎮 A simple command line tool for installing and interacting with your leaf apps

Leaf CLI 2 A simple command line tool for creating and interacting with your leaf projects. You can do stuff like installing packages, interacting wit

Leaf Framework 7 Aug 24, 2022
Tango is a command-line tool for analyzing access logs 💃

Tango Tool to get insights from the server access logs Tango is a dependency-free command-line tool for analyzing access logs ?? Currently, work on th

Roman Glushko 94 Nov 22, 2022
Opinionated version of Wikimedia composer-merge-plugin to work in pair with Bamarni composer-bin-plugin.

Composer Inheritance Plugin Opinionated version of Wikimedia composer-merge-plugin to work in pair with bamarni/composer-bin-plugin. Usage If you are

Théo FIDRY 25 Dec 2, 2022
More options when uploading files such as name changes, resizing or compression through TinyPNG.

Kirby Upload Extended More options when uploading files like name changes, resizing via Kirby or compression and optional resizing via TinyPNG. Thanks

Oli 24 Nov 12, 2022
Demo of symfony/console features to build rich command line utilities

Symfony Console Demo This project is a demonstration of symfony/console features. To run the project with Docker. With bash: docker build -t myconsole

Jérôme Tamarelle 3 Jun 16, 2022
TrovCMS command line installer.

Trov CMS Installer TrovCMS is a start kit for websites, built on Filament and Laravel. This install allows you to quickly spin up new sites to hit the

TrovCMS 12 Dec 26, 2022
Rugby schedules on the command-line

Rugby Schedule Rugby Schedule is a command-line tool that keeps you up to date with rugby tournament schedules. Install Requires PHP 8.0 or later Via

Owen Voke 0 Mar 17, 2022
Command line of the website.

Deutsch English Svenska Command 0.8.42 Command line of the website. How to use the command line Open a terminal window. Go to your installation folder

Anna 2 Dec 15, 2022
A collection of command-line utilities to aid in debugging browser engines.

Browser debug utilities This project contains several scripts that make the process of debugging browser engines much easier (some special cases excep

Clay Freeman 5 May 29, 2023
Subtree split of the SocialiteProviders/TikTok Provider (see SocialiteProviders/Providers)

TikTok composer require socialiteproviders/tiktok Installation & Basic Usage Please see the Base Installation Guide, then follow the provider specific

Socialite Providers 5 Sep 29, 2022
This project is very diverse and based upon many languages and libraries such as C++, Python, JavaScript, PHP and MQTT

ADMS-Real-time-project This project is very diverse and based upon many languages and libraries such as C++, Python, JavaScript, PHP and MQTT Advance_

Nitya parikh 1 Dec 1, 2021
Small utility library that handles metadata minification and expansion.

composer/metadata-minifier Small utility library that handles metadata minification and expansion.

Composer 134 Dec 26, 2022
An utility component for XML usage and best practices in PHP

An utility component for XML usage and best practices in PHP

Laminas Project 13 Nov 26, 2022
Glob-like file and pattern matching utility.

Glob-like file and pattern matching utility.

Chris Kankiewicz 94 Dec 14, 2022
Dobren Dragojević 6 Jun 11, 2023
Easy to use utility functions for everyday PHP projects. This is a port of the Lodash JS library to PHP

Lodash-PHP Lodash-PHP is a port of the Lodash JS library to PHP. It is a set of easy to use utility functions for everyday PHP projects. Lodash-PHP tr

Lodash PHP 474 Dec 31, 2022
Utility that helps you switch git configurations with ease.

git-profile Utility that helps you switch git configurations with ease Preface It is possible that you have multiple git configurations. For example:

Zeeshan Ahmad 240 Jul 18, 2022