Add Tag Edit Function & Wasm for Qmc & Kgm #5
Labels
No Label
bug
crypto
duplicate
enhancement
help wanted
invalid
platform-android
platform-mac
platform-win
question
wontfix
No Milestone
No project
No Assignees
3 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: um/web#5
Loading…
Reference in New Issue
No description provided.
Delete Branch "nullptr-0/web:master"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
1.Add TypeScript Support for Qmc EncV2 Decryption
2.Add Wasm Acceleration for Qmc and Kgm Decryption
3.Add Support for multi-artists in Music Tag
4.Add Music Tag Edit Function
仓库里面不要提交编译产物
引入wasm的话,可以参考 qmc_wasm,将编译产物作为npm包发布,并提供源代码
@ -34,2 +36,2 @@
let audioData = oriData.slice(headerLen);
let dataLen = audioData.length;
const kgmDecrypted = await DecryptKgmWasm(oriData, raw_ext);
// 若 v2 检测失败,降级到 v1 再尝试一次
没有 v2
@ -36,0 +39,4 @@
musicDecoded = kgmDecrypted.data;
console.log('kgm wasm decoder suceeded');
} else {
console.warn('KgmWasm failed with error %s', kgmDecrypted.error || '(no error)');
no error
应为unknown error
@ -36,0 +44,4 @@
}
if (!musicDecoded) {
musicDecoded = new Uint8Array(oriData);
还是动态生成 mask 的方案… 直接删掉这部分也许会更好?
js部分作为WASM不受支持或执行失败时的fallback
但是要注意这两个实现不一致。遇到报告错误的时候,排查问题会很麻烦。
看 caniuse 的数据,除了上古浏览器(如 IE 11 和以前),基本都有提供支援了:
https://caniuse.com/wasm
那qmc的js部分也删掉吗(既然一般情况下都支持wasm)
我的看法是也可以删了。
@ -39,3 +39,3 @@
const musicMeta = await metaParseBlob(musicBlob);
const { title, artist } = GetMetaFromFile(raw_filename, musicMeta.common.title, musicMeta.common.artist);
const { title, artist } = GetMetaFromFile(raw_filename, musicMeta.common.title, musicMeta.common.artists == undefined ? musicMeta.common.artist : musicMeta.common.artists.toString());
musicMeta.common.artists == undefined ? musicMeta.common.artist : musicMeta.common.artists.toString()
可以替换为String(musicMeta.common.artists || musicMeta.common.artist)
。@ -14,3 +14,3 @@
if (ext !== raw_ext) file = new Blob([buffer], { type: AudioMimeType[ext] });
const tag = await metaParseBlob(file);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artist);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString());
同上,
tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString()
可以替换为String(tag.common.artists || tag.common.artist)
。@ -35,0 +37,4 @@
const mixKey1: Uint8Array = new Uint8Array([ 0x33, 0x38, 0x36, 0x5A, 0x4A, 0x59, 0x21, 0x40, 0x23, 0x2A, 0x24, 0x25, 0x5E, 0x26, 0x29, 0x28 ])
const mixKey2: Uint8Array = new Uint8Array([ 0x2A, 0x2A, 0x23, 0x21, 0x28, 0x23, 0x24, 0x25, 0x26, 0x5E, 0x61, 0x31, 0x63, 0x5A, 0x2C, 0x54 ])
const v2KeyPrefix: Uint8Array = new Uint8Array([ 0x51, 0x51, 0x4D, 0x75, 0x73, 0x69, 0x63, 0x20, 0x45, 0x6E, 0x63, 0x56, 0x32, 0x2C, 0x4B, 0x65, 0x79, 0x3A ])
未使用的变量,后面直接内嵌了
@ -25,0 +27,4 @@
musicDecoded = qmcDecrypted.data;
console.log('qmc wasm decoder suceeded');
} else {
console.warn('QmcWasm failed with error %s', qmcDecrypted.error || '(no error)');
no error
应为unknown error
。@ -36,3 +55,3 @@
}
const tag = await metaParseBlob(audioBlob);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artist);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString());
tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString()
可以替换为String(tag.common.artists || tag.common.artist)
。@ -18,3 +18,3 @@
}
const tag = await metaParseBlob(file);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artist);
const { title, artist } = GetMetaFromFile(raw_filename, tag.common.title, tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString());
tag.common.artists == undefined ? tag.common.artist : tag.common.artists.toString()
可以替换为String(tag.common.artists || tag.common.artist)
。@ -92,3 +94,3 @@
const items = filename.split(separator);
if (items.length > 1) {
if (!meta.artist) meta.artist = items[0].trim();
if (!meta.artist || meta.artist.split(split_regex).length < items[0].trim().split(split_regex).length) meta.artist = items[0].trim();
不清楚这个新增的判定的含义,加一些注释可能会比较好一点。
@ -172,0 +176,4 @@
export function RewriteMetaToMp3(audioData: Buffer, info: IMusicMeta, original: IAudioMetadata) {
const writer = new ID3Writer(audioData);
// reserve original data
reserve
=>preserve
?@ -172,0 +188,4 @@
try {
writer.setFrame(frame.id, frame.value);
} catch (e) {
throw new Error('write unknown mp3 frame failed');
可以将
frame.id
和frame.value
都打印到console
,然后报错不过即便如此,更好的方法也许是提示这个错误然后继续,因为写 ID3 只是一个附加功能,而不是核心功能。
@ -172,0 +213,4 @@
export function RewriteMetaToFlac(audioData: Buffer, info: IMusicMeta, original: IAudioMetadata) {
const writer = new MetaFlac(audioData);
const old = original.common;
if (info.title) {
完全可以写一个包装函数,
addOrReplaceTag
。Add和Replace的逻辑有差别,Add以旧tag为优先,Replace以新tag为优先,感觉即使封装了最后还是要分开调用Add和Replace
这个函数就是用来方便覆盖现有 tag;如果还没有,就加入。
@ -50,3 +50,3 @@
raw_filename,
musicMeta.common.title,
musicMeta.common.artist,
musicMeta.common.artists == undefined ? musicMeta.common.artist : musicMeta.common.artists.toString(),
String(musicMeta.common.artists || musicMeta.common.artist)
。@ -40,2 +41,3 @@
console.warn('try using gbk encoding to decode meta');
musicMeta.common.artist = iconv.decode(new Buffer(musicMeta.common.artist ?? ''), 'gbk');
musicMeta.common.artist = '';
if (musicMeta.common.artists == undefined) {
== undefined
部分undefined
值,应使用===
操作符。@ -42,0 +45,4 @@
}
else {
musicMeta.common.artists.forEach((artist) => artist = iconv.decode(new Buffer(artist ?? ''), 'gbk'));
musicMeta.common.artist = musicMeta.common.artists.toString();
String(musicMeta.common.artists || musicMeta.common.artist)
。但是这样改就不是gbk编码了吧
确实忽略了 GBK 的情况,请无视之前的建议。
下面的
iconv.decode
调用也可以更改为调用这个新的包装函数。@ -45,3 +53,3 @@
}
if (id) {
if (id && id !== '0') {
为什么一开始不传入一个整数值呢
wasm版本返回的songId是string,'0'也和0一样代表无效的id
建议改一下 wasm 的返回值或 js 接收这个值的时候做类型转换。
id本身的类型就是number | string,所以我觉得两种都应该支持吧
也行
@ -68,3 +76,3 @@
blob: await writeMetaToAudioFile({
title: info.title,
artists: info.artist.split(' _ '),
artists: info.artist.split(split_regex),
同上,为什么一开始就不使用字符串数组来储存艺术家信息?
历史问题。原来的GetMetaFromFile返回的艺术家信息是string
直接重构吧,不然很多代码都要字符串、数组转来转去。
明明是同一个项目里的代码…
或者写一个包装函数调用也可以,如
const isSongIdInvalid = (songId: unknown) => songId && songId !== '0';
@ -89,3 +97,3 @@
return {
title: info.track_info.title,
artist: artists.join('、'),
artist: artists.join(','),
意义不明的更改。需要注释。
与toString的结果统一格式(虽然原来的结果regex也可以匹配)
参见上面的那条回复
@ -131,0 +146,4 @@
async handleEdit(data) {
this.showEditDialog = false;
URL.revokeObjectURL(this.editing_data.file);
if (data.picture) {
picture
换成albumCover
也许会好一点。历史问题。为了与原来的DecryptResult保持统一
也行
@ -131,0 +179,4 @@
console.warn('Error while appending cover image to file ' + e);
}
this.editing_data.file = URL.createObjectURL(this.editing_data.blob);/**/
this.$notify.success({
这个提示应该没有必要,因为用户可以看到预览更新?
可能预览更新成功了但是文件写入失败了(v1.10.2就出现了这种情况)
但这样的话不应该是捕捉出错信息并提示用户吗。
我看上面还有个
try/catch
块,但是错误直接吞掉了。看起来这些术语构建产物,添加到 .gitignore
看起来这些术语构建产物,添加到 .gitignore
@ -22,1 +22,4 @@
*.sw?
/src/KgmWasm/build
/src/KgmWasm/build
/src/KgmWasm/build
->/src/QmcWasm/build
@ -0,0 +192,4 @@
{
for (size_t i = 0; i < blobData.size(); i++) {
blobData[i] ^= 0xf4;
blobData[i] = ((blobData[i] & 0b0011_1111) << 2) | (blobData[i] >> 6); // rol 2
这里有语法错误,C++不支持分隔符
0b0011_1111
->0b00111111
83d0bcca75
toc8c4f8dfd6
LGTM;其他与 QmcWasm / KgmWasm 不相关的移动到 #9 跟踪处理