首页 > 解决方案 > 无法从 FileSaver/Blob 与 Node 的 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 大调音阶的示例。

标签: node.jsblobmidifilesaver.js

解决方案


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

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

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


推荐阅读