在将文件上传到Google Cloud Storage后,我试图获取永久的(未签名的)下载URL。我可以使用file.createWriteStream()
获得签名的下载URL,但是file.createWriteStream()
不返回包含未签名的下载URL的UploadResponse
。 bucket.upload()
包括UploadResponse
,Get Download URL from file uploaded with Cloud Functions for Firebase有几个答案说明了如何从UploadResponse
获取未签名的下载URL。如何将代码中的file.createWriteStream()
更改为bucket.upload()
?这是我的代码:
const {Storage} = require('@google-cloud/storage');
const storage = new Storage({ projectId: 'my-app' });
const bucket = storage.bucket('my-app.appspot.com');
var file = bucket.file('Audio/' + longLanguage + '/' + pronunciation + '/' + wordFileType);
const config = {
action: 'read',
expires: '03-17-2025',
content_type: 'audio/mp3'
};
function oedPromise() {
return new Promise(function(resolve, reject) {
http.get(oedAudioURL, function(response) {
response.pipe(file.createWriteStream(options))
.on('error', function(error) {
console.error(error);
reject(error);
})
.on('finish', function() {
file.getSignedUrl(config, function(err, url) {
if (err) {
console.error(err);
return;
} else {
resolve(url);
}
});
});
});
});
}
我尝试了一下,但是没用:
function oedPromise() {
return new Promise(function(resolve, reject) {
http.get(oedAudioURL, function(response) {
bucket.upload(response, options)
.then(function(uploadResponse) {
console.log('Then do something with UploadResponse.');
})
.catch(error => console.error(error));
});
});
}
错误消息为Path must be a string.
,换句话说,response
是变量,但必须是字符串。
答案 0 :(得分:2)
我使用 Google Cloud text-to-speech API 来模拟您在做什么。获取文本以从文本文件创建音频文件。创建文件后,我使用 upload 方法将其添加到我的存储桶中,并使用 makePublic 方法获取其公共 URL。我还使用了 node.js 提供的 async/await feature 而不是函数链接(使用 then)来避免“没有这样的对象:...”错误,因为在文件完成上传到存储桶之前执行了 makePublic 方法.
// Imports the Google Cloud client library
const {Storage} = require('@google-cloud/storage');
// Creates a client using Application Default Credentials
const storage = new Storage();
// Imports the Google Cloud client library
const textToSpeech = require('@google-cloud/text-to-speech');
// Get the bucket
const myBucket = storage.bucket('my_bucket');
// Import other required libraries
const fs = require('fs');
const util = require('util');
// Create a client
const client = new textToSpeech.TextToSpeechClient();
// Create the variable to save the text to create the audio file
var text = "";
// Function that reads my_text.txt file (which contains the text that will be
// used to create my_audio.mp3) and saves its content in a variable.
function readFile() {
// This line opens the file as a readable stream
var readStream = fs.createReadStream('/home/usr/my_text.txt');
// Read and display the file data on console
readStream.on('data', function (data) {
text = data.toString();
});
// Execute the createAndUploadFile() fuction until the whole file is read
readStream.on('end', function (data) {
createAndUploadFile();
});
}
// Function that uploads the file to the bucket and generates it public URL.
async function createAndUploadFile() {
// Construct the request
const request = {
input: {text: text},
// Select the language and SSML voice gender (optional)
voice: {languageCode: 'en-US', ssmlGender: 'NEUTRAL'},
// select the type of audio encoding
audioConfig: {audioEncoding: 'MP3'},
};
// Performs the text-to-speech request
const [response] = await client.synthesizeSpeech(request);
// Write the binary audio content to a local file
const writeFile = util.promisify(fs.writeFile);
await writeFile('my_audio.mp3', response.audioContent, 'binary');
console.log('Audio content written to file: my_audio.mp3');
// Wait for the myBucket.upload() function to complete before moving on to the
// next line to execute it
let res = await myBucket.upload('/home/usr/my_audio.mp3');
// If there is an error, it is printed
if (res.err) {
console.log('error');
}
// If not, the makePublic() fuction is executed
else {
// Get the file in the bucket
let file = myBucket.file('my_audio.mp3');
file.makePublic();
}
}
readFile();
答案 1 :(得分:0)
bucket.upload()
是file.createWriteStream()
周围的便捷包装,它采用本地文件系统路径并将文件作为对象上传到存储桶中。
bucket.upload("path/to/local/file.ext", options)
.then(() => {
// upload has completed
});
要生成签名的URL,您需要从存储桶中获取文件对象:
const theFile = bucket.file('file_name');
文件名将是您本地文件的文件名,或者如果您在GCS上为该文件指定了备用远程名称options.destination
。
然后,使用File.getSignedUrl()
获取签名的URL:
bucket.upload("path/to/local/file.ext", options)
.then(() => {
const theFile = bucket.file('file.ext');
return theFile.getSignedURL(signedUrlOptions); // getSignedURL returns a Promise
})
.then((signedUrl) => {
// do something with the signedURL
});
请参阅:
Bucket.upload()
documentation
File.getSignedUrl()
documentation
答案 2 :(得分:0)
您可以使用makePublic方法使存储桶中的特定文件公开可读。
从文档中
const {Storage} = require('@google-cloud/storage');
const storage = new Storage();
// 'my-bucket' is your bucket's name
const myBucket = storage.bucket('my-bucket');
// 'my-file' is the path to your file inside your bucket
const file = myBucket.file('my-file');
file.makePublic(function(err, apiResponse) {});
//-
// If the callback is omitted, we'll return a Promise.
//-
file.makePublic().then(function(data) {
const apiResponse = data[0];
});
现在,URI http://storage.googleapis.com/[BUCKET_NAME]/[OBJECT_NAME]
是文件的公共链接,如here所述。
重点是,您只需要此最少的代码即可公开对象,例如使用Cloud Function。然后,您已经知道公共链接的方式了,可以直接在您的应用程序中使用它。