简单明了地解析和生成 163key 字符串
Project description
简介
ncm-163key-parser
项目意图以简单明了的方式操纵网易云音乐歌曲标识符(即“163 key”)。
使用须知
本项目是以学习和技术研究的初衷创建的,修改、再分发时请遵循许可协议。
本项目虽然可以读取网易云音乐加密文件格式 .ncm
中的标识符,但是不可也无法移除中音频数据的加密保护!如果你是为此而来,请自行搜索并尝试其他项目!
支持特性
- 解析标识符为元数据。
- (仅限 Python 调用)简明地编辑解析的元数据。
- (仅限 Python 调用)将元数据还原为标识符。
- 支持 PC 和 Android 平台的网易云音乐客户端下载的文件包含的标识符。
- 是的,两个平台、不同版本的客户端下载的文件,包含的元数据不一致。
- (等待实现)同时也是命令行工具,可用于直接读取和解析文件中的标识符。
- 支持的文件类型包括:
- 普通音频文件(.flac、.mp3)
- 网易云音乐加密文件格式
.ncm
。(本项目不支持移除其音频的加密保护)
- 支持的文件类型包括:
- 纯 Python 实现,包括依赖包在内,没有任何 C 扩展模块,洁癖人士的不二之选。
安装
所需依赖
获取方式
PyPI(推荐)
或者在命令行使用 pip
下载安装:
$ > python -m pip install ncm-163key-parser
从本仓库获取
前往当前版本发布页,此处提供了 Wheel 包下载。
安装下载的 Wheel 包:
python -m pip install /path/to/ncm_163key_parser-[version]-py3-none-any.whl
使用方法
命令行工具(待实现)
Python 调用
以下是示例用法。如果想要玩出花样,请在使用时关注你使用的 IDE 对本模块函数、类和方法的提示信息,这样有助于你了解 API。
- 导入模块
>>> import ncm163key
>>>
解析标识符
-
使用
loads()
加载一个标识符,该函数可接受str
或字节对象形式的标识符:>>> metadata1 = ncm163key.loads("163 key(Don't modify):...") >>> metadata1 NCMMusicMetadataForAndroid(musicName='METHOD_HYMME_AMENOFLAME/.', musicId=471403213, artist={'stellatram': 12023150}, album='Kaleido Sphere ~天淵の双つ星~', albumId=35338410, albumPic='http://...', ...) >>> metadata2 = ncm163key.loads(b"163 key(Don't modify):...") >>> metadata2 NCMMusicMetadataForPCv1NCM(musicName='忘れじの言の葉 (feat. 安次嶺希和子) [2022]', musicId=1972641406, artist={'未来古代楽団': 12131344, '安次嶺希和子': 30104787}, album='忘れじの言の葉/エデンの揺り籃', albumId=149778835, albumPic='https://...', ...) >>>
-
如果使用了自定义的标识符加密密钥,通过参数
alter_id_key
传递给函数:>>> ncm163key.loads("163 key(Don't modify):...", alter_id_key=b'...') >>> ncm163key.loads(b"163 key(Don't modify):...", alter_id_key=b'...') >>>
查看解析出的元数据
以下列出了几种常用信息的获取方法。除非特殊说明,所有以“Id”结尾的属性都是 int
对象。
-
歌曲名称和 ID
musicName
- 歌曲名称(即标题)musicId
- 歌曲 ID- 注意:如果你的下载文件来源是网易云音乐 PC 端 3.0.0 及以上版本,
musicId
将会是一个str
而不是int
对象。
- 注意:如果你的下载文件来源是网易云音乐 PC 端 3.0.0 及以上版本,
>>> metadata1.musicName 'METHOD_HYMME_AMENOFLAME/.' >>> metadata1.musicId 471403213 >>>
-
歌手列表和歌手 ID:
artist
- 是一个定制的类字典对象,键(str)为歌手名称,值(int)为歌手 ID,会尝试自动转换被赋予的值artist_prettify()
- 根据artist
生成的美化后的歌手列表,默认使用顿号“、”分割每个歌手名称
>>> metadata1.artist {'stellatram': 12023150} >>> metadata1.artist_prettify() 'stellatram' >>> metadata2.artist_prettify() '未来古代楽団、安次嶺希和子' >>> metadata2.artist_prettify(sep=' | ') '未来古代楽団 | 安次嶺希和子' >>>
-
专辑名称、ID 和专辑封面链接:
album
- 专辑名称albumId
- 专辑 IDalbumPic
- 专辑封面下载链接
>>> metadata1.album 'Kaleido Sphere ~天淵の双つ星~' >>> metadata1.albumId 35338410 >>> metadata1.albumPic 'http://p2.music.126.net/cPwdlJxGCtX0e2L3SMQksg==/18915998044327357.jpg' >>>
-
flac
- 歌曲的音频格式>>> metadata1.format 'flac' >>>
-
歌曲时长
duration
- 歌曲时长,单位为毫秒duration_seconds
(只读) - 歌曲时长,由duration
除以 1000 得到,与duration
同步变化,单位为秒
>>> metadata.duration # 单位为毫秒 294026 >>> metadata.duration_seconds # metadata.duration_seconds 除以 1000,单位为秒 294.026 >>>
修改元数据
所有属性都是可修改的,但请注意,属性对类型甚至结构都有严格要求。以 bitrate
和 metadata.artist
为例:
metadata.bitrate
:仅接受非负整数。
>>> metadata.bitrate
984052
>>> metadata.bitrate = 1000000 # OK
>>> metadata.bitrate
1000000
>>> metadata.bitrate = '2000000' # TypeError
Traceback (most recent call last):
...
TypeError: 'bitrate' must be <class 'int'> (got '2000000' that is a <class 'str'>).
>>> metadata.bitrate = -1000000 # ValueError
Traceback (most recent call last):
...
ValueError: 'bitrate' must be >= 0: -1000000
>>>
metadata.artist
:仅接受可以转换为字典的对象;键必须是字符串,对应的值必须是整数,否则会引发TypeError
。
>>> metadata1.artist
{'stellatram': 12023150}
>>> metadata1.artist['群星'] = 122455 # OK
>>> metadata1.artist
{'stellatram': 12023150, '群星': 122455}
>>> metadata1.artist = {
... 'stellatram': 12023150,
... '未来古代楽団': 12131344,
... '安次嶺希和子': 30104787
... } # 尝试使用真正的字典对象为 artist 属性赋值,OK
>>> metadata.artist
{'stellatram': 12023150, '未来古代楽団': 12131344, '安次嶺希和子': 30104787}
>>> metadata.artist = 'stellatram' # ValueError
Traceback (most recent call last):
...
ValueError: not enough values to unpack (expected 2, got 1)
>>> metadata.artist = 12023150 # TypeError
Traceback (most recent call last):
...
TypeError: 'artist' must be <class 'ncm163key._ArtistsMapping'> (got 12023150 that is a <class 'int'>).
>>> metadata.artist[12023150] = 12023150 # TypeError
Traceback (most recent call last):
...
TypeError: non-str object are not available for the mapping keys: 12023150 ('int')
>>> metadata1.artist['stellatram'] = '12023150' # TypeError
Traceback (most recent call last):
...
TypeError: non-int object are not available for the mapping values: '12023150' ('str', key='stellatram')
>>>
将元数据还原为标识符
>>> ncm163key.dumps(metadata)
"163 key(Don't modify):..."
>>>
- 如果要使用自定义的标识符加密密钥,通过参数
alter_id_key
传递给函数:
>>> ncm163key.dumps(metadata, alter_id_key=b'...')
b"163 key(Don't modify):..."
>>>
(可能的)常见问题
这个项目能输出 NCM 文件的音频内容吗?
不行,以后也不可能。下一个。
我没听说过
pyaes
这个包,为什么要用它做 AES 加解密,而不用pycryptodome
?
标识符的加解密使用了 AES,没有其他加密方式,因此使用 pyaes
这种简单的 AES 算法实现就足够了,pycryptodome
这种大而全的加密算法库显得有些臃肿。
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Hashes for ncm_163key_parser-0.1.0-py3-none-any.whl
Algorithm | Hash digest | |
---|---|---|
SHA256 | 7e4f41d19568ce54fc01bfc310d1d5f927ecb5a4d0a5b5174d52ade6b5f6b822 |
|
MD5 | d1f62a396b182e48ab9da388bf843f14 |
|
BLAKE2b-256 | 3f14b5ecf385534abd4b3007ef3602ca5f361f4829ede8f3750de32899dd6ebb |