我正在开发一个基本上可以在客户端生成视频的内部项目,但由于我没有注意到的JavaScript视频编码器,我只是单独导出每个帧。我需要避免上传到服务器;这一切都发生在客户端。
我正在使用此FileSaver.js(更具体地说,Chrome的webkit FileSystem API)来保存HTML5画布生成的大量PNG。我将Chrome设置为自动下载到特定文件夹,因此当我点击“保存”时,它会起飞并保存每秒20张图像。这完全符合我的目的。
如果我可以使用JSZip将所有这些帧压缩到一个文件中,然后再将其提供给客户端进行保存,我会这么做,但我还没试过,因为浏览器根本没有足够的内存生成~8000个640x480 PNG,然后压缩它们。
问题是在一定数量的图像之后,每个下载的文件都是空的。 Chrome甚至开始在下载栏中告诉我该文件是0字节。在具有相同导出设置的同一项目上重复,空保存将在完全相同的时间开始。例如,对于一个项目,我可以在扼流圈之前保存前5494帧。 (我知道这是一个非常大的数字,但我无法帮助。)我尝试在保存之间设置10毫秒的延迟,但这没有任何影响。我没有尝试过更大的延迟,因为导出需要很长时间。
我检查了blob.size,它永远不会为零。我怀疑它超过了一些配额,但没有错误抛出;它只是默默地无法写入沙箱或将文件复制到用户指定的位置。
如何检测这些空保存?防止他们?有一个更好的方法吗?我刚搞砸了吗?
编辑:实际上,在调试FileSaver.js后,我意识到它甚至没有使用webkitRequestFileSystem;当它到达时它会返回:
if (can_use_save_link) {
object_url = get_object_url(blob);
save_link.href = object_url;
save_link.download = name;
if (click(save_link)) {
filesaver.readyState = filesaver.DONE;
dispatch_all();
return;
}
}
因此,看起来它甚至没有使用FileSystem API,因此我不知道如何在存储空满之前清空它。
编辑2:我尝试将“if(can_use_save_link)”块移动到“writer.onwriteend”函数内部,并将其更改为:
if (can_use_save_link) {
save_link.href = file.toURL();
save_link.download = name;
click(save_link);
}else{
target_view.location.href = file.toURL();
}
结果是我能够保存所有8260个文件(总共大约1.5GB),因为它现在使用带有配额的存储。之前,文件没有显示在HTML5文件系统中,因为我假设如果anchor元素支持'download'属性,则不需要将它们放在那里。
我还能够注释掉将“.download”附加到文件名的代码,并且我必须提供一个空的匿名函数作为“file.remove()”的两个实例的参数。
答案 0 :(得分:0)
使用JSZip,如果禁用压缩(这是默认设置),它将不会使用太多内存。要手动禁用压缩,请务必在调用compression: "STORE"
时传递zip.generate()
。
答案 1 :(得分:0)
我最终修改了FileSaver.js(参见原帖中的“EDIT 2”)。