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
|
Copyright (c) 2015 KrumpetPirate
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Everyone is permitted to copy and distribute verbatim or modified
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
copies of this license document, and changing it is allowed as long
|
||||||
in the Software without restriction, including without limitation the rights
|
as the name is changed.
|
||||||
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
|
DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE
|
||||||
copies or substantial portions of the Software.
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
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
|
create a method for you to download and store your books just in case
|
||||||
Audible fails for some reason.
|
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
|
## Setup
|
||||||
You will need your four byte authitication code that comes from Audible's
|
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
|
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).
|
can obtain this string from a tool like [audible-activator](https://github.com/inAudible-NG/audible-activator).
|
||||||
|
|
||||||
## Requirements
|
## 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
|
* ffmpeg version 2.8.3 or later
|
||||||
* libmp3lame (came from lame package on Arch, not sure where else this is stored)
|
* 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
|
## 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)
|
* AUTHCODE: **your** Audible auth code (it won't correctly decode otherwise) (required)
|
||||||
* -i: the input AAX file to be converted (required)
|
* Everything else is considered an input file, useful for batching!
|
||||||
* -v: verbose (optional)
|
|
||||||
|
|
||||||
Tested on Linux with the above requirements. No effort will be made to
|
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/
|
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.
|
This blurb is borrowed from the https://apprenticealf.wordpress.com/ page.
|
||||||
|
|
||||||
## License
|
## 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
|
## 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.
|
||||||
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.
|
|
||||||
|
Loading…
Reference in New Issue
Block a user