智能语音转换文字——百度API

发布时间:2022-08-19 12:51

智能语音转换文字——百度API_第1张图片

 

想实现一个功能——即通过语音转换为文字进行写博客(个人博客)

百度API很好提供了这个功能——语音技术 (baidu.com)

新用户有五万次的免费请求次数,使用也不难,申请成功之后区控制台添加应用即可看到对应三个码

智能语音转换文字——百度API_第2张图片

 复制好这三个码,后面有用。

使用步骤:

1.导入依赖


    com.baidu.aip
    java-sdk
    ${version}

2.写一个类用来发起请求百度API(官方有提供)

public class Sample {

    //设置APPID/AK/SK
    public static final String APP_ID = "你的APP_ID ";
    public static final String API_KEY = "你的API_KEY ";
    public static final String SECRET_KEY = "你的SECRET_KEY ";

    public static String basePath;
    {
        try {
            basePath = ResourceUtils.getURL("classpath:"+File.separator+"sounds").getPath();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }
    }

    public String getString(){ //自己根据需求修改的,作用是录音并获得对应的文字结果
        String filename= UUID.randomUUID().toString();
        File file = new File(basePath+File.separator+filename+".wav");
        if(!file.getParentFile().exists()){ //如果文件的目录不存在
            file.getParentFile().mkdirs(); //创建目录
            System.out.println("创建目录");
        }
        if (!file.exists()){
            try {
                file.createNewFile();//创建文件
                System.out.println("创建文件-->"+file.getPath());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

            // 初始化一个AipSpeech
            AipSpeech client = new AipSpeech(APP_ID, API_KEY, SECRET_KEY);

            // 可选:设置网络连接参数
            client.setConnectionTimeoutInMillis(2000);
            client.setSocketTimeoutInMillis(60000);

            HashMapmap=new HashMap<>();
            map.put("dev_pid",1537);

            EngineeCore engineeCore=new EngineeCore(filename);
            engineeCore.startRecognize();
            if (!engineeCore.success){
                return "";
            }
            // 调用接口
            JSONObject res = client.asr(filename, "wav", 16000, map);
            Object  result = res.get("result");//返回结果是JSON,所以从中取值即可

            return StrUtils.getFormatStr(result.toString());//StrUtils是自己写的工具类,转化String
        }
}



public class StrUtils {//工具类转化String
    public static String getFormatStr(String result){
        return result.substring(2,result.length()-2);
    }

}

这个类的方法是用来将语音文件转化为文字的,但是我们的语音文件呢?从哪来?我的需求是通过录音实时地将语音转化为文字,所以我需要做两件事:

1.录音 2.将录音文件按照百度API的要求存储格式

很幸运,这两件事网上已经有大佬实现了,参考文章

 
  

我根据自己的要求对它修改了一下,改成同步而不是多线程的方式。这显然更符合我的要求:

public class EngineeCore {
    private String filePath;

    public EngineeCore(String filePath) {
        this.filePath = filePath;
    }


    AudioFormat audioFormat;
    TargetDataLine targetDataLine;
    boolean flag = true;
    public boolean success=false;
    int cnt=3;

    private void stopRecognize() {
        flag = false;
        targetDataLine.stop();
        targetDataLine.close();
    }

    private AudioFormat getAudioFormat() {
        float sampleRate = 16000;
        // 8000,11025,16000,22050,44100
        int sampleSizeInBits = 16;
        // 8,16
        int channels = 1;
        // 1,2
        boolean signed = true;
        // true,false
        boolean bigEndian = false;
        // true,false
        return new AudioFormat(sampleRate, sampleSizeInBits, channels, signed, bigEndian);
    }// end getAudioFormat


    public void startRecognize() {
        try {
            // 获得指定的音频格式
            audioFormat = getAudioFormat();
            DataLine.Info dataLineInfo = new DataLine.Info(TargetDataLine.class, audioFormat);
            targetDataLine = (TargetDataLine) AudioSystem.getLine(dataLineInfo);

            flag = true;
            AudioFileFormat.Type fileType = null;
            File audioFile = new File(filePath);

            fileType = AudioFileFormat.Type.WAVE;
            //声音录入的权值
            int weight = 2;
            //判断是否停止的计数
            int downSum = 0;

            ByteArrayInputStream bais = null;
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            AudioInputStream ais = null;
            try {
                targetDataLine.open(audioFormat);
                targetDataLine.start();
                byte[] fragment = new byte[1024];

                ais = new AudioInputStream(targetDataLine);
                while (flag) {
                    targetDataLine.read(fragment, 0, fragment.length);
                    //当数组末位大于weight时开始存储字节(有声音传入),一旦开始不再需要判断末位
                    if (Math.abs(fragment[fragment.length - 1]) > weight || baos.size() > 0) {
                        baos.write(fragment);
                        if(cnt>0){
                            System.out.println("录音中..");
                            cnt--;
                        }

//                        System.out.println("守卫:" + fragment[0] + ",末尾:" + fragment[fragment.length - 1] + ",lenght" + fragment.length);
                        //判断语音是否停止
                        if (Math.abs(fragment[fragment.length - 1]) <= weight) {
                            downSum++;
                        } else {
//                            System.out.println("重置奇数");
                            downSum = 0;
                        }//计数超过20说明此段时间没有声音传入(值也可更改)
                        if (downSum > 20) {
                            System.out.println("停止录入");
                            break;
                        }
                    }
                }

                //取得录音输入流
                audioFormat = getAudioFormat();
                byte audioData[] = baos.toByteArray();
                bais = new ByteArrayInputStream(audioData);
                ais = new AudioInputStream(bais, audioFormat, audioData.length / audioFormat.getFrameSize());
                //定义最终保存的文件名
                System.out.println("开始生成语音文件");
                AudioSystem.write(ais, AudioFileFormat.Type.WAVE, audioFile);
                downSum = 0;
                success=true;//表示录音成功
                stopRecognize();

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                //关闭流
                try {
                    ais.close();
                    bais.close();
                    baos.reset();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        } // end catch
    }// end captureAudio method



    public static void main(String args[]) {
        String filename="";
        EngineeCore engineeCore = new EngineeCore(filename);

        engineeCore.startRecognize();

    }
}

现在基本上已经很少在C站发文了,笔记也是写在自己的博客上面,虽然还比较简陋,但也足够我个人使用了。感兴趣的兄弟,欢迎访问——点我

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号