Я понял, как это сделать в командной строке:
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 (или другие параметры).
Вот что у меня так далеко. Разрывается с нарушением доступа.
#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;
}
Вам необходимо использовать обратный вызов для загрузки файла данных. Вы можете найти пример здесь:
http://curl.haxx.se/libcurl/c/post-callback.html
data-binary не имеет значения в этом примере, потому что вы ничего не делаете с файлом, передающим данные в обратном вызове, поэтому он будет опубликован как есть.