#!/usr/bin/python
|
import argparse
|
import os
|
import glob
|
import subprocess
|
import shlex
|
import json
|
|
# arguments
|
# activation_key, file name, codec(default to mp3)
|
parser = argparse.ArgumentParser()
|
parser.add_argument("--code", help="Activation Code from audible to decrypt files")
|
parser.add_argument("--single", help="Use this option to create a single file")
|
parser.add_argument("--dpath", help="Use this to set the destination path. Otherwise I will use the current directory")
|
parser.add_argument("-v", "--verbose", help="Send output to stdout", action="store_true")
|
parser.add_argument("filename", help="Filename to convert, or directory to look in")
|
|
args = parser.parse_args()
|
|
act_byte = ""
|
metadata = ""
|
|
|
def mungetrack(track):
|
# Making sure the Track is correct
|
c = track.strip('Chapter ')
|
c = c.zfill(2)
|
return c
|
|
|
def getmetadata(aaxfile):
|
ret = subprocess.check_output(["ffprobe", "-v", "quiet", "-hide_banner", "-show_format", "-show_chapters", "-print_format", "json", os.path.abspath(aaxfile)])
|
mdata = json.loads(ret)
|
return mdata
|
|
|
def getmetabitrate():
|
bit_rate = metadata['format']['bit_rate']
|
return bit_rate[:2]
|
|
|
def getmetadatatags(key):
|
# get specific data
|
tag = metadata['format']['tags'][key]
|
return tag
|
|
|
def reencode(aaxfile, outpath):
|
# decrypt and reencode to mp3
|
command = ("ffmpeg -loglevel error -stats -activation_bytes {} -i {} -vn -codec:a libmp3lame -ab {}k -map_metadata -1 "
|
"-metadata 'title={}' -metadata 'artist={}' -metadata 'album_artist={}' -metadata 'album={}' -metadata 'date={}' "
|
"-metadata track=1/1 -metadata 'genre={}' -metadata 'copyright={}' '{}'" ).format(act_byte,aaxfile,getmetabitrate(),
|
getmetadatatags('title'), getmetadatatags('artist'),
|
getmetadatatags('album_artist'), getmetadatatags('album'),
|
getmetadatatags('date'), getmetadatatags('genre'),
|
getmetadatatags('copyright'),outpath)
|
if args.verbose:
|
print command
|
process = subprocess.Popen(shlex.split(command), stdout=subprocess.PIPE)
|
while True:
|
output = process.stdout.readline()
|
if output == '' and process.poll() is not None:
|
break
|
if output:
|
print output.strip()
|
rc = process.poll()
|
return rc
|
else:
|
process = subprocess.Popen(shlex.split(command), stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
stderr, stdout = process.communicate()
|
return
|
|
|
|
if args.dpath:
|
path = args.dpath
|
else:
|
path = os.getcwd()
|
|
if args.code:
|
act_byte = args.code
|
elif os.path.isfile('./.authcode'):
|
act_byte = open('./.authcode').readline()
|
|
if act_byte == "":
|
print "Please provide an activation code from audible. Either at the command line or the .authcode file"
|
else:
|
print act_byte
|
|
for rfile in glob.glob(args.filename):
|
if rfile.find("aax") != -1 and os.path.isfile(rfile):
|
metadata = getmetadata(rfile)
|
album = getmetadatatags('album')
|
artist = getmetadatatags('artist')
|
title = getmetadatatags('title')
|
ddir = "%s/%s/%s" % (path, artist, title)
|
single_file_path = "%s/%s.mp3" % (ddir, title)
|
if not os.path.exists(ddir):
|
os.makedirs(ddir)
|
print ddir
|
reencode(rfile, single_file_path)
|
|
|