Прочитайте видеофайл S3, обработайте его с помощью ffmpeg и загрузите на S3 - PullRequest
0 голосов
/ 28 апреля 2020

У меня есть видео, хранящееся в корзине s3 с ACL с проверкой подлинности.

Мне нужно прочитать и создать трейлер с ffmpeg (nodejs)

Вот код, который я использую для сгенерировать трейлер

exports.generatePreview = (req, res) => {
    const getParams = {
        Bucket: S3_CREDENTIALS.bucketName,
        Key: req.params.key
    }
    s3.getSignedUrl('getObject', getParams, (err, signedRequest) => {
        console.log(signedRequest, err, 'getSignedUrl')
        ffmpeg(new URL(signedRequest))
            .size('640x?')
            .aspect('4:3')
        .seekInput('3:00')
        .duration('0:30')
        .then(function (video) {
            s3.putObject({ Bucket: S3_CREDENTIALS.bucketName, key: 'preview_' + req.body.key, Body: video }, function (err, data) {
                console.log(err, data)
            })
        });
});

}

К сожалению, путь к конструктору, похоже, не читает удаленный URL. Если я пытаюсь выполнить командную строку ffmpeg с тем же подписанным (то есть ffmpeg -i "https://[bucketname].s3.eu-west-1.amazonaws.com/[key.mp4]?[signedParams]" -vn -acodec pcm_s16le -ar 44100 -ac 2 video.wav)

Я получаю сообщение об ошибке: URL подписанного запроса 'The input file does not exist'

Кажется, fs.readFileSyn c https не поддерживается, даже если я пытаюсь запросить http с тем же результатом. fs.readFileSync(signedurl) => дает тот же результат

Как преодолеть эту проблему?

1 Ответ

1 голос
/ 28 апреля 2020

Если вы используете node-ffmpeg, это невозможно, поскольку библиотека принимает только строку, указывающую на локальный путь, но fluent-ffmpeg поддерживает потоки чтения, поэтому попробуйте.

Например, (непроверенный, просто spitballing):

const ffmpeg = require('fluent-ffmpeg');
const stream = require('stream');

exports.generatePreview = (req, res) => {
  let params = {Bucket: S3_CREDENTIALS.bucketName, Key: req.params.key};

  // Retrieve object stream
  let readStream = s3.getObject(params).createReadStream();

  // Set up the ffmpeg process
  let ffmpegProcess = new ffmpeg(readStream)
    //Add your args here
    .toFormat('mp4');  

  ffmpegProcess.on('error', (err, stdout, stderr) => {
    // Handle errors here
  }).on('end', () => {
    // Processing is complete
  }).pipe(() => {
    // Create a new stream
    let pt = new stream.PassThrough();

    // Reuse the same params object and set the Body to the stream
    params.Key = 'preview_' + req.body.key;
    params.Body = pt;

    // Upload and wait for the result
    s3.upload(params, (err, data) => {
      if (err)
        return console.error(err);

      console.log("done");
    })
  });
});

Это будет иметь высокие требования к памяти, поэтому, если это лямбда-функция, вы можете поиграть с извлечением только первых X байтов файла и преобразованием только этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...