在Google App Engine存储前压缩数据

1 投票
5 回答
2603 浏览
提问于 2025-04-15 16:02

我正在尝试将用户录制的30秒MP3音频存储为Blob(大对象)在我的应用引擎数据存储中。不过,为了实现这个功能(应用引擎每次上传有1MB的限制),并且为了降低成本,我想在上传之前先压缩文件,每次请求时再解压缩。你觉得我该怎么做呢?(这可以在后台通过任务队列完成,但高效的解决方案总是好的)

根据我自己的测试和研究,我发现有两种可能的方法可以实现这个目标:

  • Zlib

为了这个,我需要使用一个While循环一次压缩一定数量的块。但是,应用引擎不允许你写入文件系统。我考虑过使用临时文件来实现这个,但在尝试从临时文件解压内容时没有成功。

  • Gzip

从网上的资料来看,应用引擎的URL获取功能似乎会请求已经被gzip压缩的内容,然后再解压缩。有没有办法阻止这个功能解压内容,这样我就可以把它以gzip格式存入数据存储中,然后在需要播放给用户时再解压呢?

请告诉我你建议如何使用zlib或gzip,或者其他什么解决方案来实现这个目标。谢谢!

5 个回答

2

虽然在其他回答中提到的通过标准压缩或以更低比特率重新编码来压缩MP3文件的技术限制是正确的,但你的目标是存储30秒的MP3编码数据。假设你可以让用户遵守这个限制,如果MP3的比特率是256kbit的固定比特率(CBR)或更低,那你就不需要使用额外的压缩技术了。在256kbit CBR的情况下,30秒的音频需要:

(((256 * 1000) / 8) * 30) / 1048576 = 0.91MB

最大标准比特率是320kbit,这相当于1.14MB,所以你需要使用256kbit或更低的比特率。在实际使用中,最常见的比特率是128kbit。

还有一些额外的开销会增加最终文件的大小,比如ID3标签和帧,但你应该没问题。如果不行,可以把最大比特率降到224kbit(30秒 = 0.80MB)。还有其他复杂的情况,比如可变比特率编码,这种情况下文件大小就不那么容易预测了,我就不讨论这些了。

所以你现在的问题不再是如何压缩MP3文件,而是如何确保用户知道他们不能上传超过30秒、以256kbit CBR编码的音频,以及如何执行这个政策。

2

“在上传之前压缩”意味着要在用户的浏览器里进行压缩,但你提问的内容并没有提到这一点!看起来你是在说在你的GAE应用里进行压缩,而那样的话,数据压缩只能在上传之后进行。你可以通过Firefox的扩展程序(或者其他浏览器的类似工具)来实现这个功能,如果你能开发这些扩展并说服用户安装它们,但这和GAE关系不大!另外,正如@RageZ的评论所说,MP3文件本身就已经压缩过了,所以压缩的效果可能不大(不过你可以通过用户的浏览器扩展来降低MP3的比特率,从而减小文件大小,这可能会影响音质,具体取决于你对这些音频文件的使用需求)。

所以,总的来说,我同意@jldupont的建议(他在评论中提到的)——使用其他服务器来存储大文件(比如S3,亚马逊的服务,当然这不是唯一的选择)。

撰写回答