网易云音乐缓存文件

2023-05-16

1.Ubuntu版的网易云音乐已经懒得加密了吗…名字里甚至都已经带了md5码的加密方法…

╰─$ ls ~/.cache/netease-cloud-music/CachedSongs 
567602-128-55881971d77b3ec1a5a134e2670a72e7.mp3

2.如果是windows或Android,需要借助Python脚本解密加密了的缓存文件

解密用Python脚本来源:https://github.com/mbinary/netease-cached-music

使用方法:

将缓存文件放到脚本文件所在目录下,在python3中运行该脚本。解密结果会输出到”cached_网易云音乐“目录下。

以下为解密用脚本:(注:因为Python2.7对UTF8编码的支持问题,需要Python3或以上版本)

#coding : utf-8
import os
import sys
import glob
import requests

DESDIR = './cached_网易云音乐'
LRCDIR = os.path.join(DESDIR, 'lyric')
MSCDIR = os.path.join(DESDIR, 'music')

API = 'https://api.imjad.cn/cloudmusic/?'
# two args: id  type
# type=song, lyric, comments, detail, artist, album, search
# eg  API = 'https://api.imjad.cn/cloudmusic/?type=song&id=1234132'    download music

hasModu = False
try:
    from mutagen.easyid3 import EasyID3
    from mutagen.mp3 import MP3
    hasModu = True
except:
    pass

def safeprint(s):
    '''deal with invalid encoded filename'''
    try:
        print(s)
    except:
        print(repr(s)[1:-1])

class netease_music:
    def __init__(self, path=''):
        '''path is the direcoty that contains Music files(cached)'''
        if path == '':
            path = input('input the path of cached netease_music')
        self.path = path
        safeprint('[+] Current Path: ' + path)
        os.chdir(path)
        self.files = glob.glob('*.uc') + glob.glob('*.uc!')
        self.id_mp = {}
        for i in self.files:
            self.id_mp[self.getId(i)] = i
        if not os.path.exists(DESDIR):
            os.mkdir(DESDIR)
        if not os.path.exists(LRCDIR):
            os.mkdir(LRCDIR)
        if not os.path.exists(MSCDIR):
            os.mkdir(MSCDIR)
        # import re
        # self.nameXpath ='//div[@class="tit"]/em[@class="f-ff2"]/text()'
        # self.lrcSentencePt=re.compile(r'\[\d+:\d+\.\d+\](.*?)\\n')         # wrong  (r'\[\d+,\d+\](\(\d+,\d+\)(\w))+\n')

    def getId(self, name):
        return name[:name.find('-')]

    def getInfoFromWeb(self, musicId):
        dic = {}
        url = API+'type=detail&id=' + musicId
        info = requests.get(url).json()['songs'][0]
        dic['artist'] = [info['ar'][0]['name']]
        dic['title'] = [info['name']]
        dic['cover'] = [info['al']['picUrl']]
        return dic

    def getInfoFromFile(self, path):
        if not os.path.exists(path):
            safeprint('Can not find file ' + path)
            return {}
        elif hasModu:
            return dict(MP3(path, ID3=EasyID3))
        else:
            print('[Error] You can use pip3 to install mutagen or connet to the Internet')
            raise Exception('Failed to get info of ' + path)

    def getPath(self, dic,musicId):
        title = dic['title'][0]
        artist = dic['artist'][0]
        if artist in title:
            title = title.replace(artist, '').strip()
        name = (title + '--' + artist)
        for i in '>?*/\:"|<':
            name = name.replace(i,'-') # form valid file name
        self.id_mp[musicId] = name
        #print('''{{title: "{title}",artist: "{artist}",mp3: "http://ounix1xcw.bkt.clouddn.com/{name}.mp3",cover: "{cover}",}},'''\
               #.format(title = title,name = name,artist=artist,cover=dic['cover'][0]))
        return os.path.join(MSCDIR, name + '.mp3')
    
    def decrypt(self, cachePath):
        musicId = self.getId(cachePath)
        idpath = os.path.join(MSCDIR, musicId + '.mp3')
        try:  # from web
            dic = self.getInfoFromWeb(musicId)
            path = self.getPath(dic,musicId)
            if os.path.exists(path): return 
            with open(path,'wb') as f:
                f.write(bytes(self._decrypt(cachePath)))
        except Exception as e:  # from file
            print(e)
            if not os.path.exists(idpath):
                with open(idpath,'wb') as f:
                    f.write(bytes(self._decrypt(cachePath)))
            dic = self.getInfoFromFile(idpath)
            path = getPath(dic,musicId)
            if os.path.exists(path):
                os.remove(idpath)
                return 
            os.rename(idpath, path)
            
    def _decrypt(self,cachePath):
        with open(cachePath, 'rb') as f:
            btay = bytearray(f.read())
        for i, j in enumerate(btay):
            btay[i] = j ^ 0xa3
        return btay
    
    def getLyric(self, musicId):
        name = self.id_mp[musicId]
        url = API + 'type=lyric&id=' + musicId
        url2 = 'https://music.163.com/api/song/lyric?id='+ musicId +'&lv=1&kv=1&tv=-1'
        try:
            lrc = requests.get(url).json()['lrc']['lyric']
            if lrc=='':
                lrc = requests.get(url2).json()['lrc']['lyric']
            if lrc=='':
                raise Exception('')
            file = os.path.join(LRCDIR, name + '.lrc')
            if not os.path.exists(file):
                with open(file, 'w', encoding='utf8') as f:
                    f.write(str(lrc))
        except Exception as e:
            print(e,end='')
            safeprint(': Failed to get lyric of music '+name)
    def getMusic(self):
        for ct, cachePath in enumerate(self.files):
            self.decrypt(cachePath)
            musicId = self.getId(cachePath)
            print('[{}]'.format(ct+1).ljust(5)+self.id_mp[musicId])
            self.getLyric(musicId)


if __name__ == '__main__':
    if len(sys.argv) > 1:
        path = sys.argv[1].strip()
    else:
        path = os.path.join(os.getcwd(), '.')
    handler = netease_music(path)
    handler.getMusic()
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

网易云音乐缓存文件 的相关文章

随机推荐

  • MySQL占用CPU过高,排查原因及解决的多种方式法

    一 mysql中的wait timeout坑 mysql gt show variables like 39 timeout 39 首先你要明白 wait timeout 指的是mysql在关闭一个非交互的连接之前所要等待的秒数 xff0c
  • Linux系统Debian安装

    虚拟机VMware安装Debian 小白教程 最近学习中顺便做了个文档 xff0c 下载 一 下载Debian 网址 xff1a https www debian org distrib 二 安装Debian8 1 选择稍后安装操作系统 2
  • sqlite3

    一 版本 从 www sqlite org 网站可下载到最新的 sqlite 代码和编译版本 写此文章时 xff0c 最新代码是 3 3 17 版本 二 基本编译 把 sqlite3 c 和 sqlite3 h 添加到工程 xff0c 再新
  • arduino esp8266开发板下载出错解决方法

    常规 arduino esp8266开发板下载安装流程 xff1a 第一步 xff0c 在arduino界面 xff0c 选择 文件 首选项 xff1a 找到附加开发板管理器网址 xff0c 将下面网址复制进去 xff1a http ard
  • linux C编程4-系统信息/时间/内存分配/随机数/定时器

    目录 1 获取系统信息 1 1 uname 函数 1 2 sysinfo 函数 1 3 gethostname 函数 1 4 sysconf 函数 1 5 getpagesize 函数 2 时间 日期 2 1 查看utc时间 2 2 查看系
  • IntelliJ IDEA插件之下载和安装方式

    IntelliJ IDEA插件下载与安装 下载方式官网下载如下图 IDEA内下载如下图 安装方式直接安装如下图 下载插件到本地安装如下图 下载方式 官网下载 如下图 IDEA内下载 如下图 进入Settings页面 xff08 File g
  • IntelliJ IDEA插件之TranslationPlugin

    IntelliJ IDEA插件之TranslationPlugin 下载地址安装插件概述使用如下图 下载地址 下载地址 安装插件 安装方式 概述 翻译他人代码或者源码中的英文 使用如下图
  • IntelliJ IDEA插件之Power Mode II

    IntelliJ IDEA插件之Power Mode II 下载地址安装插件概述使用如下图 下载地址 下载地址 安装插件 安装方式 概述 Power Mode II是写代码的时候体验狂拽酷炫的效果 使用如下图
  • IntelliJ IDEA插件之Background Image Plus +

    IntelliJ IDEA插件之Background Image Plus 43 下载地址安装插件概述 下载地址 下载地址 安装插件 安装方式 概述 IDEA 背景修改插件
  • IntelliJ IDEA插件之Free MyBatis plugin

    IntelliJ IDEA插件之Free MyBatis plugin 下载地址安装插件概述 下载地址 下载地址 安装插件 安装方式 概述 mapper接口与对应xml文件对应
  • MySQL Workbench 8.0 CE 汉化包下载

    MySQL Workbench 8 0 CE 汉化包下载 下载地址 xff1a 汉化文件下载 下载提示 xff1a 下载过程进度文件页面右键另存为即可保存文件到本地 1 把下载好的文件后放到此目录下替换此文件 C Program Files
  • IntelliJ IDEA插件之CodeGlance

    IntelliJ IDEA插件之CodeGlance 下载插件安装插件概述 下载插件 下载地址 安装插件 安装方式 概述 将类似于Sublime中的代码的微型地图嵌入到编辑器窗格中 使用您自定义的颜色对亮色和深色主题进行语法突出显示
  • IDEA Easy Code使用记录

    下载安装 xff08 忽略 xff09 设置 设置在idea的 Other Settings里面 分4个选项 Type Mapper 类型映射 xff08 数据字段和java包装器映射 xff09 Template Setting 模板设置
  • windows 10 安装MySQL5.7.25(支持多个MySQL实例)

    windows 10 安装MySQL5 7 25 下载安装包解压到对应路径 创建my ini 配置文件 xff0c 内容如下 span class token punctuation span mysql span class token
  • MySQL explain学习(MySQL版本5.7.25)

    MySQL explain学习 xff08 MySQL版本5 7 25 xff09 idselect typetablepartitionstype xff08 重要 xff09 possible keyskeykey lenrefrows
  • JAVA服务器端接入微信APP支付记录

    微信开发文档地址 xff1a https pay weixin qq com wiki doc api app app php chapter 61 8 1 业务流程图如下 xff1a 商户系统和微信支付系统主要交互说明 xff1a 步骤1
  • 小程序插入激励视频广告教程

    小程序插入激励视频广告教程 相关链接 xff1a 小程序插入banner广告小程序插入插屏广告 今天登陆小程序的后台 xff0c 收到了官方通知 xff0c 小程序激励式视频广告组件日前已上线 xff0c 也就是说可以在小程序中插入激励视频
  • Latex公式中符号上下分别加横线的写法

    下划线 xff1a underline p 效果 xff1a p underline p p 上划线 xff1a overline p 效果 xff1a
  • Error: Unable to find a match

    Error Unable to find a match 当服务器安装软件包出现 xff1a Error Unable to find a match 错误 要么是软件名称写错 xff0c 要么是根本没有这个软件包 缺少系统或者软件repo
  • 网易云音乐缓存文件

    1 Ubuntu版的网易云音乐已经懒得加密了吗 名字里甚至都已经带了md5码的加密方法 ls cache netease cloud music CachedSongs 567602 128 55881971d77b3ec1a5a134e2