unreal无损音乐百度云_将网易云音乐专用的无损音乐格式转换成全平台通用的无损格式...

前几天发现网易云音乐的ncm格式很坑爹,由于网易云的部分音乐采取了这种流媒体平台模式,这种格式的歌曲下载到设备本地以后只有在网易云音乐的app上面才能播放,而且还要在会员生效期间才能播

今天网易云弄出一个ncm,明天百度音乐来一个cnm,后天酷狗推出nmb,大后天qq音乐又来了个rnm。目前国内的音乐版权可谓是乱到了一个极端,阿叉想听一个歌手的歌还得在酷狗和网易云之间来回跑,最终用户就成了受害者

花钱买的歌我们理所当然有权利支配,而不是短期的租借,所以在这里提供一个在尽量不影响音质的情况下将ncm格式转换成flac格式的方法

21c5c950ea9f7a7df43a3c3598db3389.png

↓↓↓↓↓↓↓↓↓

(链接挂了的话就尽情骚扰阿叉的微信吧)

使用方法就是把要转换的ncm音乐文件直接拖到 格式转换.exe上

然后flac格式的音乐文件就会自己变出来啦

↑↑↑↑↑↑↑↑↑

45565edf66fe6fc39d10e9c98fbe5897.png

以这首Sailing为例,经过转换以后得到了flac文件:

c2656a6dadd2367d9cceadd3e2b63233.png

把成品导入AU之后可以发现高频部分还是很完整的,完全符合无损音质的表现

7e1aaccffab356fcf7637c0acfd65710.png

和来自某狗的原版flac对比:

2bab5ca802c410867dde9e0ddf0fe998.png

可以明显看出,转码后高频部分没有被切掉,比特率都是968kbps,音质几乎没有区别,所以我们可以完美地完成无损到无损的转换

附上源代码和注释:

import binascii

import struct

import base64

import json

import os

from Crypto.Cipher import AES

def dump(file_path):

    core_key = binascii.a2b_hex("687A4852416D736F356B496E62617857")

    meta_key = binascii.a2b_hex("2331346C6A6B5F215C5D2630553C2728")

#core_key和meta_key,把这个字符串按照十六进制反解析为二进制字节序列(bytes类型)

    unpad = lambda s : s[0:-(s[-1] if type(s[-1]) == int else ord(s[-1]))]

    f = open(file_path,'rb')

    header = f.read(8)

    assert binascii.b2a_hex(header) == b'4354454e4644414d'

#打开ncm文件并读取8个字节,确认这8个字节是否是字节序列b'4354454e4644414d',0x43=C,所以这些字节是'CTENFDAM',说明这些就是ncm独有的文件标记

    f.seek(2, 1)

    key_length = f.read(4)

    key_length = struct.unpack('

    key_data = f.read(key_length)

    key_data_array = bytearray(key_data)

    for i in range (0,len(key_data_array)): key_data_array[i] ^= 0x64

#获取4字节的key,并且按照小端(

    key_data = bytes(key_data_array)

    cryptor = AES.new(core_key, AES.MODE_ECB)

    key_data = unpad(cryptor.decrypt(key_data))[17:]

#然后用之前的core_key创建了AES_ECB解密器,将整个明文分成若干段相同的小段,然后对每一小段进行加密,如果不足则会进行补足。

cryptor.decrypt(key_data)解析出来的是:

b'neteasecloudmusic10073261712832E7fT49x7dof9OKCgg9cdvhEuezy3iZCL1nFvBFd1T4uSktAJKmwZXsijPbijliionVUXXg9plTbXEclAE9Lb\r\r\r\r\r\r\r\r\r\r\r\r\r'

    key_length = len(key_data)

    key_data = bytearray(key_data)

    key_box = bytearray(range(256))

    c = 0

    last_byte = 0

    key_offset = 0

    for i in range(256):

        swap = key_box[i]

        c = (swap + last_byte + key_data[key_offset]) & 0xff

        key_offset += 1

        if key_offset >= key_length: key_offset = 0

        key_box[i] = key_box[c]

        key_box[c] = swap

        last_byte = c

#标准RC4-KSA算法去计算S-box

    meta_length = f.read(4)

    meta_length = struct.unpack('

    meta_data = f.read(meta_length)

    meta_data_array = bytearray(meta_data)

    for i in range(0,len(meta_data_array)): meta_data_array[i] ^= 0x63

    meta_data = bytes(meta_data_array)

    meta_data = base64.b64decode(meta_data[22:])

    cryptor = AES.new(meta_key, AES.MODE_ECB)

    meta_data = unpad(cryptor.decrypt(meta_data)).decode('utf-8')[6:]

    meta_data = json.loads(meta_data)

#meta_data的值是这样的:

b"163key(Don't modify):L64FU3W4YxX3ZFTmbZ+8/fOGFX4ZDFzRxiE6WTSCw8Wbw8yYSVQFmAmCHw9A96ZnO0UOuMsVWYFWvoqD0/YcH3r7VAGU8B3l+FBJm4JL6is23S2yXChnSbfLIksnEUcTC7JtrA1JAoR0GVnz+OT3hGTJRsjGIVQXg2yide/YKBACffE+oYBApqZ5Isq0n7h/MlBnjn6ihuSlIl5V2rXEjSISQr031eSBdEVJ/JcwttzLafIPBh2FQfaVd/U0inWY5jxCXZCw/jxcIdGmGH/0Oft3UlNPt2kDBrsivoVuD03tMWL6A5Flg/jCbofSOblHFC79oU3WF9doUjD24BXuu6K7wyoWkgyG7SJu8tk72hkGw3rLK1nbTHsSEIPjocC6Ba9mzF48SB087MFTSn+9PXPZIboMXFXGI3TpMj4rR6cD+6CEWS7EoZrUC1cipi/A0jT/rFtAirM4hmkbrvslJumMHDJz1q9o6t3XRWydyoIaC3ktXuesyV8sbuoQ+Y/EMWNZRN3KhGR/jnnQPBtseQ=="

前面有22位的“163 key(Don't modify):”,去掉之后用base64解码,并同样地通过AES_ECB和meta_key进行解密:

b'music:{"musicId":441491828,"musicName":"\xe6\xb0\xb4\xe6\x98\x9f\xe8\xae\xb0","artist":[["\xe9\x83\xad\xe9\xa1\xb6",2843]],"albumId":35005583,"album":"\xe9\xa3\x9e\xe8\xa1\x8c\xe5\x99\xa8\xe7\x9a\x84\xe6\x89\xa7\xe8\xa1\x8c\xe5\x91\xa8\xe6\x9c\x9f","albumPicDocId":2946691248081599,"albumPic":"https://p4.music.126.net/wSMfGvFzOAYRU_yVIfquAA==/2946691248081599.jpg","bitrate":320000,"mp3DocId":"668809cf9ba99c3b7cc51ae17a66027f","duration":325266,"mvId":5404031,"alias":[],"transNames":[],"format":"mp3"}\r\r\r\r\r\r\r\r\r\r\r\r\r'

去掉前面的 music: ,然后转为json字典,可以得到一些歌曲原本的信息,比如歌手,歌名之类的

    crc32 = f.read(4)

    crc32 = struct.unpack('

    f.seek(5, 1)

    image_size = f.read(4)

    image_size = struct.unpack('

    image_data = f.read(image_size)

    file_name = meta_data['musicName'] + '.' + meta_data['format']

    m = open(os.path.join(os.path.split(file_path)[0],file_name),'wb')

    chunk = bytearray()

    while True:

        chunk = bytearray(f.read(0x8000))

        chunk_length = len(chunk)

        if not chunk:

            break

        for i in range(1,chunk_length+1):

            j = i & 0xff;

            chunk[i-1] ^= key_box[(key_box[j] + key_box[(key_box[j] + j) & 0xff]) & 0xff]

        m.write(chunk)

    m.close()

    f.close()

#用修改后的RC4-PRGA算法进行还原并输出新的歌曲文件,得到flac的原本数据

if __name__ == '__main__':

    import sys

    if len(sys.argv) > 1:

        for file_path in sys.argv[1:]:

            try:

                dump(file_path)

            except:

                pass

    else:

        print("Usage: python ncm_transformation.py \"File Name\"")

另:这个是git上一个大神弄的,看得懂的可以看一下,好像比这个要复杂点

https://github.com/nondanee/ncmdump

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/276018.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

锁升级

JavaSE1.6为了减少获得锁和释放锁带来的性能消耗,引入了“偏向锁”和“轻量级锁”。 在JavaSE1.6中,锁一共有4种状态,级别从低到高依次是:无锁状态、偏向锁状态、轻量级锁状态和重量级锁状态,这几个状态会随着竞争情况…

ux和ui_首先要做的— UX / UI案例研究

ux和ui休息一下! (Get some rest!) After four weeks of four-day design sprints each week, I welcomed the opportunity to work on this 9-day design challenge. With this also being an individual project, I allocated 50% of my time on the UX process a…

微信消息模板换行符转义问题处理

通常的微信模板: Hello !\n\n Are you OK? ① 直接定义字符串; ② 数据库中读取;这里需要说明的是 数据库读取 的内容,如果直接推送,\n\n是没有被转移为换行符的。此时需要: $tplStr…

Vue2 彻底从 Flow 重构为 TypeScript,焕然一新!

大家好,我是若川。欢迎加我微信 ruochuan12,长期交流学习。今天分享一篇技术热点,众所周知,前不久vue3不打算支持IE11,vue2将支持composition API,现在vue2用ts重构,试问:还学得动嘛…

红米note5linux刷机包__最新最全的红米Note5ROM刷机包下载、刷机教程_红米Note5论坛_移动叔叔...

本帖最后由 压力山大大叔 于 2018-5-15 00:52 编辑20180513跟新全屏手势。看最后一张载图。1:先解锁,刷第三方,都是这个流程。2非常干净,只有670兆,刷完没有找到浏览器,刷前下载一个浏览器在手机里备用。3电…

每个网页设计者都自以为是

(一)垃圾还是经典网页技术更新很快,一个网站的界面设计寿命仅仅2-3年而已。不管是垃圾还是精品,都没有所谓的经典。经典只存在于是哪个首次成功创新性的应用。网页设计 者不管自己的学识、技术和经验如何,都自以为自己…

文件夹的拷贝

文件夹用来把文件包裹起来,褪去这些外衣,说到底拷贝文件夹也就是拷贝文件 模拟实例:将F:/Picture/test 文件夹 拷贝到 F:/Picture/dir文件夹 该实例中test文件夹下只包含了test.txt文件 步骤分析: 1.通过路径得到File对象 2.递归查…

【抽奖】若川诚邀你加前端群,长期交流学习~

最近有许多读者朋友关注了我,加我好友没有来得及拉群交流。另外偷偷告诉你:公众号回复 411,参与抽奖,送极客时间100元以内的课程,今晚八点开奖,必须开奖前加了我的微信&&像是前端&&关注了我…

帝国cms重置管理员_重新设计《纽约时报》 CMS飞行员

帝国cms重置管理员1.什么是飞行员? (1. What Is Pilot?) For 10 weeks, I joined The New York Times’s Story Formats team as a Product Design Intern. Partnered with technology intern Shormie Faruque, we were tasked with redesigning Pilot.大约十个星期…

微信小程序开发 Request Headers: Provisional headers are shown

在微信小程序开发的时候,写了两个API请求: 请求A://请求Awx.request({url: https://wx.baidu.com/api/wx/getBallByDate,method: POST,dataType: json,data: {date: that.data.curDate},header: {content-type: application/json},success: function(dt…

昆山万象汇机器人_昆山十镇,在售新盘汇总

陆家建伟国际汽车城,均价 7500 元/㎡美吉特家居广场,均价 17000 元/㎡美吉特灯都,均价 17000 元/㎡花桥绿地象屿苏河公园,均价 22950 元/㎡凯德都会新峰,均价 21500 元/㎡越洋国际,均价 18000 元/㎡浦西玫瑰…

Mini 容器学习笔记6——组件的获取(应用)

1. 通过组件Id获取组件实例&#xff1a; [Test]public void GetByIdTest(){ServiceRegistry.Register<Person>("person");var person ServiceLocator.Get<IPerson>("person");Assert.IsTrue(person ! null);var person2 ServiceLocator.Get&…

JavaScript ES2021 最值得期待的 5 个新特性解析

大家好&#xff0c;我是若川。欢迎加我微信 ruochuan12&#xff0c;长期交流学习。今天分享一篇关于ES2021的5个新特性。点击下方卡片关注我&#xff0c;或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列在写本文时&#xff0c;本文提到的新的 JavaScript …

uniapp延迟执行_uniapp微信小程序真机调试点击按钮有1秒延迟

详细问题描述(DCloud产品不会有明显的bug&#xff0c;所以你遇到的问题大都是在特定环境下才能重现的问题&#xff0c;请仔细描述你的环境和重现方式&#xff0c;否则DCloud很难排查解决你的问题)[内容]开发uniapp小程序项目时,在页面中点击按钮后, 数据即时更新, 视图层延迟1秒…

latex排版基础_排版基础分类

latex排版基础重点 (Top highlight)There are many parts to creating a beautiful, functional, memorizing design. That’s what all User Experience designers set out to do. You need to consider your users, strategy, features, content, color, and so much more. A…

AS3 CookBook学习整理(一)

1. 我要改变swf的尺寸和颜色 在flex builder 3里&#xff0c;默认会生成一个全屏、背景色为#869CA7、帧数为24/秒的swf文件&#xff0c;要修改这些参数&#xff0c;只需要在类文件中定义 [SWF(width"800", height"600", backgroundColor"#ffffff"…

微信小程序研发问题梳理:翻页:下拉:缓存:canvas:富文本:分享

微信小程序研发问题梳理 最近鼓捣小程序的时候&#xff0c;着实遇到了一些问题&#xff0c;尽管有些再翻看文档几遍&#xff0c;就能找到答案&#xff0c;但还是要发挥下烂笔头的功效&#xff0c;顺便梳理下。 问题列表 登录流程小程序标签页地址无法跳转问题页面翻页内容加…

Nginx重启方式

2019独角兽企业重金招聘Python工程师标准>>> 重启方式有三种&#xff1a; 1.简单型&#xff0c;先关闭进程&#xff0c;修改你的配置后&#xff0c;重启进程。 2.重新加载配置文件&#xff0c;不重启进程&#xff0c;不会停止处理请求 3.平滑更新nginx二进制&#x…

axure如何页面滑动时广告位上移_新手APP运营如何做广告位投放

运营是什么&#xff1f;这种问题在各种论坛、贴吧、百度知道、问答百科类中都会出现。上面也有各种大神各式各样的回答&#xff0c;从不同角度向我们阐述了什么是运营。用 户运营、内容运营、社区运营、活动运营、市场运营、等等&#xff0c;各种各样的文章对它们有非常多的分类…

常见的8个前端防御性编程方案

大家好&#xff0c;我是若川。欢迎加我微信 ruochuan12&#xff0c;长期交流学习。今天分享几个常见的前端防御性编程方案。点击下方卡片关注我&#xff0c;或者查看源码等系列文章。学习源码整体架构系列、年度总结、JS基础系列关于前端防御性编程我们大多数情况可能遇到过&am…