Compare commits

..

No commits in common. '54ed3e2e6e2556e43f6e357d8a239113f9552ebe' and '0d01836d1e921ee83afa4f03b931979ef0288210' have entirely different histories.

  1. 35
      README.md
  2. 9
      src/cmd.py
  3. 9
      src/decrypt.py

@ -11,20 +11,18 @@ bugs and unfinished features. USE IT WITH CAUTION.**
```shell
# Download song/album with default codec (alac)
download https://music.apple.com/jp/album/nameless-name-single/1688539265
# Or a shorter command
dl https://music.apple.com/jp/album/nameless-name-single/1688539265
# Download song/album with specified codec
dl -c aac https://music.apple.com/jp/song/caribbean-blue/339592231
# Overwrite existing files
dl -f https://music.apple.com/jp/song/caribbean-blue/339592231
download https://music.apple.com/jp/song/caribbean-blue/339592231 -c aac
# Download specify artist's all albums
dl https://music.apple.com/jp/artist/%E3%83%88%E3%82%B2%E3%83%8A%E3%82%B7%E3%83%88%E3%82%B2%E3%82%A2%E3%83%AA/1688539273
download https://music.apple.com/jp/artist/%E3%83%88%E3%82%B2%E3%83%8A%E3%82%B7%E3%83%88%E3%82%B2%E3%82%A2%E3%83%AA/1688539273
# Download specify artist's all songs
dl --include-participate-songs https://music.apple.com/jp/artist/%E3%83%88%E3%82%B2%E3%83%8A%E3%82%B7%E3%83%88%E3%82%B2%E3%82%A2%E3%83%AA/1688539273
download https://music.apple.com/jp/artist/%E3%83%88%E3%82%B2%E3%83%8A%E3%82%B7%E3%83%88%E3%82%B2%E3%82%A2%E3%83%AA/1688539273 --include-participate-songs
# Download all songs of specified playlist
dl https://music.apple.com/jp/playlist/bocchi-the-rock/pl.u-Ympg5s39LRqp
download https://music.apple.com/jp/playlist/bocchi-the-rock/pl.u-Ympg5s39LRqp
# Download song from specified m3u8 with default codec (alac)
m3u8 https://aod.itunes.apple.com/itunes-assets/HLSMusic116/v4/cb/f0/91/cbf09175-ce98-d133-1936-2e46b6992aa5/P631756252_lossless.m3u8
# Start Mitm mode
mitm
```
# Support Codec
@ -105,3 +103,24 @@ poetry install
cp config.example.toml config.toml
poetry run python main.py
```
# Mitm Mode
## Prepare Environment
1. Install [Proxifier](https://www.proxifier.com/) and [Apple Music Windows](https://apps.microsoft.com/detail/9pfhdd62mxs1)
2. Sign in to Apple Music Windows with your Apple account
3. Run `poetry run mitmproxy` under the script directory and quit
4. Install the CA certificate according
to [Mitmproxy's instructions](https://docs.mitmproxy.org/stable/concepts-certificates/#quick-setup)
5. Create a new proxy server in Proxifier(`Profile -> Proxy Servers -> Add`). `Address` and `Port` are values
of `mitm.host` and `mitm.port` in `config.toml`, and `Protocol` is `SOCKS Version 5`
6. Create a new proxification rule in Proxifier(`Profile -> Proxy Servers -> Add`). Fill in `Applications` field
with `amplibraryagent.exe; applemusic.exe` and select the proxy server just created in `Action`
## Start Mitm
1. Run the script, type command `mitm`
2. Start Proxifier
3. Start Apple Music Windows and play a song or an album.
4. Now the script should catch the m3u8 link and start ripping

@ -40,21 +40,20 @@ class NewInteractiveShell:
download_parser.add_argument("-c", "--codec",
choices=["alac", "ec3", "aac", "aac-binaural", "aac-downmix", "ac3"],
default="alac")
download_parser.add_argument("-f", "--force", default=False, action="store_true")
download_parser.add_argument("--include-participate-songs", default=False, dest="include", action="store_true")
# download_from_file_parser = subparser.add_parser("download-from-file", aliases=["dlf"])
download_parser.add_argument("-f", "--force", type=bool, default=False)
download_parser.add_argument("--include-participate-songs", type=bool, default=False, dest="include")
m3u8_parser = subparser.add_parser("m3u8")
m3u8_parser.add_argument("url", type=str)
m3u8_parser.add_argument("-c", "--codec",
choices=["alac", "ec3", "aac", "aac-binaural", "aac-downmix", "ac3"],
default="alac")
m3u8_parser.add_argument("-f", "--force", default=False, action="store_true")
m3u8_parser.add_argument("-f", "--force", type=bool, default=False)
subparser.add_parser("exit")
mitm_parser = subparser.add_parser("mitm")
mitm_parser.add_argument("-c", "--codec",
choices=["alac", "ec3", "aac", "aac-binaural", "aac-downmix", "ac3"],
default="alac")
mitm_parser.add_argument("-f", "--force", default=False, action="store_true")
mitm_parser.add_argument("-f", "--force", type=bool, default=False)
logger.remove()
logger.add(lambda msg: print_formatted_text(ANSI(msg), end=""), colorize=True, level="INFO")

@ -24,12 +24,12 @@ async def decrypt(info: SongInfo, keys: list[str], manifest: Datum, device: Devi
else:
logger.info(f"Using device {device.serial} to decrypt song: {manifest.attributes.artistName} - {manifest.attributes.name}")
try:
reader, writer = await asyncio.open_connection(device.host, device.fridaPort, limit=2**14)
reader, writer = await asyncio.open_connection(device.host, device.fridaPort)
except ConnectionRefusedError:
logger.warning(f"Failed to connect to device {device.serial}, re-injecting")
device.restart_inject_frida()
raise RetryableDecryptException
decrypted = []
decrypted = bytes()
last_index = 255
for sample in info.samples:
if last_index != sample.descIndex:
@ -59,11 +59,10 @@ async def decrypt(info: SongInfo, keys: list[str], manifest: Datum, device: Devi
else:
logger.error(f"Failed to decrypt song: {manifest.attributes.artistName} - {manifest.attributes.name}")
raise DecryptException
now += 1
decrypted.append(result)
decrypted += result
writer.write(bytes([0, 0, 0, 0]))
writer.close()
return bytes().join(decrypted)
return decrypted
async def decrypt_sample(writer: asyncio.StreamWriter, reader: asyncio.StreamReader, sample: SampleInfo) -> bytes:

Loading…
Cancel
Save