无法从 FileSaver/Blob 获得与 Node 的 fs 相同的结果

Unable to get same result from FileSaver/Blob versus Node's fs

我正在尝试生成一个 midi 文件(使用 jsmidgen)并且我能够以这种方式使用节点输出它:

fs.writeFileSync('test.mid', file.toBytes(), 'binary');

那个 midi 文件工作得很好。然后我尝试从浏览器生成它,然后用 FileSaver.js 以这种方式下载它:

let blob = new Blob([file.toBytes()], {type: "audio/midi"});
saveAs(blob, "test.mid");

该 MIDI 文件已损坏。我尝试了各种 blob 内容类型但都没有成功,而且我还验证了 file.toBytes() 输出在两种情况下都是相同的。我比较了两个十六进制输出,它看起来像是编码问题,但我找不到解决方法。

好的文件中的十六进制代码(用 fs 保存在 Node 中)

4d 54 68 64 00 00 00 06 
00 00 00 01 00 80 4d 54 
72 6b 00 00 00 5e 00 90 
3c 5a 40 80 3c 5a 00 90 
3e 5a 40 80 3e 5a 00 90 
40 5a 40 80 40 5a 00 90 
41 5a 40 80 41 5a 00 90 
43 5a 40 80 43 5a 00 90 
45 5a 40 80 45 5a 00 90 
47 5a 40 80 47 5a 00 90 
48 5a 40 80 48 5a 81 00 
90 3c 5a 00 90 40 5a 00 
90 43 5a 81 00 80 3c 5a 
00 80 40 5a 00 80 43 5a 
00 ff 2f 00

来自错误文件的十六进制代码 (FileSaver/Blob) :

4d 54 68 64 00 00 00 06 
00 00 00 01 00 c2 80 4d 
54 72 6b 00 00 00 44 00
c2 90 3c 5a 40 c2 80 3c 
5a 00 c2 90 3e 5a 40 c2 
80 3e 5a 00 c2 90 40 5a 
40 c2 80 40 5a 00 c2 90 
41 5a 40 c2 80 41 5a 00 
c2 90 43 5a 40 c2 80 43 
5a 00 c2 90 45 5a 40 c2 
80 45 5a 00 c2 90 47 5a 
40 c2 80 47 5a 00 c2 90 
48 5a 40 c2 80 48 5a 00 
c3 bf 2f 00

我使用 Blob 的方式有问题吗?或者我可以尝试其他方法吗?

我用来生成midi文件的代码是jsmidgen页面上的第一个例子,演奏C大调音阶的那个。

需要专门使用Blob吗?如果没有,那么你可以使用 btoa.

我使用 jsmidgen 作为我的 module 的主要依赖项(它充当包装器并做一些其他事情)并且我遇到了类似的问题因此想出了这个:

const bytes = file.toBytes();
const b64 = btoa(bytes);
const uri = 'data:audio/midi;base64,' + b64;
const link=document.createElement('a');

link.href=uri;
link.download = 'music.mid';
link.click(); // this will start a download of the MIDI byte string 

我已经在我的模块的上下文中记录了这一点,其中也有一个可用的 JS Bin:https://scribbletune.com/documentation/core/midi