betway必威-betway必威官方网站
做最好的网站

betway必威官方网站:data数据上传,微信小程序语

这里介绍用AFN上传语音文件到服务端

项目需求,需要使用讯飞的语音识别接口,将微信小程序上传的录音文件识别成文字返回

Http/2虽然推出已经不短了,但目前整体的使用率并不高,对应的支持库也并不理想,目前主要的支持库可以参考:https://github.com/http2/http2-spec/wiki/Implementations

语音转NSData

首先去讯飞开放平台中申请开通语音识别功能

针对也Python,目前可选的库好像只有Hyper(http://hyper.readthedocs.io/en/latest/)。Hyper在官网当中声称对Requests有很好的支持,可以将Hyper集成到Request中,完成Requests对Http/2的支持,

NSData *voiceData = [message valueForKey:@"wavAudioData"];

betway必威官方网站 1

betway必威官方网站 2

代码:

在这里面下载sdk,然后解压,注意appid与sdk是关联的,appid在初始化接口时候需要

requests集成hyper

//kHostURL为开发者公司的APP对应的主域名,比如http://xxx.yyy.cnAFHTTPRequestOperationManager *manager = [[AFHTTPRequestOperationManager alloc]initWithBaseURL:[NSURL URLWithString:kHostURL]];manager.requestSerializer.timeoutInterval = 100;NSMutableDictionary *paras = [[NSMutableDictionary alloc]init];[parassetValue:self.msgType forKey:@"msgType"];//以file的形式上传,这里的key很重要"accessory",这个是和服务器端对应的,千万不能乱写,一定要看接口文档,不然会上传失败[paras setValue:(__bridge id)((__bridge FILE*)(voiceData))forKey:@"accessory"];[paras setValue:[BLLUser getPushToken]forKey:@"senderPushToken"];[paras setValue:self.receiverPushToken forKey:@"receiverPushToken"];[paras setObject:[Base getKey]forKey:@"ukey"];AFHTTPRequestOperation *operation = [manager POST:kBLLUrl_Chat_Chat parameters:paras constructingBodyWithBlock:^(idformData){NSDateFormatter *formatter = [[NSDateFormatter alloc]init];formatter.dateFormat = @"yyyyMMddHHmmss";NSString *str = [formatter stringFromDate:[NSDate date]];//fileName这里取当前时间戳//accessory还是一样和服务端对应,具体看你自己的接口文档//mimeType选择@"amr/mp3/wmr",意思是告诉服务端,我上传的文件类型是支持三种格式amr、mp3和wmr,这里需要注意//这里我是上传了一个amr格式的语音文件,那么如果你的语音文件为其它格式,一定要和服务端对应上,比如服务端让你上传wav格式的语音,那么你拿到的是amr,怎么办?//讲个笑话,有人直接改后缀,服务端不是让我上传wav的嘛,直接改.wav不就可以了嘛!真的有人这样想这样做了。那么这里告诉你,你是男的,穿了女人的衣服,你仍然是男的。即使割掉丁丁也不是女的,最多算是不男不女。解决方法就是找第三方库,把你的amr语音转换为wav,然后转为NSData再上传就可以了。NSString *fileName = [NSString stringWithFormat:@"%@.amr",str];[formData appendPartWithFileData:voiceDataname:@"accessory"fileName:fileNamemimeType:@"amr/mp3/wmr"];}success:^(AFHTTPRequestOperation *operation,NSData *responseObject){NSLog;NSError *error;NSDictionary *dic = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];//json解析得到存储服务器返回的字典NSLog(@"状态==%@", dic[@"msg"]);}failure:^(AFHTTPRequestOperation *operation,NSError *error){//连接服务器失败NSLog;}];operation.responseSerializer = [AFHTTPResponseSerializer serializer];[operation start];

betway必威官方网站 3

但在实际开发中并不理想。比如,默认Request的请求超时时间是无限的,但通过集成Hyper来使用Requests进行get请求时,还是会出现超时的情况,所以,对于Http/2的开发,不建议使用这种方式。

代码可以直接copy,改baseURL和路径,已经上传的关键参数。就可以上传成功。

由于是在Linux上开发,所以需要将.so文件和.dll文件上传到Linux服务器上安装的jdk/lib/amd64里面,要不会报引擎错误,window环境直接放在项目跟目录就行.

开发背景

在开发“才权的AI小助手”过程中,进行了DuerOS云端接口的接入,DuerOS的云端接口是基于Http/2的,而且,需要使用multipart/form-data进行当前状态和语音数据流的上传。

betway必威官方网站 4

DuerOS语音状态和数据上传格式

http://open.duer.baidu.com/doc/dueros-conversational-service/device-interface/voice-input_markdown

 

面临问题和解决方案

Hyper中并没有专门的接口用来实现multipart/form-data类型数据的上传,而是直接接收已经序列化后的body数据。

betway必威官方网站 5

Hyper数据上传

针对这种情况,我们可以Http协议的报文定义,来定制body的内容,最终实现Hyper对multipart/form-data类型数据上传的支持。

betway必威官方网站 6

数据报文格式

由于微信小程序上传的文件格式是silk的,而讯飞接口能识别wav 格式的文件,所以需要将小程序上传的silk文件转成wav的格式

示例代码

对于DuerOS的语音请求,需要讲语音状态(Json串)和语音数据(PCM音频流)以multipart/form-data的形式进行上传。这里我们通过get_multipart_formed_data()方法来定制body内容,

'''
    msg_id:消息ID(messageId字段)
    dialog_req_id:对话ID(dialogRequestId字段)
    format:语音数据格式(format字段)
    data:语音raw data(pcm数据流)
'''
def get_multipart_formed_data(self, msg_id, dialog_req_id, format, data):

    event={'clientContext':['ai.dueros.device_interface.alerts.AlertsState','ai.dueros.device_interface.audio_player.PlaybackState','ai.dueros.device_interface.speaker_controller.VolumeState','ai.dueros.device_interface.voice_output.SpeechState'], 
   'event':{'header':{'namespace':'ai.dueros.device_interface.voice_input', 
                      'name':'ListenStarted', 
                      'messageId':msg_id, 
                      'dialogRequestId':dialog_req_id}, 
            'payload':{'format':format}}}

    event=json.dumps(event)

    post_data1=[]

    # ListenStarted事件
    post_data1.append('--' boundary)
    post_data1.append('Content-Disposition: form-data; name="metadata"')
    post_data1.append('Content-Type: text/plain; charset=utf-8')
    post_data1.append('')
    post_data1.append(event)
#     post_data1.append('--' boundary '--')# test
    post_data1.append('')

#     return crlf.join(post_data1).encode('utf-8')# test

#     # Audio data
    post_data1.append('--' boundary)
    post_data1.append('Content-Disposition: form-data; name="audio"')
    post_data1.append('Content-Type: application/octet-stream')
    post_data1.append('')

    body1=crlf.join(post_data1).encode('utf-8')

    body2=data

    post_data3=[]
    post_data3.append('--' boundary '--')
    post_data3.append('')
    body3=crlf.join(post_data3).encode('utf-8')

    upload_data=body1 b'{0}'.format(crlf) body2 b'{0}'.format(crlf) body3

    return upload_data

语音状态和数据上传,

'''
    msg_id:消息ID(messageId字段)
    dialog_req_id:对话ID(dialogRequestId字段)
    format:语音数据格式(format字段)
    data:语音raw data(pcm数据流)
'''
def voice_raw_data_upload(self, msg_id, dialog_req_id, format, data):
    post_body=self.get_multipart_formed_data(msg_id, dialog_req_id, format, data)
    self.conn.request('POST', path_upload_voice_data, headers=self.headers, body=post_body)
    resp = self.conn.get_response()

    return resp.read()

由于小程序上传的silk文件是变异的silk(小程序上传的silk文件中在编码头多添加了一个字节)文件,所以需要将他处理成正常的silk文件

完整代码参考

完整的代码可以参考
《Eddy的AI小助手-百度DuerOS模块接入(23)》

由于项目是运行在Linux上,所以写了一个简单的shell脚本以供java程序调用处理

博客地址

http://caiquanliu.github.io

betway必威官方网站 7这个脚本的作用是删除输入文件中#!SILK_V3所在行的第一个字节

本文由betway必威发布于编程开发,转载请注明出处:betway必威官方网站:data数据上传,微信小程序语

TAG标签: betway必威
Ctrl+D 将本页面保存为书签,全面了解最新资讯,方便快捷。