资讯详情

我给浏览器加了个语音搜索功能

1. 前言

随着物联网的发展,语音识别技术越来越受到重视。语音识别技术正在积极推动基于语音识别的人机交互,如语音拨号、语音邮件、语音输入甚至语音控制.虽然生物识别方法越来越多,但语音识别方法仍然是主流方法.与其它生物识别技术相比,语音识别技术不仅具有非接触、非侵入性、使用方便、不会丢失和忘记,不需要记忆和其他特征。

本文采用华为云提供的在线语音识别服务,为浏览器设计语音自动搜索功能,编程语言采用C ,采用软件框架QT浏览器内核采用设计QWebEngineView,在QT5.7以后,QT里就不支持webkit目前自带浏览器内核是QWebEngineView,只能使用MSVC编译编译,mingw使用浏览器可以单独下载webkit库,或使用COM组件调用IE浏览器,当前文章中使用的浏览器是QWebEngineView,编译器采用VS2017,32bit。

使用语音采集功能QT的QAudioInput实现类别,收集声卡PCM通过华为云的语音识别保存数据HTTP接口完成文本识别,然后通过浏览器搜索文本相关内容。

image-20220106190739135

点击界面 开始语音采集按钮,然后单击停止采集,然后调用华为云的语音识别界面进行语音识别,在下面的显示框上显示识别文本,然后完成浏览器的自动搜索。

2. 创建语音服务器

2.1 使用语音服务

登录华为云官网: https://www.huaweicloud.com/

选择产品-人工智能-语音交互服务-一句话识别。

短语音识别地址: https://www.huaweicloud.com/product/asr.html

通过API从不同音频源发送的音频流或音频文件调用不超过一分钟。适用于语音搜索、人机交互等语音交互识别场景。 支持免费试用。

每天免费试用500次。

2.2 HTTP接口使用介绍

文档地址: https://support.huaweicloud.com/api-sis/sis_03_0094.html

在线调试接口地址: https://apiexplorer.developer.huaweicloud.com/apiexplorer/doc?product=SIS&api=RecognizeShortAudio

本地音频采集的频率和频道数量必须与参数相匹配。

2.3 总结接口地址

请求地址: "https://{endpoint}/v1/{project_id}/asr/short-audio"  请求数据: { 
             "config": { 
                 "audio_format": "ulaw8k8bit",         "property": "chinese_8k_common",         "add_punc": "yes",         "digit_norm": "yes",         "need_word_info": "yes"     },     "data": "/ MgxAAUeHpMAUkQAANhuRAC..." }  头里要带: X-Auth-Token 参数 

在之前的截图中介绍了请求数据中的参数,data音频文件base64编码数据。

请求地址endpoint字段、project_id字段、还有X-Auth-Token任何访问华为云的字段API接口需要填写,获取方法见此: https://bbs.huaweicloud.com/blogs/317759 翻到2.3小节。

{ 
           "trace_id": "567e8537-a89c-13c3-a882-826321939651",   "result": { 
             "text": "欢迎使用语音云服务。",     "score": 0.9,     "word_info": [       { 
                 "start_time": 150, "end_time": 570, "word": "欢迎" }, { 
          "start_time": 570, "end_time": 990, "word": "使用" }, { 
          "start_time": 990, "end_time": 1380, "word": "语音" }, { 
          "start_time": 1380, "end_time": 1590, "word": "云" }, { 
          "start_time": 1590, "end_time": 2070, "word": "服务" } ] } } 

其中的text字段就是识别的文本数据。

3. 项目代码示例

下面列出核心的代码,主要是就是字符串拼接格式,拼接完发送http请求即可。

3.1 语音转文字请求代码

//语音转文本
void Widget::audio_to_text(QByteArray data)
{ 
        
    function_select=0;

    QString requestUrl;
    QNetworkRequest request;

    //存放文件的BASE64编码
    QString base64_Data;

    //设置请求地址
    QUrl url;

    //一句话识别的请求地址
    requestUrl = QString("https://sis-ext.%1.myhuaweicloud.com/v1/%2/asr/short-audio")
            .arg(SERVER_ID)
            .arg(PROJECT_ID);
    qDebug()<<"requestUrl:"<<requestUrl;
    
    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json"));

    //将图片进行Base64编码
    base64_Data = QString(data.toBase64());

    //设置token
    request.setRawHeader("X-Auth-Token",Token);

    //构造请求
    url.setUrl(requestUrl);
    request.setUrl(url);

   //设置采样率
   QString post_param=QString
              ("{"
                   "\"config\": {"
                       "\"audio_format\": \"%1\","
                       "\"property\": \"%2\","
                       "\"add_punc\": \"yes\","
                       "\"digit_norm\": \"yes\","
                       "\"need_word_info\": \"yes\""
                   "},"
                   "\"data\": \"%3\""
               "}").arg("pcm16k16bit").arg("chinese_16k_common").arg(base64_Data);

/* chinese_16k_common 支持采样率为16k的中文普通话语音识别。 pcm16k16bit 16k16bit单通道录音数据。 */
    //发送请求
    manager->post(request, post_param.toUtf8());
}

3.2 更新token代码

/* 功能: 获取token */
void Widget::GetToken()
{ 
        
    //表示获取token
    function_select=3;

    QString requestUrl;
    QNetworkRequest request;

    //设置请求地址
    QUrl url;

    //获取token请求地址
    requestUrl = QString("https://iam.%1.myhuaweicloud.com/v3/auth/tokens")
                 .arg(SERVER_ID);

    //自己创建的TCP服务器,测试用
    //requestUrl="http://10.0.0.6:8080";

    //设置数据提交格式
    request.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/json;charset=UTF-8"));

    //构造请求
    url.setUrl(requestUrl);

    request.setUrl(url);

    QString text =QString("{\"auth\":{\"identity\":{\"methods\":[\"password\"],\"password\":"
    "{\"user\":{\"domain\": {"
    "\"name\":\"%1\"},\"name\": \"%2\",\"password\": \"%3\"}}},"
    "\"scope\":{\"project\":{\"name\":\"%4\"}}}}")
            .arg(MAIN_USER)
            .arg(IAM_USER)
            .arg(IAM_PASSWORD)
            .arg(SERVER_ID);

    //发送请求
    manager->post(request, text.toUtf8());
}

3.3 华为云返回的结果处理

//解析反馈结果
void Widget::replyFinished(QNetworkReply *reply)
{ 
        
    QString displayInfo;
    int statusCode = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();

    //读取所有数据
    QByteArray replyData = reply->readAll();

    qDebug()<<"状态码:"<<statusCode;
    qDebug()<<"反馈的数据:"<<QString(replyData);

    //更新token
    if(function_select==3)
    { 
        
        displayInfo="token 更新失败.";
        //读取HTTP响应头的数据
        QList<QNetworkReply::RawHeaderPair> RawHeader=reply->rawHeaderPairs();
        qDebug()<<"HTTP响应头数量:"<<RawHeader.size();
        for(int i=0;i<RawHeader.size();i++)
        { 
        
            QString first=RawHeader.at(i).first;
            QString second=RawHeader.at(i).second;
            if(first=="X-Subject-Token")
            { 
        
                Token=second.toUtf8();
                displayInfo="token 更新成功.";

                //保存到文件
                SaveDataToFile(Token);
                break;
            }
        }
        qDebug()<<displayInfo;
        return;
    }

    //判断状态码
    if(200 != statusCode)
    { 
        
        //解析数据
        QJsonParseError json_error;
        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        { 
        
            //判断是否是对象,然后开始解析数据
            if(document.isObject())
            { 
        
                QString error_str="";
                QJsonObject obj = document.object();
                QString error_code;
                //解析错误代码
                if(obj.contains("error_code"))
                { 
        
                    error_code=obj.take("error_code").toString();
                    error_str+="错误代码:";
                    error_str+=error_code;
                    error_str+="\n";
                }
                if(obj.contains("error_msg"))
                { 
        
                    error_str+="错误消息:";
                    error_str+=obj.take("error_msg").toString();
                    error_str+="\n";
                }
                //显示错误代码
                qDebug()<<error_str;
            }
         }
        return;
    }

    //语音识别
    if(function_select==0)
    { 
        
        //解析数据
        QJsonParseError json_error;
        QJsonDocument document = QJsonDocument::fromJson(replyData, &json_error);
        if(json_error.error == QJsonParseError::NoError)
        { 
        
            //判断是否是对象,然后开始解析数据
            if(document.isObject())
            { 
        
                QString error_str="";
                QJsonObject obj = document.object();
                QString error_code;

                if(obj.contains("result"))
                { 
        
                    QJsonObject obj2=obj.take("result").toObject();
                    if(obj2.contains("text"))
                    { 
        
                        QString text=obj2.take("text").toString();
                        qDebug()<<"识别的文本:"<<text;
                        ui->lineEdit_text_display->setText(text);

                        //浏览器搜索
                        QString url="https://www.baidu.com/s?ie=UTF-8&wd="+text;

                        m_webView->load(QUrl(url));

                    }
                }
                //显示错误代码
                qDebug()<<error_str;
            }
         }
    }
}

标签: 横沥板对板连接器bk13c06夷陵板对板连接器bk13c06

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台