Compare commits

...

14 Commits

Author SHA1 Message Date
nullptr-0 e3188ef8eb bugfix for #36 #50 2023-08-28 22:57:23 +08:00
jixunmoe 970d2485a6 Merge pull request 'docs/issue-template-2' (#55) from docs/issue-template-2 into master
Reviewed-on: um/web#55
2023-07-15 20:02:59 +00:00
Jixun Wu 84847573e1 chore: add more template 2023-07-15 20:59:49 +01:00
Jixun Wu 153319b2e5 chore: issue template update 2023-07-15 20:24:18 +01:00
jixunmoe afd9263ff1 Merge pull request '将旧的 GitHub 项目链接更换到新的域名' (#54) from fix/docs into master
Reviewed-on: um/web#54
2023-07-15 19:12:02 +00:00
Jixun Wu fc18d7de05 docs: update issue templates 2023-07-15 20:10:59 +01:00
Jixun Wu a269cd4f8e chore: replace url to old github project (fix #53) 2023-07-15 20:10:52 +01:00
jixunmoe 9205dbf701 Merge pull request '修正云音乐 PC 3.0 写出的 metadata 格式与之前不一致导致解码错误的问题' (#51) from fix/ncm-3-metadata into master
Reviewed-on: um/web#51
2023-07-07 16:50:30 +00:00
Jixun Wu 0bb5c4d864 strict type check for ncm metadata #48 2023-07-07 12:45:31 +01:00
jixunmoe fde495ce42 Merge pull request '将 package-lock 中的 npmmirror 地址更换为 npmjs 的官方地址' (#47) from dev/normalize-package-lock-url into master
Reviewed-on: um/web#47
2023-06-06 21:02:04 +00:00
Jixun Wu cd30e91d22 chore: use npmjs url instead of npmmirror 2023-06-06 22:00:15 +01:00
jixunmoe 9a5632fe22 Merge pull request 'optimization' (#29) from nullptr-0/web:master into master
Reviewed-on: um/web#29
Reviewed-by: jixunmoe <jixunmoe@noreply.unlock-music.dev>
2023-06-06 20:41:54 +00:00
xhacker-zzz 51107f004e Merge branch 'master' into master
continuous-integration/drone/push Build is passing Details
2023-01-20 12:37:05 +00:00
Unlock Music Dev 4fec47201e Merge pull request 'Fix STag Filtering & README improvement & Update Supported Extensions' (#28) from xhacker-zzz/web:master into master
Reviewed-on: um/web#28
Reviewed-by: jixunmoe <jixunmoe@noreply.unlock-music.dev>
Reviewed-by: Unlock Music Dev <dev@unlock-music.dev>
2023-01-19 16:57:53 +00:00
14 changed files with 246 additions and 93 deletions

View File

@ -0,0 +1,76 @@
name: 解码错误报告 (填表)
about: 遇到文件解码失败的问题请选择该项。
title: '[Bug/Crypto] '
labels:
- bug
- crypto
body:
- type: textarea
id: what-happened
attributes:
label: 错误描述
description: 请描述你所遇到的问题,以及你期待的行为。
placeholder: ''
value: ''
validations:
required: true
- type: dropdown
id: version
attributes:
label: Unlock Music 版本
description: |
能够重现错误的版本,版本号通常在页面底部。
如果不确定,请升级到最新版确认问题是否解决。
multiple: true
options:
- 1.10.5 (仓库最新)
- 1.10.3 (官方 DEMO)
- 其它(请在错误描述中指定)
validations:
required: true
- type: dropdown
id: browsers
attributes:
label: 产生错误的浏览器
multiple: true
options:
- 火狐 / Firefox
- Chrome
- Safari
- 其它基于 Chromium 的浏览器 (Edge、Brave、Opera 等)
- type: dropdown
id: music-platform
attributes:
label: 音乐平台
description: |
如果需要报告多个平台的问题,请每个平台提交一个新的 Issue。
请注意:播放器缓存文件不属于该项目支持的文件类型。
multiple: false
options:
- 其它 (请在错误描述指定)
- QQ 音乐
- Joox (QQ 音乐海外版)
- 虾米音乐
- 网易云音乐
- 酷我音乐
- 酷狗音乐
- 喜马拉雅
- 咪咕 3D
validations:
required: true
- type: textarea
id: logs
attributes:
label: 日志信息
description: 如果有请提供浏览器开发者控制台Console的错误日志
render: text
- type: checkboxes
id: terms
attributes:
label: 我已经阅读并确认下述内容
description: ''
options:
- label: 我已经检索过 Issue 列表,并确认这是一个为报告过的问题。
required: true
- label: 我有证据表明这是程序导致的问题(如不确认,可以通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论)
required: true

View File

@ -1,39 +1,40 @@
---
name: Bug报告
about: 报告Bug以帮助改进程序
title: ''
labels: bug
assignees: ''
name: "错误报告"
about: "报告 Bug 以帮助改进程序,非填表。"
title: "[BUG] "
labels:
- bug
---
* 请按照此模板填写,否则可能立即被关闭
- [x] 我确认已经搜索过Issue不存并确认相同的Issue
- [x] 我有证据表明这是程序导致的问题(如不确认,可以在[Discussions](https://github.com/ix64/unlock-music/discussions)内提出
- [x] 我有证据表明这是程序导致的问题(如不确认,可以通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论
**Bug描述**
## Bug描述
简要地复述你遇到的Bug
**复现方法**
## 复现方法
描述复现方法,必要时请提供样本文件
**程序截图或者Console报错信息**
## 程序截图或浏览器开发者控制台Console的报错信息
如果可以请提供二者之一
**环境信息:**
## 环境信息
- 操作系统和浏览器:
- 程序版本:
- 获取音乐文件所使用的客户端及其版本信息
- 网页版的地址(如果为非官方部署请注明)
注意:如果需要会员才能获取该资源,你可能也需要作为附件提交。
**附加信息**
## 附加信息
其他能够帮助确认问题的信息
如果有,请提供其他能够帮助确认问题的信息到下方:

View File

@ -1,26 +1,29 @@
---
name: 新功能
about: 对于程序新的想法或建议
title: ''
labels: enhancement
assignees: ''
name: "新功能"
about: "对于程序新的想法或建议"
title: "[新功能] "
labels:
- enhancement
---
- 请按照此模板填写,否则可能立即被关闭
<!-- ⚠ 请按照此模板填写,否则可能立即被关闭 -->
<!-- 提交前请使用【Preview】预览提交的更改 -->
**背景和说明**
## 背景和说明
简要说明产生此想法的背景和此想法的具体内容
<!-- 简要说明产生此想法的背景和此想法的具体内容 -->
**实现途径**
## 实现途径
- 如果没有设计方案,请简要描述实现思路
- 如果你没有任何的实现思路,请通过[Discussions](https://github.com/ix64/unlock-music/discussions)或者Telegram进行讨论
- 如果你没有任何的实现思路,请通过 Telegram 讨论组 (https://t.me/unlock_music_chat) 进行讨论
**附加信息**
## 附加信息
更多你想要表达的内容
<!-- 更多你想要表达的内容 -->

View File

@ -6,11 +6,13 @@
"128": "./img/icons/msapplication-icon-144x144.png"
},
"description": "在任何设备上解锁已购的加密音乐!",
"permissions": ["storage"],
"permissions": [
"storage"
],
"offline_enabled": true,
"options_page": "./index.html",
"homepage_url": "https://github.com/ix64/unlock-music",
"homepage_url": "https://git.unlock-music.dev/um/web",
"browser_action": {
"default_popup": "./popup.html"
}
}
}

8
package-lock.json generated
View File

@ -1,12 +1,12 @@
{
"name": "unlock-music",
"version": "1.10.4",
"version": "1.10.5",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "unlock-music",
"version": "1.10.4",
"version": "1.10.5",
"hasInstallScript": true,
"license": "MIT",
"dependencies": {
@ -5712,7 +5712,7 @@
},
"node_modules/caniuse-lite": {
"version": "1.0.30001434",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA=="
},
"node_modules/case-sensitive-paths-webpack-plugin": {
@ -25477,7 +25477,7 @@
},
"caniuse-lite": {
"version": "1.0.30001434",
"resolved": "https://registry.npmmirror.com/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001434.tgz",
"integrity": "sha512-aOBHrLmTQw//WFa2rcF1If9fa3ypkC1wzqqiKHgfdrXTWcU8C4gKVZT77eQAPWN1APys3+uQ0Df07rKauXGEYA=="
},
"case-sensitive-paths-webpack-plugin": {

View File

@ -1,13 +1,13 @@
{
"name": "unlock-music",
"version": "1.10.4",
"version": "1.10.5",
"ext_build": 0,
"updateInfo": "完善音乐标签编辑功能,支持编辑更多标签",
"license": "MIT",
"description": "Unlock encrypted music file in browser.",
"repository": {
"type": "git",
"url": "https://github.com/ix64/unlock-music"
"url": "https://git.unlock-music.dev/um/web"
},
"private": true,
"scripts": {
@ -57,4 +57,4 @@
"vue-cli-plugin-element": "^1.0.1",
"vue-template-compiler": "^2.6.14"
}
}
}

View File

@ -1,39 +1,89 @@
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="utf-8">
<meta content="webkit" name="renderer">
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible">
<meta content="width=device-width,initial-scale=1.0" name="viewport">
<head>
<meta charset="utf-8" />
<meta content="webkit" name="renderer" />
<meta content="IE=edge,chrome=1" http-equiv="X-UA-Compatible" />
<meta content="width=device-width,initial-scale=1.0" name="viewport" />
<title>音乐解锁</title>
<meta content="音乐,解锁,ncm,qmc,mgg,mflac,qq音乐,网易云音乐,加密" name="keywords"/>
<meta content="音乐解锁 - 在任何设备上解锁已购的加密音乐!" name="description"/>
<!--@formatter:off-->
<style>#loader{position:absolute;left:50%;top:50%;z-index:1010;margin:-75px 0 0 -75px;border:16px solid #f3f3f3;border-radius:50%;border-top:16px solid #1db1ff;width:120px;height:120px;animation:spin 2s linear infinite}@keyframes spin{0%{transform:rotate(0)}100%{transform:rotate(360deg)}}#loader-mask{text-align:center;position:absolute;width:100%;height:100%;bottom:0;left:0;right:0;top:0;z-index:1009;background-color:rgba(242,246,252,.88)}@media (prefers-color-scheme:dark){#loader-mask{color:#fff;background-color:rgba(0,0,0,.85)}#loader-mask a{color:#ddd}#loader-mask a:hover{color:#1db1ff}}#loader-source{font-size:1.5rem}#loader-tips-timeout{font-size:1.2rem}</style>
<!--@formatter:on-->
</head>
<body>
<meta content="音乐,解锁,ncm,qmc,mgg,mflac,qq音乐,网易云音乐,加密" name="keywords" />
<meta content="音乐解锁 - 在任何设备上解锁已购的加密音乐!" name="description" />
<style>
#loader {
position: absolute;
left: 50%;
top: 50%;
z-index: 1010;
margin: -75px 0 0 -75px;
border: 16px solid #f3f3f3;
border-radius: 50%;
border-top: 16px solid #1db1ff;
width: 120px;
height: 120px;
animation: spin 2s linear infinite;
}
@keyframes spin {
0% {
transform: rotate(0);
}
100% {
transform: rotate(360deg);
}
}
#loader-mask {
text-align: center;
position: absolute;
width: 100%;
height: 100%;
bottom: 0;
left: 0;
right: 0;
top: 0;
z-index: 1009;
background-color: rgba(242, 246, 252, 0.88);
}
@media (prefers-color-scheme: dark) {
#loader-mask {
color: #fff;
background-color: rgba(0, 0, 0, 0.85);
}
#loader-mask a {
color: #ddd;
}
#loader-mask a:hover {
color: #1db1ff;
}
}
#loader-source {
font-size: 1.5rem;
}
#loader-tips-timeout {
font-size: 1.2rem;
}
</style>
</head>
<div id="loader-mask">
<div id="loader"></div>
<noscript>
<body>
<div id="loader-mask">
<div id="loader"></div>
<noscript>
<h3 id="loader-js">请启用JavaScript</h3>
</noscript>
<h3 id="loader-source"> 请勿直接运行源代码! </h3>
<div id="loader-tips-outdated" hidden>
<h2>您可能在使用不受支持的<span style="color:#f00;">过时</span>浏览器,这可能导致此应用无法正常工作。</h2>
<h3>如果您使用双核浏览器,您可以尝试切换到 <span style="color:#f00;">“极速模式”</span> 解决此问题。</h3>
</noscript>
<h3 id="loader-source">请勿直接运行源代码!</h3>
<div id="loader-tips-outdated" hidden>
<h2>您可能在使用不受支持的<span style="color: #f00">过时</span>浏览器,这可能导致此应用无法正常工作。</h2>
<h3>如果您使用双核浏览器,您可以尝试切换到 <span style="color: #f00">“极速模式”</span> 解决此问题。</h3>
<h3>或者,您可以尝试更换下方的几个浏览器之一。</h3>
</div>
<h3 id="loader-tips-timeout" hidden>
</div>
<h3 id="loader-tips-timeout" hidden>
音乐解锁采用了一些新特性!建议使用
<a href="https://www.microsoft.com/zh-cn/edge" target="_blank">Microsoft Edge Chromium</a>
<a href="https://www.google.cn/chrome/" target="_blank">Google Chrome</a>
<a href="https://www.firefox.com.cn/" target="_blank">Mozilla Firefox</a>
| <a href="https://github.com/ix64/unlock-music/wiki/使用提示" target="_blank">使用提示</a>
</h3>
</div>
<div id="app"></div>
<script src="./loader.js"></script>
</body>
| <a href="https://git.unlock-music.dev/um/web/wiki/使用提示" target="_blank">使用提示</a>
</h3>
</div>
<div id="app"></div>
<script src="./loader.js"></script>
</body>
</html>

View File

@ -5,19 +5,19 @@
</el-main>
<el-footer id="app-footer">
<el-row>
<a href="https://github.com/ix64/unlock-music" target="_blank">音乐解锁</a>({{ version }})
<a href="https://git.unlock-music.dev/um/web" target="_blank">音乐解锁</a>({{ version }})
移除已购音乐的加密保护
<a href="https://github.com/ix64/unlock-music/wiki/使用提示" target="_blank">使用提示</a>
<a href="https://git.unlock-music.dev/um/web/wiki/使用提示" target="_blank">使用提示</a>
</el-row>
<el-row>
目前支持 网易云音乐(ncm), QQ音乐(qmc, mflac, mgg), 酷狗音乐(kgm), 虾米音乐(xm), 酷我音乐(.kwm)
<a href="https://github.com/ix64/unlock-music/blob/master/README.md" target="_blank">更多</a>
<a href="https://git.unlock-music.dev/um/web/src/branch/master/README.md" target="_blank">更多</a>
</el-row>
<el-row>
<!--如果进行二次开发此行版权信息不得移除且应明显地标注于页面上-->
<span>Copyright &copy; 2019 - {{ new Date().getFullYear() }} MengYX</span>
音乐解锁使用
<a href="https://github.com/ix64/unlock-music/blob/master/LICENSE" target="_blank">MIT许可协议</a>
<a href="https://git.unlock-music.dev/um/web/src/branch/master/LICENSE" target="_blank">MIT许可协议</a>
开放源代码
</el-row>
</el-footer>
@ -77,7 +77,7 @@ export default {
<div class="update-title">最近更新</div>
<div class="update-content"> ${config.updateInfo} </div>
</div>
<a target="_blank" href="https://github.com/ix64/unlock-music/wiki/使用提示">使用提示</a>
<a target="_blank" href="https://git.unlock-music.dev/um/web/wiki/使用提示">使用提示</a>
</div>`,
dangerouslyUseHTMLString: true,
duration: 10000,

View File

@ -43,7 +43,9 @@ form >>> input {
下载该加密文件的 JOOX 应用所记录的设备唯一识别码
<br />
参见
<a href="https://github.com/unlock-music/joox-crypto/wiki/%E8%8E%B7%E5%8F%96%E8%AE%BE%E5%A4%87-UUID">
<a
href="https://git.unlock-music.dev/um/joox-crypto/wiki/%E8%8E%B7%E5%8F%96%E8%AE%BE%E5%A4%87-UUID#%E5%89%8D%E8%A8%80"
>
获取设备 UUID · unlock-music/joox-crypto Wiki</a
>
</p>

View File

@ -22,7 +22,7 @@ describe('decrypt/joox', () => {
album: 'unused',
blob: blob,
artist: 'unused',
imgUrl: 'https://github.com/unlock-music',
imgUrl: 'https://example.unlock-music.dev/',
};
});

View File

@ -2,9 +2,6 @@ import { KgmCrypto } from '@xhacker/kgmwasm/KgmWasmBundle';
import KgmCryptoModule from '@xhacker/kgmwasm/KgmWasmBundle';
import { MergeUint8Array } from '@/utils/MergeUint8Array';
// 每次处理 2M 的数据
const DECRYPTION_BUF_SIZE = 2 *1024 * 1024;
export interface KGMDecryptionResult {
success: boolean;
data: Uint8Array;
@ -34,6 +31,9 @@ export async function DecryptKgmWasm(kgmBlob: ArrayBuffer, ext: string): Promise
return result;
}
// 每次处理 2M 的数据
const DECRYPTION_BUF_SIZE = Math.min(2 *1024 * 1024, kgmBlob.byteLength);
// 申请内存块,并文件末端数据到 WASM 的内存堆
let kgmBuf = new Uint8Array(kgmBlob);
const pQmcBuf = KgmCryptoObj._malloc(DECRYPTION_BUF_SIZE);
@ -41,7 +41,6 @@ export async function DecryptKgmWasm(kgmBlob: ArrayBuffer, ext: string): Promise
// 进行解密初始化
const headerSize = KgmCryptoObj.preDec(pQmcBuf, DECRYPTION_BUF_SIZE, ext);
console.log(headerSize);
kgmBuf = kgmBuf.slice(headerSize);
const decryptedParts = [];

View File

@ -139,7 +139,7 @@ class NcmDecrypt {
} else {
result = JSON.parse(plainText.slice(labelIndex + 1));
}
if (!!result.albumPic) {
if (result.albumPic) {
result.albumPic = result.albumPic.replace('http://', 'https://') + '?param=500y500';
}
return result;
@ -160,11 +160,20 @@ class NcmDecrypt {
// build artists
let artists: string[] = [];
if (!!this.oriMeta.artist) {
this.oriMeta.artist.forEach((arr) => artists.push(<string>arr[0]));
if (typeof this.oriMeta.artist === 'string') {
// v3.0: artist 现在可能是字符串了?
artists.push(this.oriMeta.artist);
} else if (Array.isArray(this.oriMeta.artist)) {
this.oriMeta.artist.forEach((artist) => {
if (typeof artist === 'string') {
artists.push(artist);
} else if (Array.isArray(artist) && artist[0] && typeof artist[0] === 'string') {
artists.push(artist[0]);
}
});
}
if (artists.length === 0 && !!info.artist) {
if (artists.length === 0 && info.artist) {
artists = info.artist
.split(',')
.map((val) => val.trim())
@ -180,7 +189,7 @@ class NcmDecrypt {
this.image.buffer = await img.getBufferAsync('image/jpeg');
}
} catch (e) {
console.log('get cover image failed', e);
console.log('fetch cover image failed', e);
}
this.newMeta = { title: info.title, artists, album: this.oriMeta.album, picture: this.image?.buffer };
@ -226,12 +235,14 @@ class NcmDecrypt {
this.audio = this._getAudio(keyBox);
this.format = this.oriMeta.format || SniffAudioExt(this.audio);
this.mime = AudioMimeType[this.format];
await this._buildMeta();
try {
await this._buildMeta();
await this._writeMeta();
} catch (e) {
console.warn('write meta data failed', e);
console.warn('build/write meta failed, skip.', e);
}
return this.gatherResult();
}
}

View File

@ -2,9 +2,6 @@ import { QmcCrypto } from '@xhacker/qmcwasm/QmcWasmBundle';
import QmcCryptoModule from '@xhacker/qmcwasm/QmcWasmBundle';
import { MergeUint8Array } from '@/utils/MergeUint8Array';
// 每次处理 2M 的数据
const DECRYPTION_BUF_SIZE = 2 *1024 * 1024;
export interface QMCDecryptionResult {
success: boolean;
data: Uint8Array;
@ -35,6 +32,9 @@ export async function DecryptQmcWasm(qmcBlob: ArrayBuffer, ext: string): Promise
return result;
}
// 每次处理 2M 的数据
const DECRYPTION_BUF_SIZE = Math.min(2 *1024 * 1024, qmcBlob.byteLength);
// 申请内存块,并文件末端数据到 WASM 的内存堆
const qmcBuf = new Uint8Array(qmcBlob);
const pQmcBuf = QmcCryptoObj._malloc(DECRYPTION_BUF_SIZE);

View File

@ -18,7 +18,9 @@
:album="editing_data.album"
:albumartist="editing_data.albumartist"
:genre="editing_data.genre"
@cancel="showEditDialog = false" @ok="handleEdit"></edit-dialog>
@cancel="showEditDialog = false"
@ok="handleEdit"
></edit-dialog>
<config-dialog :show="showConfigDialog" @done="showConfigDialog = false"></config-dialog>
<el-tooltip class="item" effect="dark" placement="top">
<div slot="content">
@ -37,14 +39,20 @@
开启后解锁结果将不会存留于浏览器中防止内存不足
</span>
</div>
<el-checkbox v-model="instant_save" type="success" border class="ml-2">立即保存</el-checkbox>
<el-checkbox v-model="instant_save" type="success" border class="ml-2">立即保存</el-checkbox>
</el-tooltip>
</el-row>
</div>
<audio :autoplay="playing_auto" :src="playing_url" controls />
<PreviewTable :policy="filename_policy" :table-data="tableData" @download="saveFile" @edit="editFile" @play="changePlaying" />
<PreviewTable
:policy="filename_policy"
:table-data="tableData"
@download="saveFile"
@edit="editFile"
@play="changePlaying"
/>
</div>
</template>
@ -70,7 +78,7 @@ export default {
return {
showConfigDialog: false,
showEditDialog: false,
editing_data: { picture: '', title: '', artist: '', album: '', albumartist: '', genre: '', },
editing_data: { picture: '', title: '', artist: '', album: '', albumartist: '', genre: '' },
tableData: [],
playing_url: '',
playing_auto: false,
@ -111,7 +119,7 @@ export default {
errInfo +
'' +
filename +
',参考<a target="_blank" href="https://github.com/ix64/unlock-music/wiki/使用提示">使用提示</a>',
',参考<a target="_blank" href="https://git.unlock-music.dev/um/web/wiki/使用提示">使用提示</a>',
dangerouslyUseHTMLString: true,
duration: 6000,
});
@ -164,12 +172,13 @@ export default {
console.warn('获取图像失败', this.editing_data.picture);
}
}
const newMeta = { picture: imageInfo?.buffer,
const newMeta = {
picture: imageInfo?.buffer,
title: data.title,
artists: data.artist.split(split_regex),
album: data.album,
albumartist: data.albumartist,
genre: data.genre.split(split_regex)
genre: data.genre.split(split_regex),
};
const buffer = Buffer.from(await this.editing_data.blob.arrayBuffer());
const mime = AudioMimeType[this.editing_data.ext] || AudioMimeType.mp3;