如何使用libcurl与谷歌语音API(什么是等效的——data-binary或——upload-file)
How to use libcurl with Google Speech API (what is the equivalent for --data-binary or --upload-file)?
我已经知道如何在命令行上做到这一点:
curl -X POST --upload-file audio/test.wav
--header "Content-Type: audio/l16; rate=44100;"
"https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=MYKEY"
或
curl -X POST --data-binary @audio/test.wav
--header "Content-Type: audio/l16; rate=44100;"
"https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=MYKEY"
其中'MYKEY'是我的开发人员密钥。
如何在c++中使用libcurl实现此功能?我已经搜索了几个小时,但无法弄清楚如何正确地将我的音频文件附加到使用CURLOPT_POSTFIELDS(或其他参数)的post请求。
这是我到目前为止所知道的。
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
int main(void)
{
CURL *curl; // curl handle
CURLcode res;
curl = curl_easy_init();
if (curl)
{
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Content-Type: audio/l16; rate=44100");
std::cout << curl_easy_setopt(curl, CURLOPT_POSTFIELDS, "file=@audio/test.wav") << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, 177644) << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk) << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_CAINFO, "ca-bundle.crt") << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=MYKEY") << std::endl;
res = curl_easy_perform(curl);
std::cout << res;
curl_easy_cleanup(curl);
}
return 0;
}
我不认为"file=@audio/test.wav"是正确的,我在PHP文档中看到了curl的语法,决定在libcurl中尝试一下。
我真的很不明白,如果你能帮忙的话,我将不胜感激。
编辑:这是一个工作的例子[pastebin]。我花了很长时间才弄明白。它使用http://curl.haxx.se/libcurl/c/post-callback.html中给出的示例函数,因此它不是最终解决方案,但是一个很好的起点。确保将API密钥放入语音API链接中。
#include <iostream>
#include <stdio.h>
#include <curl/curl.h>
#include <direct.h>
#include <string>
struct WriteThis {
const char *readptr;
long sizeleft;
};
// callback function from http://curl.haxx.se/libcurl/c/post-callback.html
static size_t read_callback(void *ptr, size_t size, size_t nmemb, void *userp)
{
struct WriteThis *pooh = (struct WriteThis *)userp;
if (size*nmemb < 1)
return 0;
if (pooh->sizeleft) {
*(char *)ptr = pooh->readptr[0]; /* copy one single byte */
pooh->readptr++; /* advance pointer */
pooh->sizeleft--; /* less data left */
return 1; /* we return 1 byte at a time! */
}
return 0; /* no more data left to deliver */
}
int main(void)
{
CURL *curl; // curl handle
CURLcode res;
curl = curl_easy_init();
if (curl)
{
FILE *file;
errno_t err = fopen_s(&file, "testaudio.wav", "r");
fseek(file, 0, SEEK_END);
int fileSize = ftell(file);
fseek(file, 0, SEEK_SET);
std::cout << "file open status: " << err << std::endl;
std::cout << "file " << fileSize << std::endl;
struct curl_slist *chunk = NULL;
chunk = curl_slist_append(chunk, "Content-Type: audio/l16; rate=44100");
char *audioData = (char*)malloc(fileSize);
struct WriteThis pooh;
fread(audioData, fileSize, 1, file);
fclose(file);
pooh.readptr = audioData;
pooh.sizeleft = fileSize;
std::string sizeHeader = "Content-Length: ";
sizeHeader += std::to_string(fileSize);
chunk = curl_slist_append(chunk, sizeHeader.c_str());
std::cout << curl_easy_setopt(curl, CURLOPT_POST, 1L) << std::endl;
curl_easy_setopt(curl, CURLOPT_READFUNCTION, read_callback);
curl_easy_setopt(curl, CURLOPT_READDATA, &pooh);
curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
std::cout << curl_easy_setopt(curl, CURLOPT_HTTPHEADER, chunk) << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_CAINFO, "ca-bundle.crt") << std::endl;
std::cout << curl_easy_setopt(curl, CURLOPT_URL, "https://www.google.com/speech-api/v2/recognize?output=json&lang=en-us&key=yourkey") << std::endl;
res = curl_easy_perform(curl);
std::cout << res;
curl_easy_cleanup(curl);
}
return 0;
}
需要使用callback来上传数据文件。您可以在这里找到示例:
http://curl.haxx.se/libcurl/c/post-callback.htmldata-binary在本例中是不相关的,因为您没有对在回调中传递数据的文件做任何操作,所以它将按原样发布。
相关文章:
- 如何处理 c++ 中类实现中的"invalid use of non-static data member"?
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 收到错误"invalid use of non-static data member 'stu::n' "
- LeetCode 1011.Binary Search,C++和Python的想法相同,但输出不同
- C++ 初始化 .data 部分中的变量
- 模式"allocate memory or use existing data"
- boost::asio data owning `ConstBufferSequence`
- Python to C++ Data structure API
- 当初始值设定项是基类名时'initializer does not name a non-static data member or base class'错误
- protobuf C++ SQLite handle blob data
- 错误:字段'dateOfBirth'的类型不完整'Poco::Data::Date'
- 为什么构造函数 Message(const T&data) 与 Message(T&& data) 冲突,当 T = int&时?
- "thread-safe data"与"thread-safe code/functions"的区别
- 如何找到目标文件 *.o 的 ram rom 使用情况(.bss .text .rodata .data)?
- 这在C++ "It does not own the underlying data, and so is cheap to copy or assign"中意味着什么
- 如何使用curl c ++源代码发布wav文件数据,如何使用c ++使用--data-binary?
- Java Thrift Client and Binary data
- 代码不适用于"Modifying a data in a Binary file"
- 在 c++ 中使用 libcurl 设置 --data-binary
- 如何使用libcurl与谷歌语音API(什么是等效的——data-binary或——upload-file)