u/mkb79

10 post karma · 15 comment karma · joined Feb 2019

mkb79

If you have a device backup a restore could help you.

mkb79

I’ve been experimenting with Rust for quite a while, but the idea of porting audible-cli only came to me after seeing the performance improvements Rust can offer for database-heavy operations. I also really like how quickly Cargo checks, Clippy, and rustfmt catch many problems before they turn into actual bugs.
So I started building it — partly for the technical benefits and partly because it gave me a good excuse to dig deeper into Rust. :)
The longer-term goal is to use the agent built into audible-rs as a backend, so that every CLI operation can also be controlled through a browser-based web interface.
At the moment, though, the biggest thing holding the project back is a lack of testers. I’d like to get it out of alpha and publish the first 0.1.0 release, but broader testing and real-world feedback would help a lot.

mkb79

Thank you — that genuinely made my day. Comments like this are a big part of what keeps an alpha moving, so I really appreciate you taking the moment to say it.

If you (or anyone reading) end up trying it, I'm grateful for feedback of any kind — bug reports, rough edges, "this was confusing", or feature ideas — via a GitHub issue, a Discussion, or simply an email. Even a plain "worked fine on my setup" is valuable, because at this stage I mostly only hear about things when they break.

One honest heads-up: quite a few features that already work aren't in the README yet.
I've been holding off on writing proper docs while everything is still in flux — in an alpha, commands and flags can still shift, and I'd rather not document something today and have it change next week. Full docs are firmly on the list once the surface settles.

So in case they're useful before then, a few of the less obvious things it can already do:

- Download Widevine-only titles — the Audible Plus / AYCL titles that ship no `aaxc` asset — via Widevine. That needs a Widevine CDM, which you provision yourself through an Android device registration (none is bundled).
- Flexible passphrase sources for your auth file — a prompt, an env var, an external command (your keyring, gpg, …) or a file — so fully headless/automated setups work.
- download reorganize — change your filename template or download folder later and it migrates both the files on disk *and* their database records to match.
- Listening stats & membership status — `audible stats` (per month/year/marketplace) and an account overview, straight from the API.

There's also a plugin system with a small Python SDK. As a first example it ships a plugin that opens your whole library in the browser — sortable, searchable, with a detail panel per title and per-item download status. It's read-only for now, but it's really a starting point; a lot more is possible on top of it. If you want to try it:

# 1) the plugin SDK isn't on PyPI yet, so install it from the repo:
pip install "git+https://github.com/mkb79/audible-rs.git#subdirectory=sdk/python"

# 2) install the example plugin straight from the repo (it shows you the checksum + requested scopes and asks you to confirm before installing):
audible plugin add https://raw.githubusercontent.com/mkb79/audible-rs/main/examples/plugins/cmd_library-gui.py

# 3) run it — opens a local dashboard of your library in your browser:
audible -m all library-gui

(`-m all` just means "show every marketplace of the account"; it binds to localhost with a
one-time token, and the plugin only ever talks to the API through the CLI — it never sees
your credentials.)

Thanks again for the kind words — it really means a lot this early on. 🙏

mkb79

Sorry about that — the repo is very much online, it was just a broken link in my
post (the markdown swallowed a trailing character and turned it into a 404). Here's
the plain URL:

https://github.com/mkb79/audible-rs

Thanks for the heads-up!

mkb79

Hi openaudible,

I does not know yet, that you have open sourced your code. I can not find it on GitHub.

I know that you have taken my code, how to download aaxc files and how to decrypt the encrypted license response. Then you have translate this in your programming language. I've wrote with you or something from your project about this thematic in early 2021.

Edit:

Sorry, I misunderstood your above post. Yes, I can confirm that the source code of a very old version of OpenAudible is public. But it should be noted that you include the discoveries of the open source community into your commercial product. The question will then arise whether you will share your discoveries about Audible with us free of charge?

mkb79

Libation don't upload the user credentials. So Libation is safe for use. Another great tool with GUI is BookLibConnect. That’s a great tool, open source and free.

mkb79

OpenAudible using open source code under AGPLv3 license and keep there code private.

mkb79

There are some good free tools for this purpose. Libation and Book Lib Connect is the best choice if you need a GUI. Or you can use my Audible CLI app.

mkb79

Yeah, I know. I've written audible-cli which can download audiobooks from Audible, too. But my app does not have any GUI, so you have to work with the CLI. That’s why my app is not so well known as Libation or other great (most) free apps.

mkb79

If you download it from the Audible website, then you have AAX files. But the website will not let you download books from the Plus catalog.

mkb79

Audible deliver there audiobooks in AAXC format since some time. AAXC is an encrypted M4A container. Instead of the previous AAX format, AAXC uses an unique key for each account/book combination. So inAudible will don't help you here.

mkb79

Here you can find a gist to login to goodreads to obtain your credentials to fully access theirs API

mkb79

One user created a plugin for my app. With these you are able to import your audible library data to Goodreads. Take a look here for more information.

mkb79

I think so too. Maybe they will bring the AAXC format to all devices. They have done this with the iOS and Android app already.

mkb79

It seems all blank lines are removed in the code. You have to adjust them by yourself.

mkb79

How looks this for you?

```python

import random import string

while True:

def ask_for_yes_no(question: str) -> bool:
    while True:
        answer = input(question + " [yes/no]: ").lower()
        if answer in ["yes", "no"]:
            break
        print("Please answer with yes or no!\n")

    return True if answer == "yes" else False

def get_random_string(length: int, allowed_chars: str):
    return ''.join(random.choices(allowed_chars, k=length))

lenght = int(input("How long do you want the password to be? [in numbers] "))
wantNums = ask_for_yes_no("Do you want numbers in the password?")
wantUppers = ask_for_yes_no("Do you want uppercase letters?")

def passGen(lenght):

    if wantNums and wantUppers:
        chars = string.ascii_letters + string.digits
        print(get_random_string(lenght, chars))

    elif not wantNums and wantUppers:
        chars = string.ascii_letters
        print(get_random_string(lenght, chars))

    elif wantNums and not wantUppers:
        chars = string.ascii_lowercase + string.digits
        print(get_random_string(lenght, chars))

    elif not wantNums and not wantUppers:
        chars = string.ascii_lowercase
        print(get_random_string(lenght, chars))

passGen(lenght)

restart = ask_for_yes_no("Do you want another password?")
if not restart:
    print("Goodbye!")
    break

```

mkb79

Hi,

you can write while True: instead using a variable.

To exit the while loop you can write:

```python

if restart.lower() != "yes":
    print("Goodbye!")
    break

```

mkb79

You can find here https://www.epubor.com/how-to-convert-audible-aaxc-to-mp3.html some infos about that problem.

When I download books with my audible api client (https://github.com/mkb79/Audible) I have same problems. I can’t convert them. But I get some additional informations when I make a licenserequest to the api. Maybe they help to decode the file.

Here are a sample output:

{
    "content_license": {
        "acr": "CR!...",
        "asin": "B07DDKJH33",
        "content_metadata": {
            "content_url": {
                "offline_url": "https://dyrrggeck87jc.cloudfront.net/.../bk_adko_003749ade_lc_128_44100_2.aax?voucherId=cdn:...&Policy=...&Signature=...&Key-Pair-Id=..."
            }
        },
        "drm_type": "Adrm",
        "license_response": "...==",
        "message": "Eligibility details:[GrantRightsReason [reasonCode=MEMBERSHIP, reason=No need to verify active offline license when request is not for offline consumption. OWNERSHIP-user does not have expected ownership rights over the parent title asin. OWNERSHIP-title does not qualify for long title child part ownership or customer does not own child part. OWNERSHIP-user has ownership rights. GEO_RIGHTS-user has geo-rights[DE] over the title[B07DDKJH33] in marketplaceId[AN7V1F1VY261K]. TITLE_ATTRIBUTES-title does not have rodizio plan association. GEO_RIGHTS-user has geo-rights[DE] over the title[B07DDKJH33] in marketplaceId[AN7V1F1VY261K]. No need to verify active offline license when request is not for offline consumption. BENEFIT-user has valid Radio benefit associated[RadioStub]. TITLE_ATTRIBUTES-title does not have radio plan association. Client Asin Mapping validation skipped since client id is null. AAA Client with id: ApolloEnv:AudibleApiExternalRouterService/EU/Prod, does not have access to asin: B07DDKJH33. Client does not have plans that support asin benefits.]]. Licensing details:[ADRM license granted]",
        "request_id": "...",
        "status_code": "Granted",
        "voucher_id": "cdn:..."
    },
    "response_groups": [
        "always-returned"
    ]
}

I have shorten the ouput on many places with ...! You can use my audible api client and create your own.

Greets

mkb79

I‘ve tested this now a bit. I make 200 requests (retrieve my own library) in ~ 4 mins and don’t be blocked.

mkb79

I‘m testing the API for month with hundreds of requests. Some of these tests are done within very short time interval and I don’t get in any request blocking. But you can test this out. Use omarroth‘s or my client.

mkb79

Please check out my audible API client (https://github.com/mkb79/Audible) or omarroths client (https://github.com/omarroth/audible.cr) for informations about the api.

mkb79

Why scrapping the whole site and don’t use the audible api?

mkb79

Hi Lynn_K I have updated the audible api on pypi. You can crawl the webpage from audible with this code now:

``` import audible import requests

client = audible.Client(EMAIL, USERNAME, local="your local code here")

example for get library

url = "https://www.audible.com/a/library" payload = { "purchaseDateFilter": "all", "programFilter": 'all', "sortBy": "SHORT_TITLE.asc", "pageSize": "20", "page": 1 } response = requests.get( url, params=payload, cookies=client.login_cookies ) page = response.text

```

Maybe this helps you. And don’t forget to update the audible package with pip install --update audible before.

mkb79

You‘re fast ;)

mkb79

2FA isn’t that difficult. I have implement them in my code in audible.py at line 189:211 (cvf part). I tested this with my german account. The code will be send to my mobile phone.