Firebase cloud function [ Error: memory limit exceeded. Function invocation was interrupted.] on youtube video upload
Firebase cloud function [ Error: memory limit exceeded. Function invocation was interrupted.] on youtube video upload
我正在尝试使用 firebase 云功能将视频上传到 youtube。
我需要的是当用户将视频上传到 firebase 云存储时,functions.storage.object().onFinalize 事件将被触发,在这种情况下,我将文件存储到一个临时位置并上传文件从临时位置到 youtube 到 youtube,上传后我删除了两个文件。
它适用于小文件。
但是,如果我上传一个大文件,则该功能会因显示此错误而终止
错误:超出内存限制。函数调用被中断。
上传视频的代码
var requestData = {
'params': {
'part': 'snippet,status'
},
'properties': {
'snippet.categoryId': '22',
'snippet.defaultLanguage': '',
'snippet.description': "docdata.shortDesc",
'snippet.tags[]': '',
'snippet.title': "docdata.title",
'status.embeddable': '',
'status.license': '',
'status.privacyStatus': 'public',
'status.publicStatsViewable': ''
}, 'mediaFilename': tempLocalFile
};
insertVideo(tempLocalFile, oauth2Client, requestData);
插入视频功能
function insertVideo( file, oauth2Client, requestData) {
return new Promise((resolve,reject)=>{
google.options({ auth: oauth2Client });
var parameters = removeEmptyParameters(requestData['params']);
parameters['auth'] = oauth2Client;
parameters['media'] = { body: fs.createReadStream(requestData['mediaFilename'])};
parameters['notifySubscribers'] = false;
parameters['resource'] = createResource(requestData['properties']);
console.log("INSERT >>> ");
let req = google.youtube('v3').videos.insert(parameters, (error, received)=> {
if (error) {
console.log("in error")
console.log(error);
try {
fs.unlinkSync(file);
} catch (err) {
console.log(err);
} finally{
// response.status(200).send({ error: error })
}
reject(error)
} else {
console.log("in else")
console.log(received.data)
fs.unlinkSync(file);
resolve();
}
});
})
}
创建临时本地文件的代码
bucket.file(filePath).createReadStream()
.on('error', (err)=> {
reject(err)
})
.on('response', (response)=> {
console.log(response)
})
.on('end', ()=> {
console.log("The file is fully downloaded");
resolve();
})
.pipe(fs.createWriteStream(tempLocalFile));
每个文件读写都由流处理,知道为什么会出现内存问题
Cloud Functions 中文件系统的唯一可写部分是 /tmp
目录。根据文档 here:
This is a local disk mount point known as a "tmpfs" volume in which
data written to the volume is stored in memory. Note that it will
consume memory resources provisioned for the function.
这就是您使用更大的文件达到内存限制的原因。
您的选择是:
- 为您的函数分配更多内存(目前最多 2 GB)
- 从可以写入文件系统的环境执行上传。例如,您的 Cloud Functions 可以调用 App Engine Flexible 服务来执行上传。
您还可以按照一系列步骤使用 resumable video upload:
- 您的 GCS-triggered 函数会在视频完成上传时触发。
- 该函数启动一个 resumable upload session,计算要上传的合理块,并将块定义插入到 pubsub 中,每个块的范围和 session id
- 您使用接收该消息的主题创建了一个新的 pubsub-triggered 函数,使用
range
header 从 GCS 下载块(未记录在 JSON API,但我已经报告了),并且 uploads the chunk to Youtube
我没试过,但这甚至可能允许从上传不同块的不同函数并行上传到 Youtube(这将大大提高性能,尽管文档建议块需要按顺序上传)。您可以从 GCS object 下载任意块,因此 GCS 端的并行化不是问题。
如果不允许并行上传,您可以在函数完成上传时插入一条新的 pubsub 消息,它是上传最后一个字节的块,因此函数的执行是有序的(同时它允许并行上传不同的视频).
这有点复杂,但允许您从小功能上传 arbitrary-sized 视频(Youtube 上当前最大限制为 128 GB)。
注意妥善处理故障(可能 re-inserting 块进入 pubsub 主题)。
最简单的快速修复是 increase function memory
对于 Firebase,docs 告诉您像这样设置函数内存:
exports.convertLargeFile = functions
.runWith({
timeoutSeconds: 300,
memory: '1GB',
})
.storage.object()
.onFinalize((object) => {
// Do some complicated things that take a lot of memory and time
});
内存的有效值为 128MB 256MB 512MB 1GB 2GB 4GB 8GB
但是,单独设置它对我不起作用。我还必须去 Google Cloud Platform Console functions list
然后单击要增加内存的函数的名称。这将带您进入编辑屏幕,您可以在其中进行更改和部署更改。这只是单击按钮和更改下拉值的问题。
完成后,您应该会在上述函数列表和 firebase 函数列表中看到更改 - https://console.firebase.google.com/u/0/project/YOUR_PROJECT/functions/list
现在你的函数应该可以工作了!来自 J-E-S-U-S 我主的爱。
我正在尝试使用 firebase 云功能将视频上传到 youtube。
我需要的是当用户将视频上传到 firebase 云存储时,functions.storage.object().onFinalize 事件将被触发,在这种情况下,我将文件存储到一个临时位置并上传文件从临时位置到 youtube 到 youtube,上传后我删除了两个文件。
它适用于小文件。
但是,如果我上传一个大文件,则该功能会因显示此错误而终止
错误:超出内存限制。函数调用被中断。
上传视频的代码
var requestData = {
'params': {
'part': 'snippet,status'
},
'properties': {
'snippet.categoryId': '22',
'snippet.defaultLanguage': '',
'snippet.description': "docdata.shortDesc",
'snippet.tags[]': '',
'snippet.title': "docdata.title",
'status.embeddable': '',
'status.license': '',
'status.privacyStatus': 'public',
'status.publicStatsViewable': ''
}, 'mediaFilename': tempLocalFile
};
insertVideo(tempLocalFile, oauth2Client, requestData);
插入视频功能
function insertVideo( file, oauth2Client, requestData) {
return new Promise((resolve,reject)=>{
google.options({ auth: oauth2Client });
var parameters = removeEmptyParameters(requestData['params']);
parameters['auth'] = oauth2Client;
parameters['media'] = { body: fs.createReadStream(requestData['mediaFilename'])};
parameters['notifySubscribers'] = false;
parameters['resource'] = createResource(requestData['properties']);
console.log("INSERT >>> ");
let req = google.youtube('v3').videos.insert(parameters, (error, received)=> {
if (error) {
console.log("in error")
console.log(error);
try {
fs.unlinkSync(file);
} catch (err) {
console.log(err);
} finally{
// response.status(200).send({ error: error })
}
reject(error)
} else {
console.log("in else")
console.log(received.data)
fs.unlinkSync(file);
resolve();
}
});
})
}
创建临时本地文件的代码
bucket.file(filePath).createReadStream()
.on('error', (err)=> {
reject(err)
})
.on('response', (response)=> {
console.log(response)
})
.on('end', ()=> {
console.log("The file is fully downloaded");
resolve();
})
.pipe(fs.createWriteStream(tempLocalFile));
每个文件读写都由流处理,知道为什么会出现内存问题
Cloud Functions 中文件系统的唯一可写部分是 /tmp
目录。根据文档 here:
This is a local disk mount point known as a "tmpfs" volume in which data written to the volume is stored in memory. Note that it will consume memory resources provisioned for the function.
这就是您使用更大的文件达到内存限制的原因。
您的选择是:
- 为您的函数分配更多内存(目前最多 2 GB)
- 从可以写入文件系统的环境执行上传。例如,您的 Cloud Functions 可以调用 App Engine Flexible 服务来执行上传。
您还可以按照一系列步骤使用 resumable video upload:
- 您的 GCS-triggered 函数会在视频完成上传时触发。
- 该函数启动一个 resumable upload session,计算要上传的合理块,并将块定义插入到 pubsub 中,每个块的范围和 session id
- 您使用接收该消息的主题创建了一个新的 pubsub-triggered 函数,使用
range
header 从 GCS 下载块(未记录在 JSON API,但我已经报告了),并且 uploads the chunk to Youtube
我没试过,但这甚至可能允许从上传不同块的不同函数并行上传到 Youtube(这将大大提高性能,尽管文档建议块需要按顺序上传)。您可以从 GCS object 下载任意块,因此 GCS 端的并行化不是问题。
如果不允许并行上传,您可以在函数完成上传时插入一条新的 pubsub 消息,它是上传最后一个字节的块,因此函数的执行是有序的(同时它允许并行上传不同的视频).
这有点复杂,但允许您从小功能上传 arbitrary-sized 视频(Youtube 上当前最大限制为 128 GB)。
注意妥善处理故障(可能 re-inserting 块进入 pubsub 主题)。
最简单的快速修复是 increase function memory
对于 Firebase,docs 告诉您像这样设置函数内存:
exports.convertLargeFile = functions
.runWith({
timeoutSeconds: 300,
memory: '1GB',
})
.storage.object()
.onFinalize((object) => {
// Do some complicated things that take a lot of memory and time
});
内存的有效值为 128MB 256MB 512MB 1GB 2GB 4GB 8GB
但是,单独设置它对我不起作用。我还必须去 Google Cloud Platform Console functions list
然后单击要增加内存的函数的名称。这将带您进入编辑屏幕,您可以在其中进行更改和部署更改。这只是单击按钮和更改下拉值的问题。
完成后,您应该会在上述函数列表和 firebase 函数列表中看到更改 - https://console.firebase.google.com/u/0/project/YOUR_PROJECT/functions/list
现在你的函数应该可以工作了!来自 J-E-S-U-S 我主的爱。