java调用百度语音接口

五子棋调用百度语音接口实现语音识别

Step1前端上传语音到后端

前端通过ajax进行数据传输

<!DOCTYPE html>
<html lang="en">
<head>
        <meta charset="UTF-8">
        <title>五子棋</title>
 <style>
 * {
    margin: 0;
    padding: 0;
 }

 body {
    margin-top: 20px;
    margin-left: 20px;
 }

 canvas {
    background-image: url("img/backgroud.jpg");
    border: 1px solid #000;
 }

 .mybutton {
            width: 200px;
            line-height: 40px;
            text-align: center;
            background-color: cornflowerblue;
            margin: 0 auto;
            margin-top: 20px;
            font-size: 20px;
            color: #fff;
        }
 </style>
</head>

<body>
        <canvas width="600" height="600" onclick="play(event)"></canvas>    
        
        <div>
            <input type="button" value="重新开始" onclick="replay()" class="mybutton">
            <input type="button" value="开始录音" onclick="startVoice()" class="mybutton">
            <input type="button" value="结束录音" onclick="endVoice()" class="mybutton">
        </div>

           

        <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
        <script src="../templates/recorder.js" type="text/javascript" charset="utf-8"></script>
	    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/4.0.1/socket.io.js" integrity="sha512-q/dWJ3kcmjBLU4Qc47E4A9kTB4m3wuTY7vkFJDTZKjTs8jhyGQnaUrxa0Ytd0ssMZhbNua9hE+E7Qv1j+DyZwA=="
	    crossorigin="anonymous"></script>
<script>
 /*准备工作: 1获取画布,获取画笔对象 */
 var recorder = new Recorder({
	sampleRate: 16000,
	bitRate:16,
});
    var mcanvas = document.querySelector("canvas");
    var ctx = mcanvas.getContext("2d");

    /*准备工作:2创建一个二维数组 用来定义绘制棋盘线*/
    var count = 15;//用来定义棋盘的行数和列数
    var map = new Array(count);

    var startVoice = function() {

	recorder.start().then(function() {
		// 开始录音
	});
}

    var endVoice = function() {

	// 结束录音
	recorder.stop();
	// 下载pcm文件
	// recorder.downloadPCM('test');
	// 获取 PCM 数据(Blob)
	console.log(recorder.getPCMBlob());
	let voiceBlob = recorder.getPCMBlob();
	var body;
    var formdata = new FormData(); // form 表单 {key:value}
    console.log(voiceBlob)
    formdata.append("voice", voiceBlob); // form input type="file"   

	 $.ajax({
            url: "http://127.0.0.1:8080/voice2word/store",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            processData:false,
            contentType:false, 
            data: formdata,
            success: function (data) {//请求成功之后执行的回调函数
                console.log(data.code);
                 body = data.body;
                 voiceplay(body);
            },
            error: function(error){
                console.log(error)
            }
        });

}

    for (var i = 0; i < map.length; i++) {
        map[i] = new Array(count);
        for (var j = 0; j < map[i].length; j++) {
            map[i][j] = 0;
        }
    }

    /*准备工作:3初始化棋子*/
    var black = new Image();
    var white = new Image();
    black.src = "img/black.png";
    white.src = "img/white.png";


    //开始绘制 1绘制棋盘线
    ctx.strokeStyle = "#fff";
    var rectWH = 40; //设置绘制矩形的大小
    for (var i = 0; i < map.length; i++) {
        for (var j = 0; j < map[i].length; j++) {
            ctx.strokeRect(j * rectWH, i * rectWH, rectWH, rectWH);
        }
    }

    // 用来进行黑白子的切换
    var isBlack = true;

    function voiceplay(body) {
        row = body[0];
        col = body[1];
        if (map[row][col] != 0) {
        alert("此处已经落子");
        return;
    }

    // 切换绘制黑白子
    if (isBlack) {
        ctx.drawImage(black, col * 40 - 20, row * 40 - 20);
        isBlack = false;
        map[row][col] = 1;

        $.ajax({
            url: "http://127.0.0.1:5000/yes",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            data: {//向服务器端发送的数据
                t: 1,
                row: row,
                col: col,

            },
            success: function (data) {//请求成功之后执行的回调函数
                if(data.code===201){
                    alert('黑棋获胜')
                }else if(data.code===202){
                    alert('白棋获胜')
                }

            },
            error: function(error){
                console.log(error)
            }
        });

        // Yes(1,row,col)

    } else {
        ctx.drawImage(white, col * 40 - 20, row * 40 - 20);
        isBlack = true;
        map[row][col] = 2;
        $.ajax({
            url: "http://127.0.0.1:5000/yes",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            data: {//向服务器端发送的数据
                t: 2,
                row: row,
                col: col,

            },
            success: function (data) {//请求成功之后执行的回调函数
                if(data.code===201){
                    alert('黑棋获胜')
                }else if(data.code===202){
                    alert('白棋获胜')
                }

            },
            error: function(error){
                console.log(error)
            }
        });
        // Yes(2,row,col)
    }

    }

 //开始绘制 2下子
 function play(e) {
    //获取点击canvas的位置值默认,canvas的左上角为(0,0) 点
    var leftOffset = 20;//body 的margin
    var x = e.clientX - leftOffset;
    var y = e.clientY - leftOffset;
    // console.log(x+" "+y);
    // 设置点击点后棋子下在哪里,获取点击的位置进行判断如果超过格子的一半则绘制到下一个点如果小于 则绘制在上一个点上
    var xv = (x - rectWH / 2) / rectWH;
    var yv = (y - rectWH / 2) / rectWH;

    var col = parseInt(xv) + 1;
    var row = parseInt(yv) + 1;
    console.log(xv + " " + yv + " , " + col + " " + row);

    //严格点需要验证 ,验证所输入的点是否在数组中已经存在 ,如果存在 则返回
    if (map[row][col] != 0) {
        alert("此处已经落子");
        return;
    }

    // 切换绘制黑白子
    if (isBlack) {
        ctx.drawImage(black, col * 40 - 20, row * 40 - 20);
        isBlack = false;
        map[row][col] = 1;

        $.ajax({
            url: "http://127.0.0.1:5000/yes",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            data: {//向服务器端发送的数据
                t: 1,
                row: row,
                col: col,
                
            },
            success: function (data) {//请求成功之后执行的回调函数
                if(data.code===201){
                    alert('黑棋获胜')
                }else if(data.code===202){
                    alert('白棋获胜')
                }
                
            },
            error: function(error){
                console.log(error)
            }
        });

        // Yes(1,row,col)

    } else {
        ctx.drawImage(white, col * 40 - 20, row * 40 - 20);
        isBlack = true;
        map[row][col] = 2;
        $.ajax({
            url: "http://127.0.0.1:5000/yes",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            data: {//向服务器端发送的数据
                t: 2,
                row: row,
                col: col,
              
            },
            success: function (data) {//请求成功之后执行的回调函数
                if(data.code===201){
                    alert('黑棋获胜')
                }else if(data.code===202){
                    alert('白棋获胜')
                }
                
            },
            error: function(error){
                console.log(error)
            }
        });
        // Yes(2,row,col)
    }


 }

 function replay(){
    $.ajax({
            url: "http://127.0.0.1:5000/replay",//请求的url地址
            type: 'post',//设置请求的http方式,method也可以
            dataType: 'json',//将服务器端返回的数据直接认定为是这个格式,然后会做一些自动的处理(如果是json字符串,会自动转化为js对象),服务器返回的默认格式是text/html格式
            data: {//向服务器端发送的数据
                isReplay: true
            },
            success: function (data) {//请求成功之后执行的回调函数
                window.location.href = "game.html";                
            },
            error: function(error){
                console.log(error)
            }
        });
 }

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

Step2后端接收到语音文件缓存下来

这一步有待优化,涉及到的IO比较多。

package com.yokna.homeworkhelper.service.impl;

import com.yokna.homeworkhelper.entity.RespMsg;
import com.yokna.homeworkhelper.service.UploadService;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.File;

@Service
public class UploadServiceImpl implements UploadService {

    @Override
    public RespMsg<String> upload(MultipartFile file) {
        if(file.isEmpty()) {
            return RespMsg.fail("400","上传的文件为空");
        }
        String originalFileName = file.getOriginalFilename();
        String newFileName = System.currentTimeMillis()+"."+ originalFileName;
        String filePath = "C:\\Users\\Yokna\\IdeaProjects\\homeworkhelper\\src\\main\\resources\\static\\voice\\";
        File dest = new File(filePath+newFileName);

        //判断是否存在这样的一个目录来存放我们上传的文件
        if (!dest.getParentFile().exists()){
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest);
        }catch (Exception e){
            e.printStackTrace();
            return RespMsg.fail("500","上传失败");
        }
        return RespMsg.success(filePath+newFileName);
    }
}

Step3转发给百度语音接口

package com.yokna.homeworkhelper.utils;

import com.baidu.aip.speech.AipSpeech;
import org.json.JSONObject;
import org.junit.Test;
import org.springframework.stereotype.Component;

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Component
public class BaiduVoice {
    //设置APPID/AK/SK
    public static final String APP_ID = "24287980";
    public static final String API_KEY = "gnXf3eNkMNIFSvrm91QSQioN";
    public static final String SECRET_KEY = "YPYtZ3Ny8iHyOpMEgd4DC0b9KO628G75";
    public static  HashMap<String,Integer> dict = new HashMap<String, Integer>(){
        {
            put("一",1);
            put("二",2);
            put("三",3);
            put("四",4);
            put("五",5);
            put("六",6);
            put("七",7);
            put("八",8);
            put("九",9);
            put("十",10);
            put("11",11);
            put("12",12);
            put("13",13);
            put("14",14);
            put("15",15);
            put("16",16);
            put("17",17);
        }
    };

    public int[] voice2word(String src){
        // 初始化一个AipSpeech
        AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);

        // 可选:设置网络连接参数
        client.setConnectionTimeoutInMillis(2000);
        client.setSocketTimeoutInMillis(60000);
        // 可选:设置log4j日志输出格式,若不设置,则使用默认配置
        // 也可以直接通过jvm启动参数设置此环境变量
        //System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
        // 调用接口
        JSONObject res = client.asr(src, "pcm", 16000, null);
        System.out.println(res.toString(2));
        String commandStr = (String) res.getJSONArray("result").get(0);
        int[] result = this.str2Integer(commandStr);

        return result;
    }

    public int[] str2Integer(String str){
        int[] result = new int[5];
//        str = "";
        String regex = "\u4e00|\u4e8c|\u4e09|\u56db|\u4e94|\u516d|\u4e03|\u516b|\u4e5d|\u5341|[10-18]";
        Pattern p = Pattern.compile(regex);
        Matcher m = p.matcher(str);
        int i = 0;
        while (m.find()){
//            System.out.println(m.start());
//            System.out.println(m.end());
//            System.out.println(str.substring(m.start(), m.end())+1);
            try{
                result[i] = dict.get(str.substring(m.start(),m.end()+1)+"");
            }catch (Exception e){
                continue;
            }
            i++;
//            System.out.println("i =" + i);
//            System.out.println(str.charAt(m.start()));
//            System.out.println(this.dict.get(str.charAt(m.start())+""));
//            System.out.println(m.start());
//            System.out.println(m.);
        }
        int[] tmp = new int[2];
        int k = 0;
        for (int j = 0 ; j < result.length ;j++){
            if (result[j] != 0){
                if (result[j] != 10){
                    tmp[k] = result[j];
                    k++;
                }else {
                    tmp[k] = result[j]+result[j+1];
                    j++;
                    k++;
                }
            }else continue;
        }

        return tmp;
    }

//    public int[] gobangVoiceAPI(String src){
//        this.str2Integer(voice2word(src));
//
//    }

    @Test
    public void test(){
        for (int res : str2Integer("第第11行行11列")) {
            System.out.println(res);
        }
    }
}

Step4处理百度语音返回的语音识别结果

package com.yokna.homeworkhelper.controller;

import com.yokna.homeworkhelper.entity.RespMsg;
import com.yokna.homeworkhelper.service.UploadService;
import com.yokna.homeworkhelper.utils.BaiduVoice;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

@CrossOrigin
@RestController
@RequestMapping(value = "voice2word",method = RequestMethod.POST)
public class VoiceController {
    @Autowired
    private BaiduVoice baiduVoice;
    @Autowired
    private UploadService uploadService;

    @RequestMapping("/store")
    public RespMsg storePCM(@RequestParam("voice") MultipartFile file){
        RespMsg respMsg = uploadService.upload(file);
        String newFileName = (String) respMsg.getBody();
        int[] result = baiduVoice.voice2word(newFileName);

        return RespMsg.success(result);
    }
}

五子棋其他逻辑在python后端,java后端只完成语音识别、识别到字符处理。具体后端详见之前发过的flask博文。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值