mkb79 / audible-cli

A command line interface for audible package. With the cli you can download your Audible books, cover, chapter files.
GNU Affero General Public License v3.0
455 stars 46 forks source link

Add `-c, --remove-intro-outro` option to `decrypt` #171

Closed vwkd closed 6 months ago

vwkd commented 10 months ago

This adds a -c, --remove-intro-outro option to the decrypt subcommand that removes the Audible brand intro and outro. It can't be used together with the -s, --separate-intro-outro option.

I mainly followed the example in the wiki. I chose -t with a duration instead of -to with a timestamp, because it doesn't depend on the location of -ss with respect to -i. -ss resets the timestamps to 0 if it's before -i but not if it's after. -t continues to work the same, while -to would need to adapt.

Closes #170.

vwkd commented 9 months ago

This should now be ready to review. Found the bug now which kept it a draft. Details below.


ffmpeg is sensitive to the location of the inputs -i when seeking using -ss (and -t).

Putting the input before -ss (and -t), like it was until now, had the bug that it deletes the cover. SuperUser suggests

When -ss used as an output option (after -i), ffmpeg would discard input until the timestamps reach position. Cover stream normally has very short duration, and that means it would be discarded.

To avoid output seeking, I had tried to use input seeking by moving the input after -ss (and -t) but this didn't trim the file. Confused by reading more about input seeking not being accurate for video when copying without re-encoding, I implicitly assumed it would be the same for audio and that the trim duration was probably too short. For example, SuperUser (comments), Reddit, SuperUser, SuperUser, or the manual

-ss position (input/output) When used as an input option (before "-i"), seeks in this input file to position. Note that in most formats it is not possible to seek exactly, so ffmpeg will seek to the closest seek point before position.

However, another SuperUser suggests that input seeking is accurate for audio

If you need frame accuracy, don't use -c copy [..]. It copies the bitstream, and if the specified start or end time isn't falling on an I-Frame, you get the nearest one, which can be quite far away from the desired location. See also the Seeking wiki. [..] You can however re-encode the video to get accurate cutting. The audio can be copied, as basically, an audio stream has "only keyframes".

So, why didn't it work? Turns out, I had overlooked that there are two inputs and mistook the metafile -i for the source -i. I had only moved the metafile -i after the -ss (and -t) while the source -i was always before. So, what made it not work had something to do with -ss (and -t) being in between both inputs.

Now with the source -i next to the metafile -i and both moved after -ss (and -t), input seeking works and is accurate.

mkb79 commented 8 months ago

Note: I’ve found this user comment about splitting a M4B file into chapters using mkvmerge. Maybe this can be an enhancement to the decrypt command in the future?!

Note2: I does not have tested your code yet. But if it works, the decrypt command can be moved to the build-in commands?!

vwkd commented 8 months ago

I agree, with this feature decrypt covers my basic needs. It could be a good starting point for a built-in command which would make it easier to use and hopefully drive more contributions in the future.

Splitting each chapter into a separate file should be possible by running it repeatedly for each chapter using -ss and -t in a similar fashion. Personally, I prefer a single .m4b file with complete metadata, instead of many individual files where order can be lost (e.g. rename filename) or even parts can be lost (e.g. delete one file). But this should probably be a separate issue.

vwkd commented 8 months ago

@mkb79 Were you able to test this?

Let me know if you have any questions regarding the code. It removes the intro and outro chapters by not adding them as chapters and shifting the starting times of all chapters forward by the intro duration. It cuts the audio file with the new starting time from the intro duration and the new duration from the old duration minus the intro and outro durations.

mkb79 commented 8 months ago

@vwkd The code looks good. To be honest, I didn't test it. Can you make sure that ffmpeg can cut the files correctly?

vwkd commented 8 months ago

Would be good if someone else can also confirm. For the files I have it cuts correctly.

vwkd commented 6 months ago

@mkb79 Were you able to test this by now?

The rough steps should be something like

  1. (if not already) Download some file with chapters
audible download --aaxc --chapters -a XXX
  1. Download/Checkout the repo with this PR.
  2. Use its plugins
export AUDIBLE_PLUGIN_DIR=path/to/repo/plugins_cmd
  1. Decrypt file
audible decrypt -r -c file.aaxc
mkb79 commented 6 months ago

@vwkd To be true, I doesn’t have tested it. But I will do it this week. I was also thinking about either build in the commando or bringing it to PyPI as an extra package and using a ffmpeg binding for Python. What do you mean?

vwkd commented 6 months ago

Great.

I think making the decrypt plugin a built-in command would be great and easier to use. But let's first merge this PR as is and do any other changes in a separate PR to keep a cleaner history.