如何使用libcurl与谷歌语音API(什么是等效的——data-binary或——upload-file)

How to use libcurl with Google Speech API (what is the equivalent for --data-binary or --upload-file)?

本文关键字:data-binary upload-file 什么 libcurl 何使用 谷歌 语音 API      更新时间:2023-10-16

我已经知道如何在命令行上做到这一点:

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.html

data-binary在本例中是不相关的,因为您没有对在回调中传递数据的文件做任何操作,所以它将按原样发布。