4 Commits

Author SHA1 Message Date
MengYX
fd2866f53d Bump Version 2020-08-02 18:25:56 +08:00
MengYX
5e8af22f08 Fix wrong zip file in release [Skip CI] 2020-08-01 01:20:56 +08:00
MengYX
4aa2ff7f91 Fix #77 ncm flac meta duplicated
Fix #78 write flac cover sometimes fail
2020-08-01 01:10:27 +08:00
MengYX
c9a4a901be Update README.md 2020-07-19 00:03:41 +08:00
7 changed files with 49 additions and 40 deletions

View File

@@ -26,12 +26,12 @@ jobs:
run: | run: |
npm run build npm run build
tar -czf legacy.tar.gz -C ./dist . tar -czf legacy.tar.gz -C ./dist .
zip -J9 legacy.zip ./dist zip -rJ9 legacy.zip ./dist
- name: Build Modern - name: Build Modern
run: | run: |
npm run build -- --modern npm run build -- --modern
tar -czf modern.tar.gz -C ./dist . tar -czf modern.tar.gz -C ./dist .
zip -J9 modern.zip ./dist zip -rJ9 modern.zip ./dist
- run: sha256sum *.tar.gz *.zip > sha256sum.txt - run: sha256sum *.tar.gz *.zip > sha256sum.txt
- name: Deploy - name: Deploy

View File

@@ -1,22 +1,23 @@
# Unlock Music 音乐解锁 # 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) - unlock-music项目是以学习和技术研究的初衷创建的修改、再分发时请遵循[License](https://github.com/ix64/unlock-music/blob/master/LICENSE)
- 由于存在可能的法律风险以及滥用风险不再提供Demo服务Unlock Music的CLI版本正在开发中。 - Unlock Music的CLI版本正在开发中。
- 我们新建了Telegram群组欢迎加入[https://t.me/unlock_music_chat](https://t.me/unlock_music_chat)
- [其他测试版工具](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://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)
[![Build Status](https://ci.ixarea.com/api/badges/ix64/unlock-music/status.svg)](https://ci.ixarea.com/ix64/unlock-music) - ![Release and GitHub Pages](https://github.com/ix64/unlock-music/workflows/Release%20and%20GitHub%20Pages/badge.svg)
# 特性 # 特性
## 支持的格式 ## 支持的格式
- [x] QQ音乐 (.qmc0/.qmc2/.qmc3/.qmcflac/.qmcogg/[.tkm](https://github.com/ix64/unlock-music/issues/9)) - [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] Moo音乐格式 ([.bkcmp3/.bkcflac](https://github.com/ix64/unlock-music/issues/11))
- [x] QQ音乐Tm格式 (.tm0/.tm2/.tm3/.tm6) - [x] QQ音乐Tm格式 (.tm0/.tm2/.tm3/.tm6)
- [x] QQ音乐新格式 (实验性支持) - [x] QQ音乐新格式 (实验性支持)
- [x] .mflac - [x] .mflac
- [x] [.mgg](https://github.com/ix64/unlock-music/issues/3) - [x] [.mgg](https://github.com/ix64/unlock-music/issues/3)
- [x] 网易云音乐格式 (.ncm) - [x] 网易云音乐格式 (.ncm)
- [x] 补全ncm的ID3信息 - [x] 补全ncm的ID3/FlacMeta信息
- [x] 虾米音乐格式 (.xm) (测试阶段) - [x] 虾米音乐格式 (.xm) (测试阶段)
- [x] 酷我音乐格式 (.kwm) (测试阶段) - [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)) - [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
View File

@@ -1,6 +1,6 @@
{ {
"name": "unlock-music", "name": "unlock-music",
"version": "1.6.0", "version": "1.6.1",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@@ -1,7 +1,7 @@
{ {
"name": "unlock-music", "name": "unlock-music",
"version": "1.6.0", "version": "1.6.1",
"updateInfo": "增加对flac文件的meta写入支持QQ音乐封面写入实验性", "updateInfo": "修复flac文件的meta写入",
"license": "MIT", "license": "MIT",
"description": "Unlock encrypted music file in browser.", "description": "Unlock encrypted music file in browser.",
"repository": { "repository": {

View File

@@ -58,6 +58,6 @@ export async function CommonDecrypt(file) {
if (!rt_data.rawExt) rt_data.rawExt = raw_ext; if (!rt_data.rawExt) rt_data.rawExt = raw_ext;
if (!rt_data.rawFilename) rt_data.rawFilename = raw_filename; if (!rt_data.rawFilename) rt_data.rawFilename = raw_filename;
console.log(rt_data);
return rt_data; return rt_data;
} }

View File

@@ -39,25 +39,30 @@ export async function Decrypt(file, raw_filename, raw_ext) {
if (artists.length === 0) artists.push(info.artist); if (artists.length === 0) artists.push(info.artist);
if (musicMeta.format === undefined) musicMeta.format = DetectAudioExt(audioData, "mp3"); if (musicMeta.format === undefined) musicMeta.format = DetectAudioExt(audioData, "mp3");
console.log(musicMeta)
const imageInfo = await GetWebImage(musicMeta.albumPic); 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) 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 mime = AudioMimeType[musicMeta.format];
const musicData = new Blob([audioData], {type: mime}); const musicData = new Blob([audioData], {type: mime});
let x = { return {
status: true, status: true,
title: info.title, title: info.title,
artist: info.artist, artist: info.artist,
@@ -67,8 +72,6 @@ export async function Decrypt(file, raw_filename, raw_ext) {
file: URL.createObjectURL(musicData), file: URL.createObjectURL(musicData),
mime: mime mime: mime
}; };
console.log(x)
return x;
} }

View File

@@ -60,6 +60,7 @@ export async function Decrypt(file, raw_filename, raw_ext) {
const musicMeta = await musicMetadata.parseBlob(musicBlob); const musicMeta = await musicMetadata.parseBlob(musicBlob);
for (let metaIdx in musicMeta.native) { for (let metaIdx in musicMeta.native) {
if (musicMeta.native[metaIdx].some(item => item.id === "TCON" && item.value === "(12)")) { 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.artist = decode(musicMeta.common.artist, "gbk");
musicMeta.common.title = decode(musicMeta.common.title, "gbk"); musicMeta.common.title = decode(musicMeta.common.title, "gbk");
musicMeta.common.album = decode(musicMeta.common.album, "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); const imageInfo = await GetWebImage(imgUrl);
if (imageInfo.url !== "") { if (imageInfo.url !== "") {
imgUrl = imageInfo.url imgUrl = imageInfo.url
if (ext === "mp3") { try {
let writer = new ID3Writer(musicDecoded) if (ext === "mp3") {
writer.setFrame('APIC', { let writer = new ID3Writer(musicDecoded)
type: 3, writer.setFrame('APIC', {
data: imageInfo.buffer, type: 3,
description: "Cover", data: imageInfo.buffer,
}) description: "Cover",
writer.addTag(); })
musicDecoded = writer.arrayBuffer writer.addTag();
musicBlob = new Blob([musicDecoded], {type: mime}); musicDecoded = writer.arrayBuffer
} else if (ext === 'flac') { musicBlob = new Blob([musicDecoded], {type: mime});
const writer = new MetaFlac(Buffer.from(musicDecoded)) } else if (ext === 'flac') {
writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer)) const writer = new MetaFlac(Buffer.from(musicDecoded))
musicDecoded = writer.save() writer.importPictureFromBuffer(Buffer.from(imageInfo.buffer))
musicBlob = new Blob([musicDecoded], {type: mime}); musicDecoded = writer.save()
musicBlob = new Blob([musicDecoded], {type: mime});
}
} catch (e) {
console.warn("Error while appending cover image to file " + e)
} }
} }
} }