sandreas / m4b-tool

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

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

How to add custom ffmpeg options

mperkh opened this issue · comments

Great peace of software, that makes all those mostly unuseable gui apps out there obsolete. Thanks.

I would like to make use of High-Efficiency AAC, since output at 16K bitrate is much better. https://trac.ffmpeg.org/wiki/Encode/AAC#fdk_he

This has already been implemented, https://github.com/sandreas/m4b-tool/blob/master/src/library/M4bTool/Command/MergeCommand.php#L297

How can I add additional options, like -profile:a aac_he -cutoff 18000, that get forwarded to FFmpeg?

Hey,

thanks :-) Glad that you like it.

First a small note:
I already have experimented with the ffmpeg high efficency thing and as if i used it, the resulting files where corrupt or could at least not be played with the majority of the players (including iTunes). The conversion worked, ffmpeg had no errors, but the files could only be played in vlc. Just in case you did not know that.

But now to your problem:
It is indeed possible to add custom ffmpeg parameters, but it is currently undocumented, because it produces unexpected results. Reasons:

  • order of parameters is important for ffmpeg in some cases (e.g. that they cannot be provided after the output file name)
  • it does not always work as expected, since all m4b-tool will do is append these parameters to the command it already uses

You could try the following, it hopefully works:

php m4b-tool.phar merge "data/my-audio-book" --output-file="data/my-audio-book.m4b" --debug --ffmpeg-param="-profile:a" --ffmpeg-param="aac_he" --ffmpeg-param="-cutoff"  --ffmpeg-param="18000"

The --debug will produce a logfile in which every binary call will be logged. If it does not work, you could at least see, which command m4b-tool has tried to execute and execute it manually, because temporary files are also kept on debugging.

If this does not work, i will add a --ffmpeg-profile parameter for the next release, that inserts the parameter on the right place.

Hope it helps.

Hi,

thanks for the reply and its now possible to create aac-he files with m4b-tool.

I already have experimented with the ffmpeg high efficency thing and as if i used it, the resulting files where corrupt or could at least not be played with the majority of the players (including iTunes). The conversion worked, ffmpeg had no errors, but the files could only be played in vlc. Just in case you did not know that.

Also realised, that the generated aac-he files are not compatible to iTunes (importing them is not possible) and found this thread: https://www.computeraudiophile.com/forums/topic/54904-failed-aac_he_v2-experiment-undetected-by-itunes-on-import/?do=findComment&comment=899531 where a solution to that problem is mentioned:

I was able to convert to a compatible aac-he (mono v1 --profile 5, stereo v2 --profile 29) file using https://github.com/nu774/fdkaac and a command like this and importing into iTunes is possible now:

ffmpeg -i myAudioBook.m4b -ac 1 -f caf - | fdkaac -p 5 -b 16000 - -o myAudioBook.m4a

Unfortunately I had to do a 265kBit/s encoding with m4b-tool first, to get a concated audio stream with an appropriate chapter.txt file. Still searching the perfect workflow for my projects. Perhaps it is possible to include that aac encoder into m4b-tool.

Another thing, but that might be due to a problem with my input audio sources (a playlist from youtube, downloaded with youtube-dl -f 140): The chapters times are not correct, the longer the output audio file is getting. This particular audio file has a length of 27 hours and at the end the shift between generated chaters.txt and actual audio content is around 1 minute. The same also happend using http://bluezbox.com/audiobookbinder.html.

Problem 1: Encoding with Profiles

Good find! Thank you. Since I also experimented with AAC_HE_V2 I think it would be nice to integrate another conversion step with fdkaac, since m4b-tool should always produce the best audio quality possible.

My suggestion would be the following:

I will read through some documentation and forums, e.g.:

Then do a few experiments with fdkaac on different operating systems (since i use m4b-tool on mac, linux and windows):

Then I'll add a new parameter --audio-profile, which will for the moment accept only 2 valid values: aac_he and aac_he_v2. If this parameter is provided, m4b-tool will assert, that fdkaac is installed and then build exactly the command you provided with either -p 5 on --audio-channels=1 and -p 29 on --audio-channels=2.

What do you think?

Problem 2: Shift between chapters.txt and actual audio content

There is no logic for this directly integrated, BUT:

I got exactly the same problem with a shift, when i used the chapters from music brainz. My solution was the following:

  • Detect silences with ffmpeg
  • Match the first chapters position with the nearest silence, correct the position and store the shift between them
  • Add the stored shift to the second chapters position, match the nearest silence, correct it, store the new shift
  • Go on with the next chapters

I got pretty good results with this strategy, altough it was not 100%, when the shift was too huge. In your case, it could work, because the overall shift is only 60 seconds.

m4b-tool already includes the described logic, but it would need some code improvements, that it could be used for other parts of the software, than the chapter subcommand.

  • Perhaps I could introduce a --auto-correct-chapters-by-silence parameter, that could apply this logic with the resulting file and the given chapters.txt
  • Perhaps I could integrate a --auto-correct-chapters-by-silence only into the chapter subcommand, so that you would have to add another "encoding" step in your scripts...

Second solution would be more flexible, since you could provide every existing mp4-file with chapters, detect silences and move chapter positions according the silences.

But this is perhaps much work to do and i can't promise, that this will happen in the near future.

Solution to Problem 1 sounds ok to me. Might be necessary to make additional tests, since all the final production of the audio is not done via ffmpeg, but fdkaac. By using caf as an intermediate file, it seems to be possible to pass tag to the final m4a(b).

For Problem 2 I have to investigate more time to understand the issue. In my situation, I have 210 audio files, each is a chapter in the end and the resulting audiobook is 27h in length.
For me it looks like a number rounding problem, that has more impact with longer files or files with more chapters or something with silence/gapless info.

Ok, here is a build of current master containing both improvements (some free dirty hacks included ;)
m4b-tool.phar.zip

Would be nice if you find the time to test these. In my case they work nicely on MacOS.

Examples:

fdkaac usage - produces iTunes compatible high efficiency files

# will use fdkaac for encoding mono
php m4b-tool.phar merge --audio-profile=aac_he --audio-bitrate=16k --output-file="data/_output/merged.m4b" "data/_input/"

# will use fdkaac for encoding stereo
php m4b-tool.phar merge --audio-profile=aac_he_v2 --audio-bitrate=16k --output-file="data/_output/merged.m4b" "data/_input/"

adjust-by-silence - will adjust existing chapters of a file matching nearest silences

This is a feature I've always wanted to have myself...
Important: --force will overwrite existing chapter / output files (better for testing)

# will adjust misplaced chapters in misplaced.m4b by silence detection in file adjusted.m4b
php m4b-tool.phar chapters --force --adjust-by-silence -o "data/chapter-adjust/adjusted.m4b" "data/chapter-adjust/misplaced.m4b"

I close this issue because version 0.3.1 contains all necessary improvements and fixes. If something doesn't work, please reopen the issue.

Have made some tests and he-aac encoding works fine, but it seems to get confused with temporary file handling. The resulting m4b file only contains the first track, which is repeated by no. of files.

Files in test folder:

009.m4a
010.m4a
011.m4a
012.m4a

Here log file output, where the problem can be seen imho:

ffmpeg -i /Users/michael/Desktop/m4bToolTests/009.m4a -vn -ac 1 -ar  -f caf output/merged-tmpfiles/1-009-converting.m4b.fdkaac-input
fdkaac --raw-channels 1 -p 5 -b 16k -o output/merged-tmpfiles/1-009-converting.m4b output/merged-tmpfiles/1-009-converting.m4b.fdkaac-input
ffmpeg -i /Users/michael/Desktop/m4bToolTests/010.m4a -vn -ac 1 -ar  -f caf output/merged-tmpfiles/2-010-converting.m4b.fdkaac-input
fdkaac --raw-channels 1 -p 5 -b 16k -o output/merged-tmpfiles/1-009-converting.m4b output/merged-tmpfiles/1-009-converting.m4b.fdkaac-input -o output/merged-tmpfiles/2-010-converting.m4b output/merged-tmpfiles/2-010-converting.m4b.fdkaac-input
ffmpeg -i /Users/michael/Desktop/m4bToolTests/011.m4a -vn -ac 1 -ar  -f caf output/merged-tmpfiles/3-011-converting.m4b.fdkaac-input
fdkaac --raw-channels 1 -p 5 -b 16k -o output/merged-tmpfiles/1-009-converting.m4b output/merged-tmpfiles/1-009-converting.m4b.fdkaac-input -o output/merged-tmpfiles/2-010-converting.m4b output/merged-tmpfiles/2-010-converting.m4b.fdkaac-input -o output/merged-tmpfiles/3-011-converting.m4b output/merged-tmpfiles/3-011-converting.m4b.fdkaac-input
ffmpeg -i /Users/michael/Desktop/m4bToolTests/012.m4a -vn -ac 1 -ar  -f caf output/merged-tmpfiles/4-012-converting.m4b.fdkaac-input
fdkaac --raw-channels 1 -p 5 -b 16k -o output/merged-tmpfiles/1-009-converting.m4b output/merged-tmpfiles/1-009-converting.m4b.fdkaac-input -o output/merged-tmpfiles/2-010-converting.m4b output/merged-tmpfiles/2-010-converting.m4b.fdkaac-input -o output/merged-tmpfiles/3-011-converting.m4b output/merged-tmpfiles/3-011-converting.m4b.fdkaac-input -o output/merged-tmpfiles/4-012-converting.m4b output/merged-tmpfiles/4-012-converting.m4b.fdkaac-input

Listening to the output, this scene came to mind: ;)

https://youtu.be/4lQ_MjU4QHw

Have made some tests and he-aac encoding works fine, but it seems to get confused with temporary file handling. The resulting m4b file only contains the first track, which is repeated by no. of files.

Thanks for testing :-) Should already be fixed in the latest release:
https://github.com/sandreas/m4b-tool/releases/download/v.0.3.1/m4b-tool.phar

Reason was an unclean array structure that has always been pushed instead of being replaced.

Let me know if i could do something else...

Ok. works now. Thx.

Just made a he-acc_v1 test run of my 210 chapters, 27h audiobook completely with a single invocation of mb4-tool, and regarding Problem 2, the chapters now match perfectly! Seems the shift of chapters/audio was introduced by my attempts to create the final result, using tools outside the scope of mb4-tool.

This is great news. Thank you very much for your extensive feedback and testing effort. These enhancements will also greatly improve my personal encoding steps a lot.