Libation icon indicating copy to clipboard operation
Libation copied to clipboard

Select Chapters to Split/Subchapter hierarchy support

Open schaferaccess opened this issue 2 months ago • 3 comments

This may be too niche but I have some books that are series collections The ability to split "books" into their chapter and subchapters would be great

schaferaccess avatar Dec 22 '25 08:12 schaferaccess

As another user, I'm just wondering about the details of your suggestion.

I have a book: The Ultimate Science Fiction Mega Collection: 24 of the Best Sci-Fi Books of All Time [B094X2RN1F] It's something like 120 hrs running time. Split by chapters yields all the chapters of all the books. IOW 507 files. Is what you refer to: the ability to have a separate directory for each "Book"? IOW to somehow create 24 separate directories with one for each book?

If yes, I'm currently working on some PowerShell scripts that use Libation metadata and it seems I could easily do exactly that. In fact, although it never occurred to me, I think I might find it useful in cases like above. However, in my own case, I think I would want to apply it manually in very specific cases because, many books I have, contain hierarchies that don't make sense to separate this way. So I'd find a Libation level setting to be cumbersome at best; unless you mean that 'split-by-chapter' only splits at the first level of hierarchy rather than all levels. This obviously has completely different implications...

So please, explain further...

rbielaws avatar Dec 22 '25 14:12 rbielaws

If I understand what you're saying that's precisely what I'm trying to do. So the two cases I'm trying to do this with are "Narnia the complete series" and the Bible. Libation currently has a setting that will split it up by all the chapters but like you said that creates a ton of files. If there was a way to either split by just the first level or if I could split by the chapters and then use it to create .m4b files that would be fantastic; clearly I'd prefer the former just so it was less work for me and I've been struggling to find a good program for creating .m4b files.

schaferaccess avatar Dec 24 '25 18:12 schaferaccess

Wow, I find this very interesting! I did some research and indeed, m4b format can be losslessly split. I'd love to see some thought about this. Some books it wouldn't be possible for, but some Audible books have formal "parts".

wtanksleyjr avatar Dec 24 '25 20:12 wtanksleyjr

You can use ffmpeg to split files as you like using the following options: -ss : Specifies the start time in the format hh:mm:ss or in seconds. -t : Specifies the duration of the segment from the start time, also in hh:mm:ss or seconds. -to : Specifies the absolute end time, which can be used as an alternative to -t.

Here's an example of three commands that split an audio file into 3 parts. The first part from timestamp 00:00 to 00:30:00, the second from 00:30:00 to 01:00:00, and the third from 01:00:00 to the end. The -c flag is short for "codec". and copy means to just copy the source to the destination without re-encoding.

ffmpeg -i "Before Us [B0FZKVLMH2].m4b" -ss 0 -to 00:30:00.8 -c copy out1.m4b
ffmpeg -i "Before Us [B0FZKVLMH2].m4b" -ss 30:00 -to 1:00:00 -c copy out2.m4b
ffmpeg -i "Before Us [B0FZKVLMH2].m4b" -ss 1:00:00 -c copy out3.m4b

NOTE! Audio in mpeg-4 files are stored in discrete packets called "frames". For AAC-LC, each frame is 1024 samples. Each xHE-AAC frame is typically also 1024 samples, but they can vary. The duration of a frame depends on the sample rate. Most "High" quality audiobooks are delivered at 44,100 Hz (CD quality), and most (but not all) "Normal" quality books are delivered at 22,050 Hz. For a 44,100 Hz audio, a Frame that is 1024 samples will last 1024/44100 ≈ 0.023 seconds. For a 22,050 Hz audio, a Frame that is 1024 samples will last 1024/22050 ≈ 0.046 seconds.

Why is all that important? Because the codec copy can only operate on discrete frames. No matter how precisely you specify the split times, it's only going to be as accurate as the nearest frame boundary. If you want to divide audio at the individual sample level, you're going to have to re-encode the audio. There's just no way around that.

Mbucari avatar Dec 26 '25 23:12 Mbucari

Well, since ffmpeg can also concatenate, it seems there are at least 3 ways to achieve book separation, although none look to be available with no real work. In order of difficulty:

  1. Have Libation Split by chapter and move chapters associated with each book into appropriate sub-directories.
  2. Like above but use ffmpeg to concatenate the appropriate chapter files into individual book files.
  3. Use metadata.json info to calculate the split points needed. Then use ffmpeg to split a monolithic file.

I may write something similar to 1) before too long but can't commit just now. If you'd like to try automation and don't mind PowerShell, this returns an object containing all the info in the json file pointed to.

$var = ConvertFrom-Json -InputObject (Get-Content -LiteralPath "Path<bookname>.metadata.json" -Raw)

Given CombineNestedChapterTitles was checked in Libation when the data was retrieved, $var.ChapterInfo.chapters will contain the top level array of chapters with each chapter potentially having a nested .chapters array of sub-chapter info.

rbielaws avatar Dec 27 '25 01:12 rbielaws

In order to handle the nested chapter structure in Libation, you would probably also need access to all chapter information. That of the current chapter and that of all chapters hierarchically above the current chapter.

The values for this from <ch title>, <ch#> and <ch count> would then have several entries analogous to <author> and <narrator>. Or you could offer these discreetly. E.g. via <parent-1 ch>, <parent-2 ch> etc.

Coupled with queries via <has>, the file names could be generated accordingly. Or – if different paths per chapter file were to be allowed, as requested in #1606 – the individual chapter files could then be grouped into folders.

I would say chapter splitting is handled by AAXClean. So in that case Libation would have to build a new chapterlist from the one retrieved by GetChaptersFromMetadata() so that less splits would occur. In that case - would the resulting m4b files have correct chapter-information for the subset of chapters as they would have to be positioned relatively?

Jo-Be-Co avatar Feb 13 '26 23:02 Jo-Be-Co