I want use Azure's STT REST API for my react-native app with recorded audio.
But I've try to search how to pass the wav file but always response "No audio data received" or other error response.
I'm very sure the subscribe key is working cause when I use get token it responses 200.
And the wav file is not the problem,either.Cause when I download the file to my computer then upload it in Azure STT's homepage,it responses the correct answer.
The last,I've tried to figure out how to pass it in right form,but every things are for website.
Here's my code
`
const file = new ReactNativeFile({
uri:
`file://${audioFile}`,
type: 'audio/wav',
name: 'ABCS160101e1a011b160a3e169d7b0.wav',
});
let form = new formData();
const headers = {
'Ocp-Apim-Subscription-Key': 'MyKey',
'Content-type': 'audio/wav; codecs=audio/pcm;samplerate=16000',
Accept: 'application/json',
};
const url = `https://eastasia.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US`;
await form.append('audio', file);
console.log('before');
let response = await axios.post(url, form, {
headers: headers,
});
console.log('after');
console.log('result', JSON.stringify(response));
} catch (err) {
getlog.cw('err23', err);
return err;
}
};`
and Here's My recording function in another place,it's working for play.
import AudioRecord from 'react-native-audio-record';
const options = {
sampleRate: 16000, // default 44100
bitsPerSample: 16, // 8 or 16, default 16,
wavFile: "ABCS160101e1a011b160a3e169d7b0.wav"
};
const toggleRecord = async () => {
if (isRecording) {
const audioFile = await AudioRecord.stop();
setIsRecording(false);
// reloadRecorder();
} else {
setIsRecording(true);
AudioRecord.init(options);
AudioRecord.start();
}
};
Firstly, write
let form = new FormData();
Instead of
let form = new formData();
Secondly, I suppose you audioFile looks like this - file://.... So you dont have to write like this uri: file://${audioFile} ..You can simply write
uri:audioFile
SO final implementation would be
let form = new FormData();
form.append('audio', {
uri: audioFile,
type: 'audio/wav',
name: 'ABCS160101e1a011b160a3e169d7b0.wav',
});
const headers = {
'Ocp-Apim-Subscription-Key': 'MyKey',
'Content-type': 'audio/wav; codecs=audio/pcm;samplerate=16000',
Accept: 'application/json',
};
const url = `https://eastasia.stt.speech.microsoft.com/speech/recognition/conversation/cognitiveservices/v1?language=en-US`;
console.log('before');
let response = await axios.post(url, form, {
headers: headers,
});
console.log('after');
console.log('result', JSON.stringify(response));
Related
I'm using NestJS, there is axios module inside it. I read that Telegram accepts only multipart/form-data for files, so I use form-data package. I have only 400 errors, that don't represent anything.
I don't want to use packages like telegraf (it's awesome, I know) for this simple usecase.
const config: AxiosRequestConfig = {
headers: { 'Content-Type': 'multipart/form-data' },
};
const file = await readFile(path);
const body = new FormData();
body.append('chat_id', this.chatId.toString());
body.append('document', file, { filename: 'document.pdf' });
try {
const res = await firstValueFrom(this.http.post(`${this.tgURL}/sendDocument`, body, config));
} catch (e) {
console.log(e.message);
}
Telegram needs boundary in header.
So:
const config: AxiosRequestConfig = {
headers: { 'Content-Type': `multipart/form-data; boundary=${body.getBoundary()}` },
};
i'm trying to upload my files as form-data, after i've created a scene. But I receive always the error "Specified Photoscene ID doesn't exist in the database" (which were created directly before).
My upload function:
// Upload Files
async function uploadFiles(access_Token, photoSceneId, files) {
try {
const params = new URLSearchParams({
'photosceneid': photoSceneId,
'type': 'image',
'file': files
})
const headers = Object.assign({
Authorization: 'Bearer ' + access_Token,
'Content-Type': 'multipart/form-data' },
files.getHeaders()
)
let resp = await axios({
method: 'POST',
url: 'https://developer.api.autodesk.com/photo-to-3d/v1/file',
headers: headers,
data: params
})
let data = resp.data;
return data;
} catch (e) {
console.log(e);
}
};
I've also tried a few varaints, e.g. adding the photosceneId to the form data (form.append(..), but doesn't works either.
Any helpful suggestion are appreciated. Thx in advance.
There might be two problems here.
First, I am not sure of it, as I don't have experience of URLSearchParams as a "packer" for POST requests. This might be the reason why you get "Specified Photoscene ID doesn't exist in the database" error - perhaps the way the data are serialized using URLSearchParams is not compatible.
The second problem, I am sure of it, is regarding the way you submit the files.
According to documentation, you have to pass the files one by one, like
"file[0]=http://www.autodesk.com/_MG_9026.jpg" \
"file[1]=http://www.autodesk.com/_MG_9027.jpg"
and not just passing an array to the "file" field.
Having this said, try this approach:
var axios = require('axios');
var FormData = require('form-data');
var fs = require('fs');
var data = new FormData();
var TOKEN = 'some TOKEN';
const photoSceneID = 'some_photoscene_id';
data.append('photosceneid', photoSceneID);
data.append('type', 'image');
data.append('file[0]', fs.createReadStream('/C:/TEMP/Example/DSC_5427.JPG'));
data.append('file[1]', fs.createReadStream('/C:/TEMP/Example/DSC_5428.JPG'));
data.append('file[2]', fs.createReadStream('... and so on ...'));
var config = {
method: 'post',
url: 'https://developer.api.autodesk.com/photo-to-3d/v1/file',
headers: {
'Content-Type': 'application/x-www-form-urlencoded',
'Authorization': 'Bearer ' + TOKEN,
},
data : data
};
axios(config)
.then(function (response) {
console.log(JSON.stringify(response.data));
})
.catch(function (error) {
console.log(error);
});
Also, I always recommend instead of jumping right into the code, to check first the workflow using apps like Postman or Insomnia and then, after you validated the workflow (created the photoscene, all images were properly uploaded and so on), you can translate this into the code.
At the end of this blogpost you will find the link to alrady created Postman collection, but I highly recommend building your own collection, as part of the learning step.
This is the solution that worked for me. Please note that the upload should be limited by a maximum of 20 files per call.
// Upload Files
async function uploadFiles(access_Token, photoSceneId) {
try {
let dataPath = path.join(__dirname, '../../data')
let files = fs.readdirSync(dataPath)
var data = new FormData();
data.append('photosceneid', photoSceneId)
data.append('type', 'image')
for(let i=0; i < files.length; i++) {
let filePath = path.join(dataPath, files[i])
let fileName = 'file[' + i + ']'
data.append(fileName, fs.createReadStream(filePath))
}
const headers = Object.assign({
Authorization: 'Bearer ' + access_Token,
'Content-Type': 'multipart/form-data;boundary=' + data.getBoundary()},
data.getHeaders()
)
let resp = await axios({
method: 'POST',
url: 'https://developer.api.autodesk.com/photo-to-3d/v1/file',
headers: headers,
maxContentLength: Infinity,
maxBodyLength: Infinity,
data: data
})
let dataResp = resp.data;
return dataResp;
} catch (e) {
console.log(e);
}
};
I have a code as shown below that uploads files from the browser and saves in the server, once it has been saved to the server, I want the server to connect to the Pinata API so the file can also be saved to the IPFS node.
let data = new FormData();
const fileBuffer = Buffer.from(`./public/files/${fileName}`, 'utf-8');
data.append('file', fileBuffer, `${fileName}`);
axios.post('https://api.pinata.cloud/pinning/pinJSONToIPFS',
data,
{
headers: {
'Content-Type': `multipart/form-data; boundary= ${data._boundary}`,
'pinata_api_key': pinataApiKey,
'pinata_secret_api_key': pinataSecretApiKey
}
}
).then(function (response) {
console.log("FILE UPLOADED TO IPFS NODE", fileName);
console.log(response);
}).catch(function (error) {
console.log("FILE WASNT UPLOADED TO IPFS NODE", fileName);
console.log(error);
});
The issue i'm having is that after creating a buffer of my file and wrapping it in a formdata, the pinata API returns an error :
data: {
error: 'This API endpoint requires valid JSON, and a JSON content-type'
}
If i convert the data to string like JSON.stringify(data) and change the content-type to application/json, the file buffer will be uploaded successfully as string.
I hope explained it well to get a solution. Thanks.
It looks like you're attempting to upload a file to the pinJSONToIPFS endpoint, which is intended to purely be used for JSON that is passed in via a request body.
In your situation I would recommend using Pinata's pinFileToIPFS endpoint
Here's some example code based on their documentation that may be of help:
//imports needed for this function
const axios = require('axios');
const fs = require('fs');
const FormData = require('form-data');
export const pinFileToIPFS = (pinataApiKey, pinataSecretApiKey) => {
const url = `https://api.pinata.cloud/pinning/pinFileToIPFS`;
//we gather a local file for this example, but any valid readStream source will work here.
let data = new FormData();
data.append('file', fs.createReadStream('./yourfile.png'));
return axios.post(url,
data,
{
maxContentLength: 'Infinity', //this is needed to prevent axios from erroring out with large files
headers: {
'Content-Type': `multipart/form-data; boundary=${data._boundary}`,
'pinata_api_key': pinataApiKey,
'pinata_secret_api_key': pinataSecretApiKey
}
}
).then(function (response) {
//handle response here
}).catch(function (error) {
//handle error here
});
};
The proper code to pin any file to IPFS is as below.
Apparently, even Pinata support staff didn't know this.
You need to set an object with the property name filepath as your last parameter. The name doesn't matter, it can be a duplicate, it can be the same as others, or it can be unique.
const url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
const fileContents = Buffer.from(bytes);
const data = new FormData();
data.append("file", fileContents, {filepath: "anyname"});
const result = await axios
.post(url, data, {
maxContentLength: -1,
headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`,
"pinata_api_key": userApiKey,
"pinata_secret_api_key": userApiSecret,
"path": "somename"
}
});
Code to upload a file on IPFS using Pinata.
There are two methods available to upload files/images on Pinata. One is with Pinata SDK and the second is the pinFileToIPFS endpoint.
If you are uploading files from Next.js then you cannot convert your image into binary using fs.createReadStream or Buffer.from. These packages support the Node side. So if you want to upload the file with Next.js on Pinata then you can use this code.
// convert file into binary
const data = new FormData();
data.append("title", file.name);
data.append("file", file);
const url = "https://api.pinata.cloud/pinning/pinFileToIPFS";
// pass binary data into post request
const result = await axios.post(url, data, {
maxContentLength: -1,
headers: {
"Content-Type": `multipart/form-data; boundary=${data._boundary}`,
pinata_api_key: "your_pinata_key",
pinata_secret_api_key:
"your_pinata_secret",
path: "somename",
},
});
console.log("RESULT", result);
this will upload a file to ipfs under the path ipfs://{cid}/images/{fileId}
const PINATA_BASE_URL = "https://api.pinata.cloud";
const PINATA_PIN_URI = "/pinning/pinFileToIPFS";
const fileExt = file.type.split("/")[1];
let nftId = 1
// creates a 64byte string '0000...0001' to follow ERC-1155 standard
const paddedId = createPaddedHex(nftId);
const ipfsFileId = `${paddedId}.${fileExt}`;
const ipfsImageFilePath = `/images/${ipfsFileId}`;
const fileUploadData = new FormData();
// this uploads the file and renames the uploaded file to the path created above
fileUploadData.append("file", file, ipfsImageFilePath);
fileUploadData.append(
"pinataOptions",
'{"cidVersion": 1, "wrapWithDirectory": true}'
);
fileUploadData.append(
"pinataMetadata",
`{"name": "${ipfsImageFilePath}", "keyvalues": {"company": "Pinata"}}`
);
const pinataUploadRes = await axios.post(
PINATA_BASE_URL + PINATA_PIN_URI,
fileUploadData,
{
headers: {
Authorization: `Bearer ${PINATA_JWT}`,
},
}
);
const ipfsCID = pinataUploadRes.data.IpfsHash;
I am trying to send post request to backend containing base64url encoded value of my image. When I send request with any random string, the request is received at backend but when I try to do same thing using encoded value, it responds me back with
request failed with status code 500
My code for the request is:
const uploadFileHandler = async (e) => {
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
reader.onloadend = () => {
setPreviewSource(reader.result);
uploadtobackend(reader.result);
};
const uploadtobackend = async (filedata) => {
try {
const config = {
headers: {
'Content-Type': 'application/json',
},
};
console.log(config);
console.log(filedata);
const { data } = await axios.post(
`/api/uploads`,
{
data: filedata,
},
config,
);
setImages(data);
setUploading(false);
} catch (error) {
console.log(error);
setUploading(false);
}
};
};
Here filedata is the encoded value and it is displayed if I console it.
Instead of
data: filedata
If I send
data: "some random string"
then request reaches backend otherwise not.
You nedd to send your file by wrapping in FormData.
You can do something like
const fd = new FormData()
// data you want to send other than file
fd.append('payload',JSON.stringify(payload))
fd.append('file',file) // file you want to send to node backend
Now in your backed you can get this file using req.file
Probably you need to use JSON.stringify() here are some example of use
const { data } = await axios.post(
`/api/uploads`,
{
data: new Buffer(JSON.stringify(filedata)).toString("base64")
},
config
)
I am uploading a video file to my s3 bucket using a presigned URL using the following code
function postsignedURL(req) {
return new Promise(function (resolve, reject) {
const params = {
Bucket: 'bucket1',
Expires: 60 * 60, // in seconds,
Fields: {
key: req,
'Content-Type': 'video/'
},
Conditions: [
['content-length-range', 300, 4000e+7],
{ 'Content-Type': 'video/' },
["starts-with", "$Content-Type", "video/"]
]
}
s3.createPresignedPost(params, (err, data) => {
if (err) {
reject(err)
} else {
resolve(data);
}
})
})
}
I am able to upload the file correctly and I can even download it using the following code in
const video = await readObjectSignedUrl(key)
console.log(video, " video ");
This one returns a presigned url. I can download the video using fetch method below
const objectResult = await fetchS3Object(video);
const bufferType = Buffer.from(objectResult);
const fileTypeResult = await fileType.fromBuffer(bufferTy[e);
console.log(fileTypeResult )
The result of fileTypeResult is the following which is correct
{ ext: 'mov', mime: 'video/quicktime' }
The code for the fetchS3Object is the following
async function fetchS3Object(key) {
console.log(key," KEY ")
const result = await fetch(key, {
method: 'GET',
mode: "cors",
headers: {
'Access-Control-Allow-Origin': '*',
}
})
const response = await result.text()
return response
}
When i print the objectResult variable it is some gibberish.
I am trying to write the objectResult to file using writeFileSync method.
fs.writeFileSync('/tmp/file', objectResult);
The file is written correctly in the specified location, but the video file is corrupted. When I try to play it, it is not working.
Is there is a reason why the written file is corrupted
I have Managed to solve the problem. Here is the issue. The problem arise from the fact that the original uploaded file which is a video had an encoding of
windows-1252,
However the fetch method return a binary which is encoded with
UTF-8.
As a result when you try to use writeFileSync the output is a corrupted file.
To solve this problem this what has to be done. The fetchS3Object function has to be changed to the following
async function fetchS3Object(key) {
console.log(key," KEY ")
const result = await fetch(key, {
method: 'GET',
mode: "cors",
headers: {
'Access-Control-Allow-Origin': '*',
}
})
const response = await result.arrayBuffer();
return response
}
then
const objectResult = await fetchS3Object(video);
const bufferType = Buffer.from(objectResult);
fs.writeFileSync('/tmp/file', bufferType);