Rails 5 - параллельная загрузка видео и кодирование FFMPEG в фоновом режиме делает сервер очень медленным - PullRequest
2 голосов
/ 21 марта 2020

У меня есть работающие приложения на Rails 5, использующие Reactjs для внешнего интерфейса и React Dropzone Uploader для загрузки видеофайлов с использованием carrierwave.

Пока что отлично работает перечисленные ниже -

  1. Пользователь может загружать видео и видео, закодированные на основе выбора, сделанного пользователем - HLS или MPEG-DA SH для потоковой передачи в Интернете.
  2. После загрузки видео на сервер начинается потоковая передача: -
    • FIRST, копирование видео в папку /tmp.
    • Запуск сценарий bash, использующий ffmpeg в транскодирование загруженное видео с использованием предопределенных команд для создания новых фрагментов видео в папке /tmp.
    • Как только фоновое задание выполнено, все видео загружается на AWS S3, как это работает по умолчанию carrierwave
  3. Итак, когда загружено несколько видео, все они копируются в папку / tmp, а затем транскодируется и в конечном итоге загружается в S3.

Мои вопросы, по которым мне нужна помощь, перечислены ниже -

1 - описанный выше процесс подходит для небольших видео, НО что если Есть много одновременных пользователей, загружающих 2 ГБ видео ? Я знаю, что это убьет мой сервер, так как моя папка /tmp будет увеличиваться и занимать всю память, делая ее жесткой до d ie. Как я могу разрешить одновременное видео загружать видео, не влияя на потребление памяти моим сервером ?

2- Есть ли способ, где я могу напрямую загрузить видео сначала на AWS -S3, а затем использовать еще одно приложение прокси-сервера / дочернее приложение для кодирования видео с S3 , загрузить его на дочерний сервер, преобразовать и снова загрузить в пункт назначения? но это почти то же самое, но в облаке, где потребление памяти может быть по требованию, но не будет экономически эффективным.

3 - Есть ли некоторые простые и экономически эффективные способ, которым я могу загружать большие видео, транскодировать их и загружать их в AWS S3, не влияя на память моего сервера. Мне не хватает какой-то технической архитектуры здесь.

4- Как работает Youtube / Netflix, я знаю, что они делают то же самое умным способом, но может кто-нибудь помочь мне улучшить это?

Спасибо в заранее.

Ответы [ 3 ]

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

FFmpeg имеет несколько опций для подключения из потока, так что вы можете напрямую подключиться к файлу S3, обработать его небольшими частями и загрузить как составную часть в S3. Вы можете сделать это прямо на сервере, который у вас уже есть, или использовать lambda. с AWS как сказал @samuil

вот вопрос , где у них есть простой фрагмент, который может направить вас в нужном направлении

var s3Client = new AmazonS3Client(RegionEndpoint.USEast1);

var startInfo = new ProcessStartInfo
{
    FileName = "ffmpeg",
    Arguments = $"-i pipe:0 -y -vn -ar 44100 -ab 192k -f mp3 pipe:1",
    CreateNoWindow = true,
    RedirectStandardInput = false,
    RedirectStandardOutput = false,
    UseShellExecute = false,
    RedirectStandardInput = true,
    RedirectStandardOutput = true,
};

using (var process = new Process { StartInfo = startInfo })
{
    // Get a stream to an object stored on S3.
    var s3InputObject = await s3Client.GetObjectAsync(new GetObjectRequest
    {
        BucketName = "my-bucket",
        Key = "input.wav",
    });

    process.Start();

    // Store the output of ffmpeg directly on S3 in a background thread
    // since I don't 'await'.
    var uploadTask = s3Client.PutObjectAsync(new PutObjectRequest
    {
        BucketName = "my-bucket",
        Key = "output.wav",
        InputStream = process.StandardOutput.BaseStream,
    });

    // Feed the S3 input stream into ffmpeg
    await s3Object.ResponseStream.CopyToAsync(process.StandardInput.BaseStream);
    process.StandardInput.Close();

    // Wait for FFmpeg to be done
    await uploadTask;

    process.WaitForExit();
}
0 голосов
/ 02 апреля 2020

Я предполагаю, что этот вопрос касается ваших ограниченных ресурсов как на машине, так и на деньгах.

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

0 голосов
/ 02 апреля 2020

Один удобный вариант для этого:

  1. Загрузка файлов непосредственно на S3 с использованием предварительно назначенных URL-адресов
  2. Использование AWS Lambda для транскодирования или еще лучше: используйте для этого размещенное и управляемое решение .

Параллельные пользователи не будут вашим ограничением: вам не особо важны дисковые ИЛИ вычислительные ресурсы. Spikey traffi c будет обрабатываться управляемым сервисом. Хотя эксплуатационные расходы могут быть немного выше по сравнению с самостоятельными решениями, я сомневаюсь, что это будет дешевле, если вы учтете затраты на настройку и обслуживание инфраструктуры.

...