亚马逊 S3 服务器上的 Concat MP3/媒体音频文件
Posted
技术标签:
【中文标题】亚马逊 S3 服务器上的 Concat MP3/媒体音频文件【英文标题】:Concat MP3/media audio files on amazon S3 server 【发布时间】:2015-09-24 22:30:09 【问题描述】:我想连接上传到 Amazon S3 服务器上的文件。 我该怎么做。
我可以使用以下代码在本地机器上进行连接。
var fs = require('fs'),
files = fs.readdirSync('./files'),
clips = [],
stream,
currentfile,
dhh = fs.createWriteStream('./concatfile.mp3');
files.forEach(function (file)
clips.push(file.substring(0, 6));
);
function main()
if (!clips.length)
dhh.end("Done");
return;
currentfile = './files/' + clips.shift() + '.mp3';
stream = fs.createReadStream(currentfile);
stream.pipe(dhh, end: false);
stream.on("end", function()
main();
);
main();
【问题讨论】:
你不能,因为你不能在 S3 服务器上执行代码。您需要下载、连接、上传。 可以在 unix shell 中使用cat
管道|
和大于>
来完成连接文件。将两个 mp3 放在一起是一个不同的问题。请区分并更好地描述您的问题。
是的,连接 mp3 的内容是不同的业务,然后只是连接文件
连接文本文件是一回事......你只需下载 concat 然后上传。但是,二进制媒体文件(例如 MP3)不能只是串联,因为这实际上是一个相当复杂的过程。关于 MP3 或如何从 S3 连接通用文本文件的问题也是如此。请适当编辑您的问题。
您可以使用 audiosprite 节点模块将 mp3 文件与 ffmpeg 连接起来。 https://github.com/tonistiigi/audiosprite
。正如其他人所提到的。您通常需要从 S3 下载 mp3 文件,然后加入它们。根据您的最终目标,可以加入并将加入的文件提供给您的用户,而无需下载到您的服务器,而是根据用户事件(例如join button
)使用 AWS lambda 进行处理。 lambda 和 S3 靠得很近,因此不会增加双倍延迟或额外的服务器负载。如果这是您想知道的,请更新问题。
【参考方案1】:
你可以把它分成两个步骤来实现你想要的:
在 s3 上操作文件
由于 s3 是远程文件存储,因此您无法在 s3 服务器上运行代码以在本地执行操作(如 @Andrey 所述)。 您需要在代码中做的是获取每个输入文件,在本地处理它们并将结果上传回 s3。查看amazon的代码示例:
var s3 = new AWS.S3();
var params = Bucket: 'myBucket', Key: 'mp3-input1.mp3';
var file = require('fs').createWriteStream('/path/to/input.mp3');
s3.getObject(params).createReadStream().pipe(file);
在此阶段,您将运行连接代码,并将结果上传回来:
var fs = require('fs');
var zlib = require('zlib');
var body = fs.createReadStream('bigfile.mp3').pipe(zlib.createGzip());
var s3obj = new AWS.S3(params: Bucket: 'myBucket', Key: 'myKey');
s3obj.upload(Body: body).
on('httpUploadProgress', function(evt) console.log(evt); ).
send(function(err, data) console.log(err, data) );
合并两个(或更多)mp3 文件
由于 MP3 文件包含指定比特率等信息的标头,因此简单地将它们连接在一起可能会导致播放问题。 见:https://***.com/a/5364985/1265980
你想用什么工具来做。您可以采用一种方法将输入的 mp3 文件保存在 tmp 文件夹中,然后执行外部程序,例如更改比特率、连接文件和修复标题。 或者,您可以使用允许您使用的库 ffmpeg within node.js.
在他们展示的代码示例中,您可以看到他们如何在节点 api 中将两个文件合并在一起。
ffmpeg('/path/to/part1.avi')
.input('/path/to/part2.avi')
.input('/path/to/part2.avi')
.on('error', function(err)
console.log('An error occurred: ' + err.message);
)
.on('end', function()
console.log('Merging finished !');
)
.mergeToFile('/path/to/merged.avi', '/path/to/tempDir');
【讨论】:
【参考方案2】:这是我对下载和处理S3 objects
问题的快速看法。我的示例主要侧重于获取本地数据,然后在全部下载后对其进行处理。我建议你使用上面提到的ffmpeg
方法之一。
var RSVP = require('rsvp');
var s3 = new AWS.S3();
var bucket = '<your bucket name>';
var getFile = function(key, filePath)
return new RSVP.Promise(function(resolve, reject)
var file = require('fs').createWriteStream(filePath);
if(!file)
reject('unable to open file');
s3.getObject(
Bucket: bucket,
Key: key
).on('httpData', function(chunk)
file.write(chunk);
).on('httpDone', function()
file.end();
resolve(filePath);
);
);
;
var tempFiles = ['<local temp filename 1>', '<local temp filename 2>'];
var keys = ['<s3 object key 1>', '<s3 object key 2>'];
var promises = [];
for(var i = 0; i < keys.length; ++i)
var promise = getFile(keys[i], tempFiles[i]);
promises.push(promise);
RSVP.all(promises).then(function(data)
//do something with your files
).catch(function(error)
//handle errors
);
【讨论】:
以上是关于亚马逊 S3 服务器上的 Concat MP3/媒体音频文件的主要内容,如果未能解决你的问题,请参考以下文章