通过科大讯飞实时转写接口了解音频数据采集

通过科大讯飞实时转写接口了解音频数据采集

音频采集相关术语

采样率(sample rate)
音频采样率是指录音设备在一秒钟内对声音信号的采样次数,采样频率越高声音的还原就越真实越自然

采样位数(sample size)
即采样值或取样值(就是将采样样本幅度量化)。它是用来衡量声音波动变化的一个参数,也可以说是声卡的分辨率。它的数值越大,分辨率也就越高,所发出声音的能力越强。

每个采样数据记录的是振幅, 采样精度取决于采样位数的大小:

1 字节(也就是8bit) 只能记录 256 个数, 也就是只能将振幅划分成 256 个等级;
2 字节(也就是16bit) 可以细到 65536 个数, 这已是 CD 标准了;
4 字节(也就是32bit) 能把振幅细分到 4294967296 个等级, 实在是没必要了.
语音编码(format)
语音编码指语音数据存储和传输的方式。请注意,语音编码和语音文件格式不同。例如常见的.WAV文件格式,会在其头部定义语音数据的具体编码,其中的音频数据通常是使用PCM编码,但也有可能是AMR或其他编码。

声道(sound chanel
声道是指声音在录制时在不同空间位置采集的相互独立的音频信号,所以声道数也就是声音录制时的音源数量。常见的音频数据为单声道或双声道(立体声)。

除录音文件识别以外的服务只支持单声道(mono)语音数据,如果您的数据是双声道或其他,需要先转换为单声道才能识别。

通过科大讯飞实时转写可以得到音频输入流的必要条件:

1音频属性:采样率16k、位长16bits、单声道。
2音频格式:pcm
3 数据发送:建议音频流每40ms发送1280字节
4语言种类:中文普通话。
将以上4点准备好数据发送至服务接口即可。

音频数据采集逻辑
1请求麦克风资源
2创建一个音频环境对象
3读取音频流,将音频流放入储存声音缓存区中
4根据采集音频数据标准,进行格式化与压缩
将压缩后的音频数据传递到科大讯飞接口

开始使用AudioContext
AudioContext是一个专门用于音频处理的接口,并且工作原理是将AudioContext创建出来的各种节点(AudioNode)相互连接,音频数据流经这些节点并作出相应处理。

在HTML5通过AudioContext对象可以实现音频的数据采集
由于浏览器兼容性问题,我们需要为不同浏览器配置AudioContext,在这里我们可以用下面这个表达式来统一对AudioContext的访问。

var AudioContext = window.AudioContext || window.webkitAudioContext;
 
   var audioContext = new AudioContext(); //实例化AudioContext对象
浏览器 chrome Firefox IE Opera safari
支持版本 10.0 25.0 不支持 25.0 支持版本
AudioContext.createMediaStreamSource()   //创建一个MediaStreamAudioSourceNode接口来关联可能来自本地计算机麦克风或其他来源的音频流MediaStream.
 
 
AudioContext.createScriptProcessor()   //创建一个可以通过JavaScript直接处理音频的ScriptProcessorNode
  //音频采集
        recorder.onaudioprocess = function (e) {
            var  sizeData= audioData.input(e.inputBuffer.getChannelData(0));    //将采集的音频数据放入缓冲区,返回音频大小
            if(sizeData < 150000){                                               
//                 console.log("测试音频数据" + sizeData);
            }else {
                // this.reocrder.transforTest('http://localhost:8080/return/updateforwarfile');
                    var url = base + "/evnetseventreceivelow/evn-ets-eventreceive-low!updateForAudioStream.do"
                    var fd = new FormData();
                    var buffer = audioData.getPureWavData(0);
                    fd.set('wavData', buffer);
                    fd.set('sign', "open");
                    console.log("wavSize: " + buffer.size);
                    // document.getElementById('btn-text-content').value = "当前录音长度为:" + buffer.size;
                    //方法二
                    $.ajax({
                        type:"post",
                        url:url,
                        data:fd,
                        contentType: false,
                        processData: false,
                        dataType:"json",
                        success:function(res){
                            if(res != 'undefined'){
                                document.getElementById('voiceWrite').value = res.message;
                            }
                        },
                        error:function (msg) {
                        }
                    })
            }
        };

将超过150000大小的音频数据,进行处理放入后台,同时初始化缓冲区。(以上的方法是通过ajax轮询进行的查询,这种方式,存在“有延迟”,“部分音频数据在处理过程中容易造成音频数据丢失结果”)。

扫描二维码关注公众号,回复: 9138756 查看本文章

通过WebSocket传递音频数据

(一):实现websocket连接

var websocketOfXunFei;
var sumStr = '';   //总
var temporaryStr = ''; //临时
 
var protocol = window.location.protocol;
var baseService = window.location.host;
var pathName = window.location.pathname;
var projectName = pathName.substring(0,pathName.substr(1).indexOf('/')+1);
var protocolStr = document.location.protocol;
var baseHttpProtocol = "ws://";
var svrUrl =  baseHttpProtocol + baseService + projectName;
 
function init() {
    output = document.getElementById("output");
}
 
function send_messageOfKeDaXunFei() {
    sumStr = '';   //总
    if ('WebSocket' in window) {
        websocketOfXunFei = new WebSocket(svrUrl+ "/websocket/streamOfXunfei");
    } else if ('MozWebSocket' in window) {
        websocketOfXunFei = new MozWebSocket(svrUrl+ "/websocket/streamOfXunfei");
    } else {
        // websocket = new SockJS("http://localhost:8080/amp/sockjs/webSocketServer");
    }
    // websocket = new WebSocket(wsUri);
    websocketOfXunFei.onopen = function(evt) {
        onOpenOfXunFei(evt)
    };
    websocketOfXunFei.onmessage = function(evt) {
        onMessageOfXunFei(evt)
    };
    websocketOfXunFei.onerror = function(evt) {
        onErrorOfXunFei(evt)
    };
    // websocket.onclose = function(){
    //
    // }
 
}
 
function onCloseVoice_ofKeDaXunfei(e){
    console.log(e);
    websocketOfXunFei.close();  //暂时注释
}
 
function onOpenOfXunFei(evt) {
}
 
 
function onMessageOfXunFei(evt) {
     console.info(evt.data)
     var jsonObj = jQuery.parseJSON(evt.data);
     if("1" == jsonObj.nameStr){
         temporaryStr = jsonObj.messageStr;
     }else if("0" == jsonObj.nameStr){
         sumStr+= jsonObj.messageStr;
         temporaryStr = "";
     }else if("TranscriptionResultChanged" == jsonObj.nameStr){
         temporaryStr = jsonObj.messageStr;
     }else if("SentenceEnd" == jsonObj.nameStr){
         sumStr+= jsonObj.messageStr;
         temporaryStr = "";
     }
     writeToScreen(sumStr + temporaryStr);
}
 
function onErrorOfXunFei(evt) {
    writeToScreen('ERROR:' + evt.data);
}
 
function doSend(message) {
    websocketOfXunFei.send(message);    //测试已注释
}
 
function writeToScreen(message) {
     document.getElementById('voiceWriteStr').value = message;
}
 
window.addEventListener("load", init, false);

(二):通过websocket发送音频数据

//音频采集
      recorder.onaudioprocess = function (e) {
          var  sizeData= audioData.input(e.inputBuffer.getChannelData(0));
          var buffer = audioData.getPureWavData(0);  //经过压缩后的数据
          doSend(buffer);   //通过websocke中的方法进行发送
      };

(三):websocket接受前端发送音频二进制数据,调用科大讯飞发送音频数据接口

 /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息*/
    @OnMessage
    public void onMessage(byte[] message, Session session) throws InterruptedException {
//        System.out.println("收到来自前端websocket"+sid+"的信息:"+message.length);
        //调用科大讯飞接口static
        EvnEtsEventreceiveLowAction.sendVoiceData(client,message);   //这里暂时这样写
    }

将科大讯飞返回的文字,发送到前端


public static void sendInfoOfTest(String name, String message,String sid) throws IOException {
    System.out.println("推送消息到窗口"+sid+",推送内容:"+message);
    for (WebSocketServerOfXunFei item : webSocketSet) {
        try {
            //这里可以设定只推送给这个sid的,为null则全部推送
            JSONObject jsonObj = new JSONObject();
            jsonObj.put("nameStr", name);
            jsonObj.put("messageStr", message);
            if(sid==null) {
                item.sendMessage(jsonObj.toString());
            }else if(item.sid.equals(sid)){
                item.sendMessage(jsonObj.toString());
            }
        } catch (IOException e) {
            continue;
        }
    }
}

以上通过websocket实现了音频与返回数据(文字)中转能力,websocket为实时通讯,对比轮询返回的数据准确率高,实时展示效果良好。

发布了24 篇原创文章 · 获赞 8 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/wg22222222/article/details/100780228