Compare commits
4 Commits
Author | SHA1 | Date | |
---|---|---|---|
![]() |
fd2866f53d | ||
![]() |
5e8af22f08 | ||
![]() |
4aa2ff7f91 | ||
![]() |
c9a4a901be |
4
.github/workflows/release.yml
vendored
4
.github/workflows/release.yml
vendored
@@ -26,12 +26,12 @@ jobs:
|
||||
run: |
|
||||
npm run build
|
||||
tar -czf legacy.tar.gz -C ./dist .
|
||||
zip -J9 legacy.zip ./dist
|
||||
zip -rJ9 legacy.zip ./dist
|
||||
- name: Build Modern
|
||||
run: |
|
||||
npm run build -- --modern
|
||||
tar -czf modern.tar.gz -C ./dist .
|
||||
zip -J9 modern.zip ./dist
|
||||
zip -rJ9 modern.zip ./dist
|
||||
- run: sha256sum *.tar.gz *.zip > sha256sum.txt
|
||||
|
||||
- name: Deploy
|
||||
|
11
README.md
11
README.md
@@ -1,22 +1,23 @@
|
||||
# Unlock Music 音乐解锁
|
||||
- Unlock encrypted music file in browser.
|
||||
- 在浏览器中解锁加密的音乐文件。
|
||||
- 在浏览器中解锁加密的音乐文件。 Unlock encrypted music file in browser.
|
||||
- unlock-music项目是以学习和技术研究的初衷创建的,修改、再分发时请遵循[License](https://github.com/ix64/unlock-music/blob/master/LICENSE)
|
||||
- 由于存在可能的法律风险以及滥用风险,不再提供Demo服务;Unlock Music的CLI版本正在开发中。
|
||||
- Unlock Music的CLI版本正在开发中。
|
||||
- 我们新建了Telegram群组,欢迎加入
|
||||
- [其他测试版工具](https://github.com/ix64/unlock-music/wiki/%E5%85%B6%E4%BB%96%E9%9F%B3%E4%B9%90%E6%A0%BC%E5%BC%8F%E5%B7%A5%E5%85%B7)
|
||||
|
||||
[](https://ci.ixarea.com/ix64/unlock-music)
|
||||
- 
|
||||
|
||||
# 特性
|
||||
## 支持的格式
|
||||
- [x] QQ音乐 (.qmc0/.qmc2/.qmc3/.qmcflac/.qmcogg/[.tkm](https://github.com/ix64/unlock-music/issues/9))
|
||||
- [x] 写入封面图片
|
||||
- [x] Moo音乐格式 ([.bkcmp3/.bkcflac](https://github.com/ix64/unlock-music/issues/11))
|
||||
- [x] QQ音乐Tm格式 (.tm0/.tm2/.tm3/.tm6)
|
||||
- [x] QQ音乐新格式 (实验性支持)
|
||||
- [x] .mflac
|
||||
- [x] [.mgg](https://github.com/ix64/unlock-music/issues/3)
|
||||
- [x] 网易云音乐格式 (.ncm)
|
||||
- [x] 补全ncm的ID3信息
|
||||
- [x] 补全ncm的ID3/FlacMeta信息
|
||||
- [x] 虾米音乐格式 (.xm) (测试阶段)
|
||||
- [x] 酷我音乐格式 (.kwm) (测试阶段)
|
||||
- [x] 酷狗音乐格式 (.kgm) ([CLI版本](https://github.com/ix64/unlock-music/wiki/%E5%85%B6%E4%BB%96%E9%9F%B3%E4%B9%90%E6%A0%BC%E5%BC%8F%E5%B7%A5%E5%85%B7#%E9%85%B7%E7%8B%97%E9%9F%B3%E4%B9%90-kgmvpr%E8%A7%A3%E9%94%81%E5%B7%A5%E5%85%B7))
|
||||
|
2
package-lock.json
generated
2
package-lock.json
generated
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "unlock-music",
|
||||
"version": "1.6.0",
|
||||
"version": "1.6.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "unlock-music",
|
||||
"version": "1.6.0",
|
||||
"updateInfo": "增加对flac文件的meta写入;支持QQ音乐封面写入(实验性)",
|
||||
"version": "1.6.1",
|
||||
"updateInfo": "修复flac文件的meta写入",
|
||||
"license": "MIT",
|
||||
"description": "Unlock encrypted music file in browser.",
|
||||
"repository": {
|
||||
|
@@ -58,6 +58,6 @@ export async function CommonDecrypt(file) {
|
||||
|
||||
if (!rt_data.rawExt) rt_data.rawExt = raw_ext;
|
||||
if (!rt_data.rawFilename) rt_data.rawFilename = raw_filename;
|
||||
|
||||
console.log(rt_data);
|
||||
return rt_data;
|
||||
}
|
||||
|
@@ -39,25 +39,30 @@ export async function Decrypt(file, raw_filename, raw_ext) {
|
||||
if (artists.length === 0) artists.push(info.artist);
|
||||
|
||||
if (musicMeta.format === undefined) musicMeta.format = DetectAudioExt(audioData, "mp3");
|
||||
console.log(musicMeta)
|
||||
|
||||
const imageInfo = await GetWebImage(musicMeta.albumPic);
|
||||
if (musicMeta.format === "mp3") {
|
||||
audioData = await WriteMp3Meta(
|
||||
audioData, artists, info.title, musicMeta.album, imageInfo.buffer, musicMeta.albumPic);
|
||||
} else if (musicMeta.format === "flac") {
|
||||
const writer = new MetaFlac(Buffer.from(audioData))
|
||||
writer.setTag("TITLE=" + info.title);
|
||||
writer.setTag("ALBUM=" + musicMeta.album);
|
||||
artists.forEach(artist => writer.setTag("ARTIST=" + artist));
|
||||
writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer))
|
||||
audioData = writer.save()
|
||||
}
|
||||
console.log(imageInfo)
|
||||
try {
|
||||
if (musicMeta.format === "mp3") {
|
||||
audioData = await WriteMp3Meta(
|
||||
audioData, artists, info.title, musicMeta.album, imageInfo.buffer, musicMeta.albumPic);
|
||||
} else if (musicMeta.format === "flac") {
|
||||
const writer = new MetaFlac(Buffer.from(audioData))
|
||||
//writer.setTag("TITLE=" + info.title);
|
||||
//writer.setTag("ALBUM=" + musicMeta.album);
|
||||
//artists.forEach(artist => writer.setTag("ARTIST=" + artist));
|
||||
writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer))
|
||||
audioData = writer.save()
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Error while appending cover image to file " + e)
|
||||
}
|
||||
|
||||
const mime = AudioMimeType[musicMeta.format];
|
||||
const musicData = new Blob([audioData], {type: mime});
|
||||
|
||||
let x = {
|
||||
return {
|
||||
status: true,
|
||||
title: info.title,
|
||||
artist: info.artist,
|
||||
@@ -67,8 +72,6 @@ export async function Decrypt(file, raw_filename, raw_ext) {
|
||||
file: URL.createObjectURL(musicData),
|
||||
mime: mime
|
||||
};
|
||||
console.log(x)
|
||||
return x;
|
||||
}
|
||||
|
||||
|
||||
|
@@ -60,6 +60,7 @@ export async function Decrypt(file, raw_filename, raw_ext) {
|
||||
const musicMeta = await musicMetadata.parseBlob(musicBlob);
|
||||
for (let metaIdx in musicMeta.native) {
|
||||
if (musicMeta.native[metaIdx].some(item => item.id === "TCON" && item.value === "(12)")) {
|
||||
console.log("The metadata is using gbk encoding")
|
||||
musicMeta.common.artist = decode(musicMeta.common.artist, "gbk");
|
||||
musicMeta.common.title = decode(musicMeta.common.title, "gbk");
|
||||
musicMeta.common.album = decode(musicMeta.common.album, "gbk");
|
||||
@@ -77,21 +78,25 @@ export async function Decrypt(file, raw_filename, raw_ext) {
|
||||
const imageInfo = await GetWebImage(imgUrl);
|
||||
if (imageInfo.url !== "") {
|
||||
imgUrl = imageInfo.url
|
||||
if (ext === "mp3") {
|
||||
let writer = new ID3Writer(musicDecoded)
|
||||
writer.setFrame('APIC', {
|
||||
type: 3,
|
||||
data: imageInfo.buffer,
|
||||
description: "Cover",
|
||||
})
|
||||
writer.addTag();
|
||||
musicDecoded = writer.arrayBuffer
|
||||
musicBlob = new Blob([musicDecoded], {type: mime});
|
||||
} else if (ext === 'flac') {
|
||||
const writer = new MetaFlac(Buffer.from(musicDecoded))
|
||||
writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer))
|
||||
musicDecoded = writer.save()
|
||||
musicBlob = new Blob([musicDecoded], {type: mime});
|
||||
try {
|
||||
if (ext === "mp3") {
|
||||
let writer = new ID3Writer(musicDecoded)
|
||||
writer.setFrame('APIC', {
|
||||
type: 3,
|
||||
data: imageInfo.buffer,
|
||||
description: "Cover",
|
||||
})
|
||||
writer.addTag();
|
||||
musicDecoded = writer.arrayBuffer
|
||||
musicBlob = new Blob([musicDecoded], {type: mime});
|
||||
} else if (ext === 'flac') {
|
||||
const writer = new MetaFlac(Buffer.from(musicDecoded))
|
||||
writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer))
|
||||
musicDecoded = writer.save()
|
||||
musicBlob = new Blob([musicDecoded], {type: mime});
|
||||
}
|
||||
} catch (e) {
|
||||
console.warn("Error while appending cover image to file " + e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user