Подтвердить что ты не робот

Конкат MP3/мультимедийные аудиофайлы на сервере Amazon S3

Я хочу объединить файлы, загруженные на сервер 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();
4b9b3361

Ответ 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 содержит заголовок, который указывает некоторую информацию, такую ​​как биттрейт, просто объединение их вместе может вызвать проблемы с воспроизведением. См.: fooobar.com/questions/107043/...

что вы хотите использовать с этим инструментом. вы можете использовать один из способов сохранения ваших входных mp3 файлов в папке tmp и выполнения внешней программы, например, для изменения битрейта, contcatenate файлов и исправления заголовка. альтернативно вы можете использовать библиотеку, которая позволяет использовать ffmpeg в node.js.

в показанном примере кода, вы можете увидеть, как их объединение двух файлов вместе в node 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
});