Как использовать libcurl с Google Speech API (что эквивалентно —data-binary или —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 (или другие параметры).

Вот что у меня так далеко. Разрывается с нарушением доступа.

#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;
}

1

Решение

Вам необходимо использовать обратный вызов для загрузки файла данных. Вы можете найти пример здесь:

http://curl.haxx.se/libcurl/c/post-callback.html

data-binary не имеет значения в этом примере, потому что вы ничего не делаете с файлом, передающим данные в обратном вызове, поэтому он будет опубликован как есть.

1

Другие решения


По вопросам рекламы [email protected]