ruby-on-rails - Rails 5 - 并发的大型视频上传和后台 FFMPEG 编码使服务器非常慢

标签 ruby-on-rails amazon-s3 ffmpeg video-streaming carrierwave

我有一个工作的 Rails 5 应用程序,前端使用 Reactjs 和 React dropzone uploader使用载波上传视频文件。

到目前为止,下面列出了运行良好的内容 -

  1. 用户可以上传视频,视频会根据用户的选择进行编码 - HLSMPEG-DASH用于在线流媒体。
  2. 一旦视频上传到服务器,它就会开始流式传输:-
    • 首先,将视频复制到 /tmp 文件夹。
    • 运行使用 ffmpeg 的 bash 脚本,使用预定义的命令转码上传的视频,以在 /tmp 文件夹中生成新的视频片段。
    • 后台作业完成后,所有视频都会上传到 AWS S3,这就是默认 carrierwave 的工作方式
  3. 因此,当上传多个视频时,它们都被复制到/tmp 文件夹中,然后转码,最终上传到S3

我的问题,我正在寻找帮助的地方列在下面 -

1- 上述过程适用于小视频,但是如果有许多并发用户上传 2GB 的视频怎么办?我知道这会杀死我的服务器,因为我的 /tmp 文件夹将不断增加并消耗所有内存,使其难以抗拒。如何允许并发视频上传视频而不影响我的服务器的内存消耗?

2- 有没有一种方法可以让我先直接在 AWS-S3 上上传视频,然后再使用一个代理服务器/子应用程序从 S3 编码视频,下载给 child 服务器,将其转换并再次上传到目的地?但这几乎是一样的,但是在云上进行,内存消耗可以按需但不具有成本效益。

3- 是否有一些简单且经济高效的方法可以让我上传大型视频、对其进行转码并将其上传到 AWS S3,而不影响我的服务器内存。我在这里是否遗漏了一些技术架构。

4- Youtube/Netflix 是如何工作的,我知道他们以一种聪明的方式做同样的事情,但有人可以帮助我改进吗?

提前致谢。

最佳答案

FFmpeg 有一些从流连接的选项,因此您可以直接连接到您的 S3 文件并按小部分处理它,然后作为多部分上传到 S3,您也可以使用您已有的服务器或使用 lambda 执行此操作正如@samuil 所说,来自 AWS

here is a question他们有一个简单的片段,可以将您带到正确的方向

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();
}

关于ruby-on-rails - Rails 5 - 并发的大型视频上传和后台 FFMPEG 编码使服务器非常慢,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60792462/

相关文章:

FFmpeg 幻灯片 concat 仅输出最后一张图片

Java:跨平台.flv播放

ruby-on-rails - nokogiri 从 xml 到数组的多个元素

ruby-on-rails - docker 上的回形针无法上传图像?

ruby-on-rails - Rails/heroku 从 gem 迁移到 toolbelt

ruby-on-rails - 如何大规模更新 User 对象?

java - Maven 可以从私有(private) s3 存储桶引用父 POM 吗?

node.js - 使用 NodeJS+Express、aws-sdk 将文件直接流式传输到 s3

python - 将 S3 对象名称转换为 S3 对象 url (python)

FFMPEG 在我向其提供第一张图像后花费 6 秒来创建第一个视频帧?