【平头哥RVB2601开发板试用体验】基于 HTTPClient 的云语音识别 3

本文介绍了使用RVB2601开发板实现云语音识别的过程,包括通过HTTPClient手动发送录音数据、codec录制音频、按键中断、监控任务和服务器端的nginx与PHP处理。项目源码已开源,通过按键启动录音,上传云端识别后返回结果。开发体验良好,YOC功能强大,适合物联网应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

作者 | 哈猪猪

前言

在文章2中,我们简单分析了 HTTPClient 组件的源码,发现其并不能实现“multipart/form-data”类型内容的 POST 请求。因此在本文中,我们将手动实现这一功能,并且最终完成整个云语音识别项目。以下为全部开发流程:

项目源码:https://github.com/ha-zhuzhu/ch2601_speech_recognizer

实现效果:请见演示视频

RVB2601

首先,我们结合之前所作的工作,重新梳理云语音识别项目的目标与思路。

目标:按下板载按钮,RVB2601 开始录音,上传云端语音识别后返回识别结果至串口。

思路:实现的程序流程与所需要的关键组件如下:

  • gpio_pin:设置按键中断。按下按钮后设置“开始录音标志位”为1。
  • rhino:注册监控任务。监控“开始录音标志位”,若为1则:
    1. codec:进行录音。
    2. HTTPClient :上传录音数据,接收并返回识别结果。
    3. 清空标志位

HTTPClient 发送录音数据

首先从最复杂的,手动发送音频数据开始。

借鉴另一个组件 http 的思路,先针对我们的应用场景设置好 boundary 和请求体的头部、尾部:

// 请求体格式
static const char *boundary = "----WebKitFormBoundarypNjgoVtFRlzPquKE";
#define MY_FORMAT_START "------WebKitFormBoundarypNjgoVtFRlzPquKE\r\nContent-Disposition: %s; name=\"%s\"; filename=\"%s\"\r\nContent-Type: %s\r\n\r\n"
#define MY_FORMAT_END "\r\n------WebKitFormBoundarypNjgoVtFRlzPquKE--\r\n"

由于我们的音频数据较大,且一次流程只发送一个文件,因此发送 POST 请求体时可以分三部分发送:头部、音频数据、尾部。所以在进行音频数据传输时,相比于原来的流程,我们要先设置“Content-Type”,接着基于模板制备请求体头部尾部,设置 Content-Length,并将 POST 相关变量统一存放在一个结构体中,方便进行 POST 请求时调用。以下是音频发送函数:

static void post_audio()
{
    http_client_config_t config = {
        .url = "http://upload.hazhuzhu.com/myasr.php",
        .method = HTTP_METHOD_POST,
        .event_handler = _http_event_handler,
    };

    http_client_handle_t client = http_client_init(&config);
    // 设置 Content-Type
    http_client_set_header(client, "Content-Type", "multipart/form-data; boundary=----WebKitFormBoundarypNjgoVtFRlzPquKE");

    const unsigned char *post_content = repeater_data_addr; // POST 请求体的内容为录音数据
    // 请求体格式相关变量
    const char *content_disposition = "form-data";
    const char *name = "file";
    const char *filename = "raw_recording";
    const char *content_type = "application/octet-stream";
    int boundary_len = strlen(boundary);

    // 制备请求体头部
    int post_start_len = strlen(MY_FORMAT_START) - 8 + strlen(content_disposition) + strlen(name) + strlen(filename) + strlen(content_type) + 1;
    char *post_start = (char *)malloc(post_start_len + 1);
    memset(post_start, 0, sizeof(post_start_len));
    snprintf(post_start, post_start_len, MY_FORMAT_START, content_disposition, name, filename, content_type);
    const char *post_end = MY_FORMA
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值