mirror of
https://github.com/KrumpetPirate/AAXtoMP3.git
synced 2024-11-17 18:58:58 +01:00
Added support for chapters as well as convert to bash script
This commit is contained in:
parent
c387b1e03b
commit
9d28be4f06
71
AAXtoMP3.pl
71
AAXtoMP3.pl
@ -1,71 +0,0 @@
|
||||
#!/usr/bin/env perl
|
||||
use strict;
|
||||
use warnings;
|
||||
use v5.22.0;
|
||||
use autodie;
|
||||
use Getopt::Long qw/GetOptions/;
|
||||
Getopt::Long::Configure qw/gnu_getopt/;
|
||||
use File::Basename qw/fileparse/;
|
||||
use IO::CaptureOutput qw/capture_exec/;
|
||||
|
||||
say "Starting $0...";
|
||||
|
||||
my $VERBOSE;
|
||||
my $AUTHCODE;
|
||||
my $INPUT_FILE;
|
||||
GetOptions(
|
||||
'auth|a=s' => \$AUTHCODE,
|
||||
'input|i=s' => \$INPUT_FILE,
|
||||
'verbose|v' => \$VERBOSE,
|
||||
) or die "Usage: $0 -verbose -auth <AUDIBLE AUTH CODE> -input <INPUT FILE PATH>";
|
||||
die "Usage: $0 -verbose -auth <AUDIBLE AUTH CODE> -input <INPUT AAX PATH>"
|
||||
unless ($INPUT_FILE && $AUTHCODE);
|
||||
die "$INPUT_FILE is not a valid path" unless (-f $INPUT_FILE);
|
||||
|
||||
my ($filename, $dir, $extension) = fileparse($INPUT_FILE, qr/\.[^.]*/);
|
||||
my $ret = system_execute("ffprobe $INPUT_FILE");
|
||||
|
||||
my @fflines = split /\n/, $ret;
|
||||
my $file_type = pull_from_ffprobe("major_brand", @fflines);
|
||||
my $file_title = pull_from_ffprobe("title", @fflines);
|
||||
my $file_author = pull_from_ffprobe("artist", @fflines);
|
||||
die "Input file ffprobe does not appear to match an AAX file type metadata"
|
||||
unless $file_type =~ /aax/;
|
||||
|
||||
my $output;
|
||||
if ($file_title && $file_author) {
|
||||
$output = "$file_title by $file_author";
|
||||
} else {
|
||||
$output = $filename;
|
||||
}
|
||||
my $output_sh_safe = quotemeta $output;
|
||||
say "Using Audible auth code to copy AAX audio directly to MP3 format...";
|
||||
$ret = system_execute("ffmpeg -activation_bytes $AUTHCODE -i $INPUT_FILE -vn -c:a libmp3lame -ab 128k $dir$output_sh_safe.mp3");
|
||||
say $ret if $VERBOSE;
|
||||
|
||||
say "End of $0...";
|
||||
|
||||
sub system_execute {
|
||||
my ($stdout, $stderr, $success, $exit_code) = capture_exec(@_);
|
||||
say "stdout: $stdout\nstderr: $stderr\nsuccess: $success\nexit code: $exit_code" if ($VERBOSE);
|
||||
if ($success) {
|
||||
return $stdout if $stdout;
|
||||
return $stderr if $stderr;
|
||||
} else {
|
||||
my $command = join " ", @_;
|
||||
die "Command $command was not successful, debug.";
|
||||
}
|
||||
}
|
||||
|
||||
sub pull_from_ffprobe {
|
||||
my $desired = shift;
|
||||
my @fflines = @_;
|
||||
return unless ($desired && @fflines);
|
||||
my ($line) = grep { m/^\s+$desired/ } @fflines;
|
||||
$line =~ s/^\s*(.*?)\s*$/$1/;
|
||||
my @parts = split /\:/, $line;
|
||||
shift @parts;
|
||||
$line = join ':', @parts;
|
||||
$line =~ s/^\s*(.*?)\s*$/$1/;
|
||||
return $line;
|
||||
}
|
37
AAXtoMP3.sh
Executable file
37
AAXtoMP3.sh
Executable file
@ -0,0 +1,37 @@
|
||||
#!/usr/bin/bash
|
||||
AUTHCODE=$1
|
||||
shift
|
||||
while [ $# -gt 0 ]; do
|
||||
FILE=$1
|
||||
echo "Decoding $FILE with AUTHCODE $AUTHCODE..."
|
||||
|
||||
ffmpeg -i "$FILE" 2> tmp.txt
|
||||
TITLE=`grep -a -m1 -h -r "title" tmp.txt | head -1 | cut -d: -f2- | xargs`
|
||||
TITLE=`echo $TITLE | sed -r 's/\(Unabridged\)//' | xargs`
|
||||
ARTIST=`grep -a -m1 -h -r "artist" tmp.txt | head -1 | cut -d: -f2- | xargs`
|
||||
GENRE=`grep -a -m1 -h -r "genre" tmp.txt | head -1 | cut -d: -f2- | xargs`
|
||||
BITRATE=`grep -a -m1 -h -r "bitrate" tmp.txt | head -1 | rev | cut -d: -f 1 | rev | egrep -o [0-9]+ | xargs`
|
||||
BITRATE="${BITRATE}k"
|
||||
OUTPUT="$TITLE"
|
||||
OUTPUT_DIR="${GENRE}/${ARTIST}/${TITLE}"
|
||||
|
||||
ffmpeg -v error -stats -activation_bytes $AUTHCODE -i "${FILE}" -vn -c:a libmp3lame -ab $BITRATE "${OUTPUT}.mp3"
|
||||
|
||||
echo "Created ${OUTPUT}.mp3."
|
||||
|
||||
echo "Extracting chaptered mp3 files from ${OUTPUT}.mp3..."
|
||||
mkdir -p "${OUTPUT_DIR}"
|
||||
while read -r first _ _ start _ end; do
|
||||
if [[ $first = Chapter ]]; then
|
||||
read
|
||||
read _ _ chapter
|
||||
ffmpeg -v error -stats -i "${OUTPUT}.mp3" -ss "${start%?}" -to "$end" -acodec copy "${OUTPUT} - $chapter.mp3" < /dev/null
|
||||
mv "${OUTPUT} - $chapter.mp3" "${OUTPUT_DIR}"
|
||||
fi
|
||||
done < tmp.txt
|
||||
mv "${OUTPUT}.mp3" "${OUTPUT_DIR}"
|
||||
echo "Done creating chapters. Single file and chaptered files contained in ${OUTPUT_DIR}."
|
||||
|
||||
rm tmp.txt
|
||||
shift
|
||||
done
|
25
LICENSE
25
LICENSE
@ -1,22 +1,13 @@
|
||||
The MIT License (MIT)
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
Version 2, December 2004
|
||||
|
||||
Copyright (c) 2015 KrumpetPirate
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
Everyone is permitted to copy and distribute verbatim or modified
|
||||
copies of this license document, and changing it is allowed as long
|
||||
as the name is changed.
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||
|
||||
0. You just DO WHAT THE FUCK YOU WANT TO.
|
||||
|
49
README.md
49
README.md
@ -12,33 +12,29 @@ your **personal** Audible account. The purpose of this software is to
|
||||
create a method for you to download and store your books just in case
|
||||
Audible fails for some reason.
|
||||
|
||||
I recently converted this script to bash instead of perl. Something about more people knowing bash or something rather.
|
||||
Additionally I put some work into creating chaptered files as well as the mp3 version. A directory of structure GENRE/WRITER/TITLE
|
||||
will contain the large mp3 as well as chaptered mp3s extracted from the AAX file metadata.
|
||||
|
||||
TODO: Automatically fix the MP3 tags on the generated audio files. For now I use easytag which seems to work okay.
|
||||
|
||||
## Setup
|
||||
You will need your four byte authitication code that comes from Audible's
|
||||
servers. This will be used by ffmpeg to perform the initial audio convert. You
|
||||
can obtain this string from a tool like [audible-activator](https://github.com/inAudible-NG/audible-activator).
|
||||
|
||||
## Requirements
|
||||
* perl version 5.22.0 or later
|
||||
* bash 4.3.42 or later tested
|
||||
* ~~perl version 5.22.0 or later~~ (Converted the script to bash for greater readability!)
|
||||
* ffmpeg version 2.8.3 or later
|
||||
* libmp3lame (came from lame package on Arch, not sure where else this is stored)
|
||||
|
||||
You will also require the following perl modules:
|
||||
* autodie
|
||||
* Getopt::Long
|
||||
* File::Basename
|
||||
* IO::CaptureOutput
|
||||
|
||||
I would suggest installing cpanminus either through CPAN or (preferably) through your
|
||||
distro's repositories. Take note that many perl modules can be packaged in your repos
|
||||
as well so take a look there before resorting to cpan/cpanminus.
|
||||
|
||||
## Usage
|
||||
```
|
||||
perl AAXtoMP3.pl -a AUTHCODE -i AAXFILE -v
|
||||
bash AAXtoMP3.sh <AUTHCODE> {INPUT_FILES}
|
||||
```
|
||||
* -a: **your** Audible auth code (it won't correctly decode otherwise) (required)
|
||||
* -i: the input AAX file to be converted (required)
|
||||
* -v: verbose (optional)
|
||||
* AUTHCODE: **your** Audible auth code (it won't correctly decode otherwise) (required)
|
||||
* Everything else is considered an input file, useful for batching!
|
||||
|
||||
Tested on Linux with the above requirements. No effort will be made to
|
||||
port this work to any other operating system, though it may work fine. Want a Windows/
|
||||
@ -59,24 +55,7 @@ hear, and enjoy. Don’t be a parasite.
|
||||
This blurb is borrowed from the https://apprenticealf.wordpress.com/ page.
|
||||
|
||||
## License
|
||||
The MIT License
|
||||
Changed the license to the WTFPL, do whatever you like with this script. Ultimately it's just a front-end for ffmpeg after all.
|
||||
|
||||
Copyright (c) 2015 KrumpetPirate
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
## Need Help?
|
||||
I'll help out if you are having issues, just submit and issue and I'll get back to you when I can.
|
||||
|
Loading…
Reference in New Issue
Block a user