• 简单语音识别实现

    2018-04-18 19:50:38
    本文主要介绍如何实现一个简单的语音识别系统,识别的是英文0-9十个英文单词 首先介绍下实现的思路: 1.对语音wav文件进行mfcc特征提取(这一步由librosa完成,细节可以不care) 2.对得到的数据进行归一化 3.使用...

    本文主要介绍如何实现一个简单的语音识别系统,识别的是英文0-9十个英文单词
    首先介绍下实现的思路:
    1.对语音wav文件进行mfcc特征提取(这一步由librosa完成,细节可以不care)
    2.对得到的数据进行归一化
    3.使用CNN神经网络对归一化的数据进行分类

    源代码cnn-asr

    特征提取

    实现代码

    def read_files(files):
        labels = []
        features = []
        for ans, files in files.items():
            for file in files:
                wave, sr = librosa.load(file, mono=True)
                label = dense_to_one_hot(ans, 10)
                # label = [float(value) for value in label]
                labels.append(label)
                mfcc = librosa.feature.mfcc(wave, sr)
                l = len(mfcc)
                # print(np.array(mfcc).shape)
                mfcc = np.pad(mfcc, ((0, 0), (0, 80 - len(mfcc[0]))), mode='constant', constant_values=0)
                features.append(np.array(mfcc))
                # print('reading '+file)
        return np.array(features), np.array(labels)

    函数输入的是包含wav文件名的list,每个文件是一个单词的发音,每个单词发音特征提取后是一个20*80的数据矩阵。可以理解乘每个单词发音包含20个mfcc,每个mfcc是一个长度为80的向量。

    数据归一化

    实现代码

    def mean_normalize(features):
        std_value = features.std()
        mean_value = features.mean()
        return (features - mean_value) / std_value

    CNN分类

    cnn原理可参考 CNN(卷积神经网络)详解

    这里写图片描述

    参照上图,我们CNN的输入是shape为[20,80]数据矩阵,分别经过两种size的卷积核(filter):[2,80]和[3,80]。两种卷积核的个数都是是64个,分别得到64个长度为18的向量和64个长度为19的向量。然后取每个向量的最大值,取最大值的原因是保留每个卷积核捕获到的最大特征。把这些最大特征拼凑在一块作为x经过卷积后的特征向量(size=128),后面接全连接层以及输出层。

    实现代码

    class ASRCNN(object):
        def __init__(self, config, width, height, num_classes):  # 20,80
            self.config = config
            self.input_x = tf.placeholder(tf.float32, [None, width, height], name='input_x')
            self.input_y = tf.placeholder(tf.float32, [None, num_classes], name='input_y')
            self.keep_prob = tf.placeholder(tf.float32, name='keep_prob')
    
            # input_x = tf.reshape(self.input_x, [-1, height, width])
            input_x = tf.transpose(self.input_x, [0, 2, 1])
            pooled_outputs = []
            for i, filter_size in enumerate(self.config.filter_sizes):
                with tf.name_scope("conv-maxpool-%s" % filter_size):
                    print("conv-maxpool-%s" % filter_size)
                    conv = tf.layers.conv1d(input_x, self.config.num_filters, filter_size, activation=tf.nn.relu)
                    pooled = tf.reduce_max(conv, reduction_indices=[1])
                    pooled_outputs.append(pooled)
            num_filters_total = self.config.num_filters * len(self.config.filter_sizes)  # 32*3
            pooled_reshape = tf.reshape(tf.concat(pooled_outputs, 1), [-1, num_filters_total])
            #pooled_flat = tf.nn.dropout(pooled_reshape, self.keep_prob)
    
            fc = tf.layers.dense(pooled_reshape, self.config.hidden_dim, activation=tf.nn.relu, name='fc1')
            fc = tf.contrib.layers.dropout(fc, self.keep_prob)
            #fc = tf.nn.relu(fc)
            # 分类器
            self.logits = tf.layers.dense(fc, num_classes, name='fc2')
            self.y_pred_cls = tf.argmax(tf.nn.softmax(self.logits), 1)  # 预测类别
            # 损失函数,交叉熵
            cross_entropy = tf.nn.softmax_cross_entropy_with_logits(logits=self.logits, labels=self.input_y)
            self.loss = tf.reduce_mean(cross_entropy)
            # 优化器
            self.optim = tf.train.AdamOptimizer(learning_rate=self.config.learning_rate).minimize(self.loss)
            # 准确率
            correct_pred = tf.equal(tf.argmax(self.input_y, 1), self.y_pred_cls)
            self.acc = tf.reduce_mean(tf.cast(correct_pred, tf.float32))

    我们也可以引入更多size的卷积核如[5,20],事实上,更多种类的卷积核可以捕获更多的特征,我们卷积得到的特征向量维度就等于所有卷积核的个数。

    展开全文
  • 小程序实现语音识别功能,通过语音的方式代替手动输入查询。经过查询微信小程序api,发现微信并没有对外提供语音识别的api,所以要另外想办法。经过多发查找资料发现了思路。 解决思路: 微信小程序提供了录音的...

    小程序实现语音识别功能,通过语音的方式代替手动输入查询。经过查询微信小程序api,发现微信并没有对外提供语音识别的api,所以要另外想办法。经过多发查找资料发现了思路。

    解决思路:

    微信小程序提供了录音的功能,通过录音的方式,然后把录音文件传到服务器,后台服务器将语音转码,然后再调用第三方语音识别api,我这里使用的是百度的api,最后在将识别的文字返回给微信小程序。

    直接上代码:

    小程序端代码:

    startRecord: function() {

    if (this.recorderManager == null) {

    this.recorderManager = wx.getRecorderManager();

    this.options = {

    duration: 10000,

    sampleRate: 16000,

    numberOfChannels: 1,

    encodeBitRate: 64000,

    format: 'mp3',

    frameSize: 50

    }

    }

    this.recorderManager.start(this.options);

    this.recorderManager.onStop((res) => {

    console.log(res)

    wx.uploadFile({

    url: 'https://xxxx',//将录音文件传到后台服务器

    filePath: res.tempFilePath,

    method:'POST',

    name: 'file',

    header: {

    'content-type': 'multipart/form-data'

    },

    success: function(res) {

    console.log(res);

    },

    fail: function() {

    console.log("语音识别失败");

    }

    })

    });

    },

    stopRecord: function() {

    this.recorderManager.stop()

    }

     

    服务端代码:

    注意:需要使用mp3plugin.jar包,网上可以下载到。

        // 百度语音识别
        public static final String APP_ID = "xxx";
        public static final String API_KEY = "xxx";
        public static final String SECRET_KEY = "xxx";

        /**
         * @Description TODO
         * @return
         */
        @RequestMapping(value = "speechRecognition", method = RequestMethod.POST)
        @ResponseBody
        public Object speechReco(HttpServletRequest request) {
            MultipartFile file = ((MultipartHttpServletRequest) request).getFile("file");
            try {
                byte[] pcmBytes = mp3Convertpcm(file.getInputStream());
                org.json.JSONObject resultJson = speechBdApi(pcmBytes);
                System.out.println(resultJson.toString());
                if (null != resultJson && resultJson.getInt("err_no") == 0) {
                    return resultJson.getJSONArray("result").get(0).toString().split(",")[0];
                }
            } catch (Exception e) {
                e.printStackTrace();
            }

            return "";
        }

        /**
         * @Description MP3转换pcm
         * @param mp3Stream
         *            原始文件流
         * @return 转换后的二进制
         * @throws Exception
         */
        public byte[] mp3Convertpcm(InputStream mp3Stream) throws Exception {
            // 原MP3文件转AudioInputStream
            BufferedInputStream zipTest=new BufferedInputStream(mp3Stream);
            //重新包装一层,不然会报错。
            AudioInputStream mp3audioStream = AudioSystem.getAudioInputStream(zipTest);
            // 将AudioInputStream MP3文件 转换为PCM AudioInputStream
            AudioInputStream pcmaudioStream = AudioSystem.getAudioInputStream(AudioFormat.Encoding.PCM_SIGNED,
                    mp3audioStream);
            byte[] pcmBytes = IOUtils.toByteArray(pcmaudioStream);
            pcmaudioStream.close();
            mp3audioStream.close();
            return pcmBytes;
        }

        /**
         * @Description 调用百度语音识别API
         * @param pcmBytes
         * @return
         */
        public static org.json.JSONObject speechBdApi(byte[] pcmBytes) {
            // 初始化一个AipSpeech
            AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);
            // 可选:设置网络连接参数
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);
            // 调用接口
            org.json.JSONObject res = client.asr(pcmBytes, "pcm", 16000, null);
            return res;
        }

     

    如果我的文章帮助到了大家,减少大家的弯路,愿意打赏的请扫下面的二维码。也可留言。

     

    展开全文
  • 现在要实现语音识别不需要自己实现算法,只要能把声音通过网络传给语音识别服务提供商就可以了,语音识别在服务提供商的服务器上完成,然后把结果返回过来。这种模式对于我这种不追求自主知识产权的人来说已经足够了...
    前几天研究了一下在树莓派上使用麦克风,目的是实现树莓派上的语音识别。
    现在要实现语音识别不需要自己实现算法,只要能把声音通过网络传给语音识别服务提供商就可以了,语音识别在服务提供商的服务器上完成,然后把结果返回过来。这种模式对于我这种不追求自主知识产权的人来说已经足够了。
    目前语音识别服务主要有百度、科大讯飞、google。
    百度提供ios、安卓、linux等的sdk,同时还提供基于http的访问接口,用户只要能实现http post method就可以了,可以说非常的方便。百度的开放平台审核效率还是很高的,我在大年初一申请语音识别API权限,他们初三就审核通过了!大年初三!通过了!!!用起来也很简单,半天时间就可以调通的了。
    科大讯飞也提供各主流平台的sdk,另外有树莓派的sdk可供申请(还没拿到,不知道是不是基于http的)。讯飞能做到目前的程度,一定有其过人之处,希望有机会能试用一下。
    google,呵呵,国内不要用了吧。

    下面记录一下百度语音识别API的开发过程:
    1. 在百度开放平台新建工程,申请到ID、API key、secret key以及开发文档等。
    2. 用上面的数据到百度oauth获取access token。
    3. 把要识别的语音数据按照百度文档中的格式传到其服务器上。我使用的是隐式上传,需要对语音数据做base64编码,和另外一些格式信息组成json数据,post到服务器端。
    4. 服务器返回识别结果的json文本,对结果进行解析即可。

    百度提供了c++、java等的例子工程,太复杂了。python 50行代码搞定的事儿,c++要一堆代码,还是不要看了。
      1 #! /usr/bin/env python3
      2
      3 import baidu_oauth
      4 import uuid
      5 import base64
      6 import json
      7 import urllib.request
      8 import sys
      9
     10 asr_server = 'http://vop.baidu.com/server_api'
     11 baidu_oauth_url = 'https://openapi.baidu.com/oauth/2.0/token/'
     12 client_id = 'xxx'
     13 client_secret = 'xxx'
     14 access_token = baidu_oauth.get_baidu_access_token(baidu_oauth_url, client_id, client_secret)
     15 mac_address=uuid.UUID(int=uuid.getnode()).hex[-12:]
     16
     17 def baidu_asr(speech_file):
     18         with open(speech_file, 'rb') as f:
     19                 speech_data = f.read()
     20         speech_base64=base64.b64encode(speech_data).decode('utf-8')
     21         speech_length=len(speech_data)
     22         data_dict = {'format':'wav', 'rate':8000, 'channel':1, 'cuid':mac_address, 'token':access_token, 'lan':'zh', 'speech':speech_base64, 'len':speech_length}
     23         json_data = json.dumps(data_dict).encode('utf-8')
     24         json_length = len(json_data)
     25
     26         request = urllib.request.Request(url=asr_server)
     27         request.add_header("Content-Type", "application/json")
     28         request.add_header("Content-Length", json_length)
     29         fs = urllib.request.urlopen(url=request, data=json_data)
     30
     31         result_str = fs.read().decode('utf-8')
     32         json_resp = json.loads(result_str)
     33         return json_resp
     34
     35 json_resp = baidu_asr(sys.argv[1])
     36 print(json_resp)
    展开全文
  • 首先,语音识别技术已经不是什么新鲜的词汇了,各大公司也提供了自己的语音识别API,据说百度、讯飞等公司的识别率已经达到99%。 最近我也想给网站加上一个语音识别功能,用于搜索词汇。我首选的是讯飞,毕竟人家是...

    首先,语音识别技术已经不是什么新鲜的词汇了,各大公司也提供了自己的语音识别API,据说百度、讯飞等公司的识别率已经达到99%。

    最近我也想给网站加上一个语音识别功能,用于搜索词汇。我首选的是讯飞,毕竟人家是专业做语音的,但关于html5的SDK讯飞已经下架,无法使用人家现成的接口。

    没办法只能使用百度的语音识别,百度语音识别,需要提供音频文件,格式为pcm、wav 、avr。所以需要做一个html5的录音功能,我辗转各个网站,浏览了三天的信息,入了无数个坑,也发现了现在的html5录音基本上使用的是recorder.js,通过配合html5的audio标签来实现的。但网上挂着的那些录音代码十个有九个不能用,特别坑。现在网上的html5录音格式基本上都是mp3的,我又费了一点劲调成了wav格式的。

    现在步入正题哈

    1.首先建一个html,代码如下:

    <!DOCTYPE html>
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title></title>
    </head>
    <body>
        <div>
            <audio controls autoplay></audio>
            <input οnclick="startRecording()" type="button" value="录音" />
            <input οnclick="stopRecording()" type="button" value="停止" />
            <input οnclick="playRecording()" type="button" value="播放" />
            <input οnclick="uploadAudio()" type="button" value="提交" />
        </div>

        <script type="text/javascript" src="HZRecorder.js"></script>

        <script>
            var recorder;
            var audio = document.querySelector('audio');
            function startRecording() {
                HZRecorder.get(function (rec) {
                    recorder = rec;
                    recorder.start();
                });
            }
            function stopRecording() {
                recorder.stop();
            }
            function playRecording() {
                recorder.play(audio);
            }
            function uploadAudio() {
                recorder.upload("UploadVideoServlet.do", function (state, e) {
                    switch (state) {
                        case 'uploading':
                            //var percentComplete = Math.round(e.loaded * 100 / e.total) + '%';
                            break;
                        case 'ok':
                            //alert(e.target.responseText);
                            //alert("上传成功");
                            window.location.href="VideoSearchServlet.do";
                            break;
                        case 'error':
                            alert("上传失败");
                            break;
                        case 'cancel':
                            alert("上传被取消");
                            break;
                    }
                });
            }

        </script>
    </body>
    </html>

    2.再建一个HZRecorder.js

    (function (window) {
        //兼容
        window.URL = window.URL || window.webkitURL;
        navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;


        var HZRecorder = function (stream, config) {
            config = config || {};
            config.sampleBits = config.sampleBits || 16;      //采样数位 8, 16
            config.sampleRate = config.sampleRate || (8000);   //采样率(1/6 44100)


            var context = new AudioContext();
            var audioInput = context.createMediaStreamSource(stream);
            var recorder = context.createScriptProcessor(4096, 1, 1);


            var audioData = {
                size: 0          //录音文件长度
                , buffer: []     //录音缓存
                , inputSampleRate: context.sampleRate    //输入采样率
                , inputSampleBits: 16       //输入采样数位 8, 16
                , outputSampleRate: config.sampleRate    //输出采样率
                , oututSampleBits: config.sampleBits       //输出采样数位 8, 16
                , input: function (data) {
                    this.buffer.push(new Float32Array(data));
                    this.size += data.length;
                }
                , compress: function () { //合并压缩
                    //合并
                    var data = new Float32Array(this.size);
                    var offset = 0;
                    for (var i = 0; i < this.buffer.length; i++) {
                        data.set(this.buffer[i], offset);
                        offset += this.buffer[i].length;
                    }
                    //压缩
                    var compression = parseInt(this.inputSampleRate / this.outputSampleRate);
                    var length = data.length / compression;
                    var result = new Float32Array(length);
                    var index = 0, j = 0;
                    while (index < length) {
                        result[index] = data[j];
                        j += compression;
                        index++;
                    }
                    return result;
                }
                , encodeWAV: function () {
                    var sampleRate = Math.min(this.inputSampleRate, this.outputSampleRate);
                    var sampleBits = Math.min(this.inputSampleBits, this.oututSampleBits);
                    var bytes = this.compress();
                    var dataLength = bytes.length * (sampleBits / 8);
                    var buffer = new ArrayBuffer(44 + dataLength);
                    var data = new DataView(buffer);


                    var channelCount = 1;//单声道
                    var offset = 0;


                    var writeString = function (str) {
                        for (var i = 0; i < str.length; i++) {
                            data.setUint8(offset + i, str.charCodeAt(i));
                        }
                    }
                    
                    // 资源交换文件标识符 
                    writeString('RIFF'); offset += 4;
                    // 下个地址开始到文件尾总字节数,即文件大小-8 
                    data.setUint32(offset, 36 + dataLength, true); offset += 4;
                    // WAV文件标志
                    writeString('WAVE'); offset += 4;
                    // 波形格式标志 
                    writeString('fmt '); offset += 4;
                    // 过滤字节,一般为 0x10 = 16 
                    data.setUint32(offset, 16, true); offset += 4;
                    // 格式类别 (PCM形式采样数据) 
                    data.setUint16(offset, 1, true); offset += 2;
                    // 通道数 
                    data.setUint16(offset, channelCount, true); offset += 2;
                    // 采样率,每秒样本数,表示每个通道的播放速度 
                    data.setUint32(offset, sampleRate, true); offset += 4;
                    // 波形数据传输率 (每秒平均字节数) 单声道×每秒数据位数×每样本数据位/8 
                    data.setUint32(offset, channelCount * sampleRate * (sampleBits / 8), true); offset += 4;
                    // 快数据调整数 采样一次占用字节数 单声道×每样本的数据位数/8 
                    data.setUint16(offset, channelCount * (sampleBits / 8), true); offset += 2;
                    // 每样本数据位数 
                    data.setUint16(offset, sampleBits, true); offset += 2;
                    // 数据标识符 
                    writeString('data'); offset += 4;
                    // 采样数据总数,即数据总大小-44 
                    data.setUint32(offset, dataLength, true); offset += 4;
                    // 写入采样数据 
                    if (sampleBits === 8) {
                        for (var i = 0; i < bytes.length; i++, offset++) {
                            var s = Math.max(-1, Math.min(1, bytes[i]));
                            var val = s < 0 ? s * 0x8000 : s * 0x7FFF;
                            val = parseInt(255 / (65535 / (val + 32768)));
                            data.setInt8(offset, val, true);
                        }
                    } else {
                        for (var i = 0; i < bytes.length; i++, offset += 2) {
                            var s = Math.max(-1, Math.min(1, bytes[i]));
                            data.setInt16(offset, s < 0 ? s * 0x8000 : s * 0x7FFF, true);
                        }
                    }


                    return new Blob([data], { type: 'audio/wav' });
                }
            };


            //开始录音
            this.start = function () {
                audioInput.connect(recorder);
                recorder.connect(context.destination);
            }


            //停止
            this.stop = function () {
                recorder.disconnect();
            }


            //获取音频文件
            this.getBlob = function () {
                this.stop();
                return audioData.encodeWAV();
            }


            //回放
            this.play = function (audio) {
                audio.src = window.URL.createObjectURL(this.getBlob());
            }


            //上传
            this.upload = function (url, callback) {
                var fd = new FormData();
                fd.append("audioData", this.getBlob());
                var xhr = new XMLHttpRequest();
                if (callback) {
                    xhr.upload.addEventListener("progress", function (e) {
                        callback('uploading', e);
                    }, false);
                    xhr.addEventListener("load", function (e) {
                        callback('ok', e);
                    }, false);
                    xhr.addEventListener("error", function (e) {
                        callback('error', e);
                    }, false);
                    xhr.addEventListener("abort", function (e) {
                        callback('cancel', e);
                    }, false);
                }
                xhr.open("POST", url);
                xhr.send(fd);
            }


            //音频采集
            recorder.onaudioprocess = function (e) {
                audioData.input(e.inputBuffer.getChannelData(0));
                //record(e.inputBuffer.getChannelData(0));
            }


        };
        //抛出异常
        HZRecorder.throwError = function (message) {
            alert(message);
            throw new function () { this.toString = function () { return message; } }
        }
        //是否支持录音
        HZRecorder.canRecording = (navigator.getUserMedia != null);
        //获取录音机
        HZRecorder.get = function (callback, config) {
            if (callback) {
                if (navigator.getUserMedia) {
                    navigator.getUserMedia(
                        { audio: true } //只启用音频
                        , function (stream) {
                            var rec = new HZRecorder(stream, config);
                            callback(rec);
                        }
                        , function (error) {
                            switch (error.code || error.name) {
                                case 'PERMISSION_DENIED':
                                case 'PermissionDeniedError':
                                    HZRecorder.throwError('用户拒绝提供信息。');
                                    break;
                                case 'NOT_SUPPORTED_ERROR':
                                case 'NotSupportedError':
                                    HZRecorder.throwError('浏览器不支持硬件设备。');
                                    break;
                                case 'MANDATORY_UNSATISFIED_ERROR':
                                case 'MandatoryUnsatisfiedError':
                                    HZRecorder.throwError('无法发现指定的硬件设备。');
                                    break;
                                default:
                                    HZRecorder.throwError('无法打开麦克风。异常信息:' + (error.code || error.name));
                                    break;
                            }
                        });
                } else {
                    HZRecorder.throwErr('当前浏览器不支持录音功能。'); return;
                }
            }
        }


        window.HZRecorder = HZRecorder;


    })(window);

     

    现在前台的代码就到这里了。

     

    3.下面进行Servlet处理

    我先说一下,这是在Tomcat服务器中运行的。

    下面的这个Servlet:UploadVideoServlet.do是将音频文件保存到服务器端的。

    代码如下:

    package com.hanfeng.servlet;

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.PrintWriter;
    import java.util.ArrayList;
    import java.util.List;
    import javax.servlet.ServletException;
    import javax.servlet.http.HttpServlet;
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    import javax.servlet.http.HttpSession;
    import javax.sound.sampled.AudioInputStream;
    import javax.sound.sampled.AudioSystem;
    import javax.sound.sampled.Clip;


    import java.io.IOException;
    import javax.servlet.annotation.WebServlet;
    import org.apache.commons.fileupload.FileItem;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;


    import com.hanfeng.dao.Music;
    import com.hanfeng.dao.Regist;
    import com.hanfeng.service.MusicService;
    import com.hanfeng.service.RegistService;


    public class UploadVideoServlet extends HttpServlet {


    public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }


    public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
    MusicService musicService = new MusicService();
    HttpSession  hs = request.getSession();
    String userName = (String) hs.getAttribute("username");
    // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
    String savePath = "D:/java web/apache-tomcat-9.0.0.M17/webapps/pcm";

    File file = new File(savePath);
    // 判断上传文件的保存目录是否存在
    if (!file.exists() && !file.isDirectory()) {
    System.out.println(savePath + "目录不存在,需要创建");
    // 创建目录
    file.mkdir();
    }
    // 消息提示
    String message = "";
    try {
    String filename = null;
    // 使用Apache文件上传组件处理文件上传步骤:
    // 1、创建一个DiskFileItemFactory工厂
    DiskFileItemFactory factory = new DiskFileItemFactory();
    // 2、创建一个文件上传解析器
    ServletFileUpload upload = new ServletFileUpload(factory);
    // 解决上传文件名的中文乱码
    upload.setHeaderEncoding("UTF-8");
    // 3、判断提交上来的数据是否是上传表单的数据
    if (!ServletFileUpload.isMultipartContent(request)) {
    // 按照传统方式获取数据
    return;
    }
    // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
    List<FileItem> list = upload.parseRequest(request);


    //System.out.println(list.get(0));
    String[] value = new String[5]; 
    int i=0;
    for (FileItem item : list) {
    // 如果fileitem中封装的是普通输入项的数据
    if (item.isFormField()) {
    // System.out.println("歌曲名"+item.getString("musicName")+"类别"+item.getString("musicType"));
    String name = item.getFieldName();
    // 解决普通输入项的数据的中文乱码问题
    value[i++] = item.getString("UTF-8");
    // value = new String(value.getBytes("iso8859-1"),"UTF-8");
    //System.out.println(name + "=" + value);
    } else {// 如果fileitem中封装的是上传文件
    // 得到上传的文件名称,

    filename = "test.wav";
    //item.getName();
    System.out.println(filename);
    if (filename == null || filename.trim().equals("")) {
    continue;
    }
    // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
    // c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt
    // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
    filename = filename.substring(filename.lastIndexOf("\\") + 1);
    // 获取item中的上传文件的输入流
    InputStream in = item.getInputStream();
    // 创建一个文件输出流
    FileOutputStream out = new FileOutputStream(savePath + "\\" + filename);
    // 创建一个缓冲区
    byte buffer[] = new byte[1024];
    // 判断输入流中的数据是否已经读完的标识
    int len = 0;
    // 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
    while ((len = in.read(buffer)) > 0) {
    // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\\"
    // + filename)当中
    out.write(buffer, 0, len);
    }
    // 关闭输入流
    in.close();
    // 关闭输出流
    out.close();
    // 删除处理文件上传时生成的临时文件
    item.delete();
    message = "文件上传成功!";
    }
    }

    } catch (Exception e) {
    message = "文件上传失败!";
    e.printStackTrace();
    }

    }

    }

    4.下面进入百度语音识别端口的连接,

    首先进入百度语音网站申请端口(都是免费的)http://yuyin.baidu.com/

    (1)点击SDK下载

    (2)选择应用,自己填一下信息,申请一下,很简单的

    (3)选择SDK,画红圈的是百度语音提供的demo,做javaweb用这个足以,就下载那个就行。

    选择java,导入到自己的工程中。

    (4)上述的都弄好了之后,进入应用管理,获取自己的key

     

    5.下面进行百度语音识别API连接

    建一个java文件

    package com.baidu.speech.serviceapi;


    import java.io.BufferedReader;
    import java.io.DataOutputStream;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.net.HttpURLConnection;
    import java.net.URL;
    import java.util.regex.Matcher;
    import java.util.regex.Pattern;


    import javax.xml.bind.DatatypeConverter;


    import org.json.JSONObject;


    public class Sample {


        private static final String serverURL = "http://vop.baidu.com/server_api";
        private static String token = "";
        private static final String testFileName = "D:/java web/apache-tomcat-9.0.0.M17/webapps/pcm/test.wav";//需要识别的音频文件
        //put your own params here
        private static final String apiKey = "自己的apiKey";
        private static final String secretKey = "自己的secretKey";
        private static final String cuid = “自己的网卡物理地址";


        public static void main(String[] args) throws Exception {
            getToken();
            method1();
            method2();
        }
        private static void getToken() throws Exception {
            String getTokenURL = "https://openapi.baidu.com/oauth/2.0/token?grant_type=client_credentials" + 
                "&client_id=" + apiKey + "&client_secret=" + secretKey;
            HttpURLConnection conn = (HttpURLConnection) new URL(getTokenURL).openConnection();
            token = new JSONObject(printResponse(conn)).getString("access_token");
        }


        private static void method1() throws Exception {
            File wavFile = new File(testFileName);
            HttpURLConnection conn = (HttpURLConnection) new URL(serverURL).openConnection();


            // construct params
            JSONObject params = new JSONObject();
            params.put("format", "wav");
            params.put("rate", 16000);
            params.put("channel", "1");
            params.put("token", token);
            params.put("cuid", cuid);
            params.put("lan", "zh");
            params.put("len", wavFile.length());
            params.put("speech", DatatypeConverter.printBase64Binary(loadFile(wavFile)));


            // add request header
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "application/json; charset=utf-8");


            conn.setDoInput(true);
            conn.setDoOutput(true);


            // send request
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.writeBytes(params.toString());
            wr.flush();
            wr.close();


            printResponse(conn);
        }


        private static void method2() throws Exception {
            File wavFile = new File(testFileName);
            HttpURLConnection conn = (HttpURLConnection) new URL(serverURL
                    + "?cuid=" + cuid + "&token=" + token).openConnection();


            // add request header
            conn.setRequestMethod("POST");
            conn.setRequestProperty("Content-Type", "audio/wav; rate=16000");


            conn.setDoInput(true);
            conn.setDoOutput(true);


            // send request
            DataOutputStream wr = new DataOutputStream(conn.getOutputStream());
            wr.write(loadFile(wavFile));
            wr.flush();
            wr.close();


            printResponse(conn);
        }


        private static String printResponse(HttpURLConnection conn) throws Exception {
            if (conn.getResponseCode() != 200) {
                // request error
                return "";
            }
            InputStream is = conn.getInputStream();
            BufferedReader rd = new BufferedReader(new InputStreamReader(is));
            String line;
            StringBuffer response = new StringBuffer();
            while ((line = rd.readLine()) != null) {
                response.append(line);
                response.append('\r');
            }
            rd.close();
            System.out.println(new JSONObject(response.toString()).toString(4));
            //System.out.println(response.toString());
            return response.toString();
        }


        private static byte[] loadFile(File file) throws IOException {
            InputStream is = new FileInputStream(file);


            long length = file.length();
            byte[] bytes = new byte[(int) length];


            int offset = 0;
            int numRead = 0;
            while (offset < bytes.length
                    && (numRead = is.read(bytes, offset, bytes.length - offset)) >= 0) {
                offset += numRead;
            }


            if (offset < bytes.length) {
                is.close();
                throw new IOException("Could not completely read file " + file.getName());
            }


            is.close();
            return bytes;
        }
        public static String getChinese(String paramValue) {
        String regex = "([\u4e00-\u9fa5]+)";
        String str = "";
        Matcher matcher = Pattern.compile(regex).matcher(paramValue);
        while (matcher.find()) {
        str+= matcher.group(0);
        }
        return str;
        }
    }

     

     

    好了做完上述操作基本上语音识别就实现了,自己可以先打开html的录音录好后,运行java程序,就可以查看语音识别结果了。

    当然你也可以将main方法去掉,将代码放入到一个Servlet中,将识别结果return出来,可以用ajaxj将结果回调获取,传值到搜索的页面,获得搜索结果。

    这是我做的Demo,有需要的可以自行下载  https://download.csdn.net/download/qq_33609401/10847695

    好的,就这些了,希望能帮助到需要语音识别的你们。

    如果有不懂的地方可以留言,谢谢。

    展开全文
  • 本文采用百度云语音识别API接口,实现低于60s音频的语音识别,也可以用于合成文本长度小于1024字节的音频,此外采用snowboy离线语音唤醒引擎可实现离线语音唤醒,实现语音交互。基于本内容可实现语音控制小车,语音...

    本文采用百度云语音识别API接口,实现低于60s音频的语音识别,也可以用于合成文本长度小于1024字节的音频,此外采用snowboy离线语音唤醒引擎可实现离线语音唤醒,实现语音交互。基于本内容可实现语音控制小车,语音控制音箱、语音交互。。。
    可以查看我的github获取更多信息:https://github.com/dalinzhangzdl/AI_Car_Raspberry-pi
    一、 百度云语音识别 python-SDK的安装
    工欲善其事必先利其器,下面先来武装一下自己,申请属于自己的百度AI开发者账号,安装SDK(Software Development Kit,软件开发工具包)。
    1、进入百度云平台,进入百度语音控制台后,创建自己的应用,获取属于你的ID号和密钥:
    APP_ID = ‘114xxxx5’
    API_KEY = ‘NYIvd23qqGAZxxxxxxxxxxxxxxx’
    SECRET_KEY = ‘DcQWQ9Hxxxxxxxxxxxxxxxxxxxxxx’
    2、SDK的下载与安装
    应用创建完成后下载相应的开发SDK,这里采用python开发,下载python-SDK即可
    在这里插入图片描述
    SDK的安装:
    将下载的SDK包拷贝到树莓派pi目录下,终端界面解压安装,安装过程如下:
    解压包:unzip aip-python-sdk-2.0.0.zip
    安装SDK包: sudo pip install baidu-aip
    在这里插入图片描述
    在这里插入图片描述
    遵循以上步骤操作,就搭建好属于自己的语音识别和语音合成平台,再添加一个麦克风和一个喇叭或者音箱就可以进行语音识别方面的开发了,语音控制小车,控制智能家电等。

    二、Python-SDK 实现语音识别和语音合成
    1、python-SDK实现语音识别
    遵循SDK文档进行快速开发,务必阅读文档。如果对自己的录音进行测试,需先采用格式工厂对录音文件进行转换,确保录音的音频参数符合云语音识别的要求。单通道、采样频率为16K PCM格式,也可先直接采用官方的音频进行测试。
    程序如下:

    #_*_ coding:UTF-8 _*_
    # @author: zdl 
    # 百度云语音识别Demo,实现对本地语音文件的识别。
    # 需安装好python-SDK,录音文件不不超过60s,文件类型为wav格式。
    # 音频参数需设置为 单通道 采样频率为16K PCM格式 可以先采用官方音频进行测试
    
    # 导入AipSpeech  AipSpeech是语音识别的Python SDK客户端
    from aip import AipSpeech
    import os
    
    ''' 你的APPID AK SK  参数在申请的百度云语音服务的控制台查看'''
    APP_ID = '114xxxx5'
    API_KEY = 'NYIvd23qqGAZxxxxxxxxxxxxxxx'
    SECRET_KEY = 'DcQWQ9Hxxxxxxxxxxxxxxxxxxxxxx'
    
    # 新建一个AipSpeech
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    
    
    # 读取文件
    def get_file_content(filePath):   #filePath  待读取文件名
        with open(filePath, 'rb') as fp:
            return fp.read()
    
    		
    def stt(filename):         # 语音识别
        # 识别本地文件
        result = client.asr(get_file_content(filename),
                            'wav',
                            16000,
                            {'dev_pid': 1536,}      # dev_pid参数表示识别的语言类型 1536表示普通话
                            )
        print result
    
    	# 解析返回值,打印语音识别的结果
        if result['err_msg']=='success.':
            word = result['result'][0].encode('utf-8')       # utf-8编码
            if word!='':
                if word[len(word)-3:len(word)]==',':
                    print word[0:len(word)-3]
                    with open('demo.txt','w') as f:
                        f.write(word[0:len(word)-3])
                    f.close()
                else:
                    print (word.decode('utf-8').encode('gbk'))
                    with open('demo.txt','w') as f:
                        f.write(word)
                    f.close()
            else:
                print "音频文件不存在或格式错误"
        else:
            print "错误"
    
    # main函数 识别本地录音文件yahboom.wav
    if __name__ == '__main__':
        
        stt('test.wav')
        
    

    2、python-SDK实现语音合成
    语音合成较语音识别简单,合成文本长度必须小于1024字节,如果本文长度较长,可以采用多次请求的方式。下面是合成本地文件demo程序:

    #_*_ coding:UTF-8 _*_
    # @author: zdl 
    # 百度云语音合成Demo,实现对本地文本的语音合成。
    # 需安装好python-SDK,待合成文本不超过1024个字节
    # 合成成功返回audio.mp3 否则返回错误代码
    
    # 导入AipSpeech  AipSpeech是语音识别的Python SDK客户端
    from aip import AipSpeech
    import os
    
    ''' 你的APPID AK SK  参数在申请的百度云语音服务的控制台查看'''
    APP_ID = '114xxxx5'
    API_KEY = 'NYIvd23qqGAZxxxxxxxxxxxxxxx'
    SECRET_KEY = 'DcQWQ9Hxxxxxxxxxxxxxxxxxxxxxx'
    
    # 新建一个AipSpeech
    client = AipSpeech(APP_ID, API_KEY, SECRET_KEY)
    
    # 将本地文件进行语音合成
    def tts(filename):
        f = open(filename,'r')
        command = f.read()
        if len(command) != 0:
            word = command
        f.close()
        result  = client.synthesis(word,'zh',1, {
            'vol': 5,'per':0,
        })
    	
    # 合成正确返回audio.mp3,错误则返回dict 
        if not isinstance(result, dict):
            with open('audio.mp3', 'wb') as f:
                f.write(result)
            f.close()
            print 'tts successful'
    
    # main
    
    if __name__ == '__main__':
    
    tts('demo.txt')
    
    展开全文
  • python通过调用百度api实现语音识别(超详细) 最近在学习python,做一些python练习题 github上几年前的练习题 有一题是这样的: 使用 Python 实现:对着电脑吼一声,自动打开浏览器中的默认网站。 例如,对着笔记本...
  • 调用科大讯飞语音听写,使用Python实现语音识别,将实时语音转换为文字。 首先在官网下载了关于语音听写的SDK,然后在文件夹内新建了两个.py文件,分别是get_audio.py和iat_demo.py,并且新建了一个存放录音的...
  • Android 轻松实现语音识别的完整代码,学习Android之必备。
  • 调用科大讯飞语音听写,使用Python实现语音识别,将实时语音转换为文字。 首先在官网下载了关于语音听写的SDK,然后在文件夹内新建了两个.py文件,分别是get_audio.py和iat_demo.py,并且新建了一个存放录音的文件夹...
  • Python实现语音识别

    2019-05-09 21:19:19
    Python在语音识别方面功能很强大,程序语言简单高效,下面编程实现一下如何实现语音识别。本文实现案例是将文本转换成语音,给出实现代码,作为学习和技术交流。 Python基础环境准备 参见:...
  • 市面上语音识别技术原理已经有很多很多了,然而很多程序员兄弟们想研究的时候却看的头大,一堆的什么转mfcc,然后获取音素啥的,对于非专业音频研究者或非科班出生的程序员来说,完全跟天书一样。 最近在研究相关的...
  • 通过微软的SAPI,不仅仅可以实现语音合成TTS,同样可以实现语音识别SR。下面我们就介绍并贴出相关代码。主要有两种方式: 1、使用COM组件技术,不管是C++,C#,Delphi都能玩的转,开发出来的东西在XP和WIN7都能跑。...
  • Linux下python实现语音识别详细教程语音识别工作原理简介选择合适的python语音识别包安装SpeechRecognition识别器类音频文件的使用英文的语音识别噪音对语音识别的影响麦克风的使用中文的语音识别小范围中文识别语音...
  • Android实战——科大讯飞语音听写SDK的使用,实现语音识别功能
  • 现在语音识别已经被广泛的应用到各个领域中,在Unity开发中,语音识别也非常受欢迎。大部分人都会选择科大讯飞的语音识别功能,但是在一些小的项目中,使用科大讯飞的就有点大材小用了。今天就介绍一下Unity自带的...
  • speech.input() 这一行代码就可以实现语音识别,第一次使用需要配置一下。 运行效果图: 它调用了本地了语音识别软件。 你说英语的话它不容易识别出来,但是中文却识别的很好!应该是计算机语言是简体中文,要是...
  • LSTM实现语音识别

    2020-02-25 20:47:17
    序言:语音识别作为人工智能领域重要研究方向,近几年发展迅猛,其中...RNN与LSTM介绍RNNLSTM语音识别介绍声学特征提取声学特征转换成音素(声学模型)音素转文本(语言模型+解码)语音识别简单实现提取WAV文件中特征将...
  • 使用C++实现语音识别语音识别,还记得星球大战里的那个总陪在主人身边听话的智能机器人么?拥有了听和说的技能,在那个时候这还是人们的想象,但是今天我们就可以来实现它!微软的语音识别,在这里我们简称它为SR(speech ...
  • 作为移动互联网杀手级的交互方式,语音识别从问世以来就一直备受人们的关注,从IOS的Siri到国内的讯飞语音,语音识别技术在移动开发领域是最为充满前景和希望的技术。Android作为一个移动操作系统,其本身就继承了...
  •  谷歌允许开发人员调用他们实现的语音识别的接口,当然识别率不是很高,个人感觉不如科大讯飞做的语音识别率那么高,但通过谷歌给开发的接口实现语音识别是个非常简单的事情。Android中主要通过RecognizerIntent来...
1 2 3 4 5 ... 20
收藏数 74,700
精华内容 29,880