сделать видео thumbnail firebase cloud function [duplicate]

Решение HTML5

<input type="submit" hidden />
9
задан Frank van Puffelen 13 March 2017 в 22:49
поделиться

5 ответов

ffmpeg не предустановлен (в значительной степени просто ImageMagick); чтобы увидеть, что именно установлено, проверьте файл Docker здесь: https://github.com/GoogleCloudPlatform/nodejs-docker/blob/master/runtime-image/Dockerfile .

Однако вы можете загружать произвольные двоичные файлы при загрузке кода с помощью gcloud beta functions deploy, потому что загружается все в текущем каталоге (кроме node_modules).

Примечание: у вас есть только доступ к записи на диск в /tmp/.

Вариант 1: использовать модуль ffmpeg-static npm

ffmpeg-static - модуль npm, который строит правильный двоичный файл ffmpeg на основе текущей системы во время npm install. Поскольку облачные функции строят ваш код в облаке, он построит правильный двоичный файл ffmpeg.

https://github.com/eugeneware/ffmpeg-static

Вы можете увидеть это в действии в Облачных функциях для примеров Firebase repo .

const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

var cmd = ffmpeg('/tmp/video.avi')
  .setFfmpegPath(ffmpeg_static.path)
  .videoBitrate(1024)
  .videoCodec('divx')
  .format('avi')
  .on('end', () => {
    // ...
  })
  .on('error', err => {
    console.error(err);
  })
  .save('/tmp/file-out.avi');

( Спасибо Даниэлю Лессе за то, что он указал на этот модуль в его ответе .)

Вариант 2: загрузить свой собственный двоичный файл

Вы можете включить двоичный файл ffmpeg как часть загрузите и затем запустите команду оболочки, используя что-то вроде child_process.exec . Вам понадобится двоичный файл ffmpeg, который скомпилирован для целевой платформы (Debian / jessie).

Список файлов с предварительно скомпилированным ffmpeg binary

./
../
index.js
ffmpeg

Затем запустите, например, gcloud beta functions deploy myFunc --trigger-http

index.js

var exec = require('child_process').exec;
var cmd = 'ffmpeg -i /tmp/myvideo.mp4 /tmp/image-%d.jpg';

exec(cmd, function(error, stdout, stderr) {
  // command output is in stdout
});
18
ответ дан Bret McGowen 15 August 2018 в 14:51
поделиться
  • 1
    github.com/eugeneware/ffmpeg-static также работает – user473453 16 April 2017 в 22:48
  • 2
    Как я могу ссылаться на файл в функции облачной Firebase, я имею в виду, каков путь для записи в команде FFMPEG, чтобы ссылаться на файл в хранилище firebase? – Omar HossamEldin 4 December 2017 в 23:24
  • 3
    @OmarHossamEldin все, что вы загружаете как часть вашей функции, хранится в каталоге /user_code/ на сервере. – Bret McGowen 6 April 2018 в 23:31
  • 4
    Это была спасательная жизнь - спасибо! Это была такая помощь с ссылками на страницы Github. Однако обратите внимание, что я использую пакет fluent-ffmpeg npm и необходимо добавить путь ffmpeg к двоичному файлу в файле Docker в качестве переменной ENV: ENV PATH="/usr/src/app/node_modules/ffmpeg-static/bin/linux/x64:${PATH}" – Peza 5 June 2018 в 11:02

Пока вы технически можете запускать FFMPEG на экземпляре Firebase Functions, вы быстро достигнете небольших пределов квоты.

В соответствии с этим ответом вместо этого вы можете использовать функции, чтобы инициировать запрос к более мощным сервисам App Engine или Compute Engine GCP. Процесс App Engine может захватывать файл из одного и того же ведра, обрабатывать транскодирование и загружать готовый файл обратно в ведро. Если вы проверите другие ответы по ссылке, один пользователь разместил образец репо, который делает именно это.

2
ответ дан ajabeckett 15 August 2018 в 14:51
поделиться

Используйте lib https://github.com/eugeneware/ffmpeg-static

const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');


let cmd = ffmpeg.('filePath.mp4')
   .setFfmpegPath(ffmpeg_static.path)
   .setInputFormat('mp4')
   .output('outputPath.mp4')
   ...
   ...
   .run()
5
ответ дан Daniel Lessa 15 August 2018 в 14:51
поделиться

Насколько я знаю, ffmpeg не предварительно установлен на контейнерах.

Когда мне нужно перекодировать носитель, я просмотрел кросс-скомпилированную версию ffmpeg emscripten . Казалось, что он отлично работает в средах локальных узлов, но я никогда не собирался его развертывать (поскольку нам не нужно было перекодировать в конце концов).

0
ответ дан Frank van Puffelen 15 August 2018 в 14:51
поделиться
/**
 * Copyright 2017 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for t`he specific language governing permissions and
 * limitations under the License.
 */
'use strict';

const functions = require('firebase-functions');
const gcs = require('@google-cloud/storage')();
const path = require('path');
const os = require('os');
const fs = require('fs');
const ffmpeg = require('fluent-ffmpeg');
const ffmpeg_static = require('ffmpeg-static');

/**
 * When an audio is uploaded in the Storage bucket We generate a mono channel audio automatically using
 * node-fluent-ffmpeg.
 */
exports.generateMonoAudio = functions.storage.object().onChange(event => {
  const object = event.data; // The Storage object.

  const fileBucket = object.bucket; // The Storage bucket that contains the file.
  const filePath = object.name; // File path in the bucket.
  const contentType = object.contentType; // File content type.
  const resourceState = object.resourceState; // The resourceState is 'exists' or 'not_exists' (for file/folder deletions).
  const metageneration = object.metageneration; // Number of times metadata has been generated. New objects have a value of 1.

  // Exit if this is triggered on a file that is not an audio.
  if (!contentType.startsWith('audio/')) {
    console.log('This is not an audio.');
    return;
  }

  // Get the file name.
  const fileName = path.basename(filePath);
  // Exit if the audio is already converted.
  if (fileName.endsWith('_output.flac')) {
    console.log('Already a converted audio.');
    return;
  }

  // Exit if this is a move or deletion event.
  if (resourceState === 'not_exists') {
    console.log('This is a deletion event.');
    return;
  }

  // Exit if file exists but is not new and is only being triggered
  // because of a metadata change.
  if (resourceState === 'exists' && metageneration > 1) {
    console.log('This is a metadata change event.');
    return;
  }

  // Download file from bucket.
  const bucket = gcs.bucket(fileBucket);
  const tempFilePath = path.join(os.tmpdir(), fileName);
  // We add a '_output.flac' suffix to target audio file name. That's where we'll upload the converted audio.
  const targetTempFileName = fileName.replace(/\.[^/.]+$/, "") + '_output.flac';
  const targetTempFilePath = path.join(os.tmpdir(), targetTempFileName);
  const targetStorageFilePath = path.join(path.dirname(filePath), targetTempFileName);

  return bucket.file(filePath).download({
    destination: tempFilePath
  }).then(() => {
    console.log('Audio downloaded locally to', tempFilePath);
    // Convert the audio to mono channel using FFMPEG.
    const command = ffmpeg(tempFilePath)
      .setFfmpegPath(ffmpeg_static.path)    
      .audioChannels(1)
      .audioFrequency(16000)
      .format('flac')
      .on('error', (err) => {
        console.log('An error occurred: ' + err.message);
      })
      .on('end', () => {
        console.log('Output audio created at', targetTempFilePath);

        // Uploading the audio.
        return bucket.upload(targetTempFilePath, {destination: targetStorageFilePath}).then(() => {
          console.log('Output audio uploaded to', targetStorageFilePath);

          // Once the audio has been uploaded delete the local file to free up disk space.     
          fs.unlinkSync(tempFilePath);
          fs.unlinkSync(targetTempFilePath);

          console.log('Temporary files removed.', targetTempFilePath);
        });
      })
      .save(targetTempFilePath);
  });
});

https://github.com/firebase/functions-samples/blob/master/ffmpeg-convert-audio/functions/index.js

0
ответ дан Henry 15 August 2018 в 14:51
поделиться
Другие вопросы по тегам:

Похожие вопросы: