node.js - Google App Engine - 上传到存储桶后访问文件
问题描述
我已经使用我的谷歌应用引擎后端将文件上传到我的存储桶,但现在我无法访问该文件以传入 ffmpeg。我从 try-catch 收到此错误消息:“输入文件不存在”。我可以看到文件已上传,因为我检查了存储桶下的开发人员控制台。我正在使用谷歌提供的样板代码,但添加了 ffmpeg 进行测试。我正在尝试使用访问上传文件的路径,但它不正确,尽管我得到了 bucket.name 值和 blob.name 值。我为此使用“flex”环境。
const originalFilePath = `gs://${bucket.name}/${blob.name}`;
这是完整的代码:
const process = require('process'); // Required to mock environment variables
const express = require('express');
const helpers = require('./helpers/index');
const Multer = require('multer');
const bodyParser = require('body-parser');
const ffmpeg = require("ffmpeg"); //https://www.npmjs.com/package/ffmpeg
const {Storage} = require('@google-cloud/storage');
// Instantiate a storage client
const storage = new Storage();
const app = express();
app.set('view engine', 'pug');
app.use(bodyParser.json());
// Multer is required to process file uploads and make them available via
// req.files.
const multer = Multer({
storage: Multer.memoryStorage(),
limits: {
fileSize: 5 * 1024 * 1024, // no larger than 5mb, you can change as needed.
},
});
// A bucket is a container for objects (files).
const bucket = storage.bucket(process.env.GCLOUD_STORAGE_BUCKET);
// Display a form for uploading files.
app.get('/', (req, res) => {
res.render('form.pug');
});
// Process the file upload and upload to Google Cloud Storage.
app.post('/upload', multer.single('file'), (req, res, next) => {
if (!req.file) {
res.status(400).send('No file uploaded.');
return;
}
// Create a new blob in the bucket and upload the file data.
const blob = bucket.file(req.file.originalname);
const blobStream = blob.createWriteStream({
resumable: false,
});
blobStream.on('error', err => {
next(err);
});
blobStream.on('finish', () => {
const audioFile = helpers.replaceAllExceptNumbersAndLetters(new Date());
// this path is incorrect but I cannot find correct way to do it
const originalFilePath = `gs://${bucket.name}/${blob.name}`;
const filePathOutput = `gs://${bucket.name}/${audioFile}.mp3`;
try {
const process = new ffmpeg(originalFilePath);
process.then(function (video) {
// Callback mode
video.fnExtractSoundToMP3(filePathOutput, (error, file) => {
if (!error)
res.send(`audio file: ${file}`);
});
}, (error) => {
res.send(`process error: ${error}`);
});
} catch (e) {
res.send(`try catch error: ${JSON.stringify(e)} | bucket: ${JSON.stringify(bucket)} |
blob: : ${JSON.stringify(blob)}`);
}
});
blobStream.end(req.file.buffer);
});
const PORT = process.env.PORT || 8080;
app.listen(PORT, () => {
console.log(`App listening on port ${PORT}`);
console.log('Press Ctrl+C to quit.');
});
module.exports = app;
解决方案
我使用评论中的信息创建了这个社区维基。
此存储库显示所需的 npm 包
const functions = require('firebase-functions');
const { Storage } = 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');
以及如何正确构建存储桶中文件的路径以将其传递给ffmpeg。
// Get the file name.
const fileName = path.basename(filePath);
// Exit if the audio is already converted.
if (fileName.endsWith('_output.flac')) {
functions.logger.log('Already a converted audio.');
return null;
}
// 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);
await bucket.file(filePath).download({destination: tempFilePath});
functions.logger.log('Audio downloaded locally to', tempFilePath);
// Convert the audio to mono channel using FFMPEG.
let command = ffmpeg(tempFilePath)
.setFfmpegPath(ffmpeg_static)
.audioChannels(1)
.audioFrequency(16000)
.format('flac')
.output(targetTempFilePath);
await promisifyCommand(command);
functions.logger.log('Output audio created at', targetTempFilePath);
这另一篇文章展示了如何替换 ffmpeg_static.path 安装“ffmpeg-installer/ffmpeg”,以及如何设置正确的路径
const ffmpegPath = require('@ffmpeg-installer/ffmpeg').path;
const ffmpeg = require('fluent-ffmpeg');
let command = ffmpeg(tempFilePath)
.setFfmpegPath(ffmpegPath)
.audioChannels(1)
.audioFrequency(16000)
.format('flac')
.output(targetTempFilePath);
推荐阅读
- python - 在python中将单个函数委托给客户端服务器
- vb.net - 当我在 DataGrdiView 中添加一行时,我得到“连接没有关闭。连接的当前状态为打开”
- reactjs - React-JSS 与 material-ui 和服务器端渲染
- python - python中具有大量数字的指数函数
- python - 从源代码文件匹配正则表达式并保存到列表/数据框
- python - 如果在电子邮件主题中找到多个部分字符串,则将电子邮件移至文件夹
- python - 如何在数据框中添加以下自定义列?
- apache-spark - Delta Lake 增量清单文件生成
- python - django 返回 NoReverseMatch 但它实际上得到了值
- javascript - 用光标悬停时更改背景颜色