首页 > 解决方案 > 为什么在谷歌云函数上启动的ffmpeg会抛出“错误:输出流错误:超出最大调用堆栈大小”?

问题描述

我正在尝试使用在谷歌云功能上运行的 ffmpeg 处理视频文件。视频文件从 google 文件存储中下载,由 fluent-ffmpeg 在流中处理并流式传输到新的 google 存储文件。它适用于较小的文件,但在较大的文件上会引发“输出流错误:超出最大调用堆栈大小”。

我尝试在普通电脑上运行代码,即使文件较大,我也没有遇到此错误。

这些是我部署该功能的参数

gcloud functions deploy $FUNCTION_NAME --runtime nodejs8 --trigger-http --timeout=180 --memory 256

这是处理视频的代码

function cutVideo({videoUrl, startTime, duration, dist}) {
    return ffmpeg(videoUrl)
    .outputOptions('-movflags frag_keyframe+empty_moov')
    .videoCodec('copy')
    .audioCodec('copy')
    .format('mp4')
    .setStartTime(startTime)
    .setDuration(duration);
}

const sectionStream = cutVideo({
    videoUrl,
    startTime,
    duration,
    dist: tempFilePath,
});

const outputStream = bucket.file(sectionPath)
.createWriteStream({
    metadata: {
        contentType: config.contentType,
    },
    public: true,
});

实际错误堆栈如下所示

  Error: Output stream error: Maximum call stack size exceeded
                                                                  at Pumpify.<anonymous> (/srv/node_modules/fluent-ffmpeg/lib/processor.js:498:34)
                                                                  at emitOne (events.js:121:20)
                                                                  at Pumpify.emit (events.js:211:7)
                                                                  at Pumpify.Duplexify._destroy (/srv/node_modules/duplexify/index.js:191:15)
                                                                  at /srv/node_modules/duplexify/index.js:182:10
                                                                  at _combinedTickCallback (internal/process/next_tick.js:132:7)
                                                                  at process._tickDomainCallback (internal/process/next_tick.js:219:9)
  RangeError: Maximum call stack size exceeded
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:28:31)
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:37:30)
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:37:30)
                                                                  at value.map.v (/srv/node_modules/@google-cloud/projectify/build/src/index.js:30:32)
                                                                  at Array.map (<anonymous>)
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:30:23)
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:37:30)
                                                                  at replaceProjectIdToken (/srv/node_modules/@google-cloud/projectify/build/src/index.js:37:30)
                                                                  at value.map.v (/srv/node_modules/@google-cloud/projectify/build/src/index.js:30:32)
                                                                  at Array.map (<anonymous>)

什么可能导致谷歌云功能出现此错误?

标签: node.jsffmpeggoogle-cloud-functionsfluent-ffmpeg

解决方案


除了基于内存/cpu 的限制之外,由于现实中的超时,这些长时间运行的进程不可能在 Google Cloud Functions 中适用。

实现这一点的唯一方法是使用“Google App Engine Flex”。它本质上具有最长的可用超时机制,可以在 app.yaml/gunicorn(或您打算使用的任何网络服务器)和实际 GAE 超时两个级别中设置。

其余服务 GAE 标准或 Google Cloud Functions,它们有一个严格的超时时间,您不能将其更改为超过 10 秒到 30 分钟。这些超时不足以用于 ffmpeg 和转码目的。


推荐阅读