随笔(十) mp3格式转pcm格式并调用百度语音识别

前言:

        近期做帮做毕业设计,需求里面要做语音识别,识别出用户朗读的文章,将识别出来的字符串返回给用户查看。这个想到的就只有百度开放平台的api了。

 

思路:

       ① 前往百度开放平台拿到APP_ID,API_KEY,SECRET_KEY    

       ② 用户本地录音后,将MP3或其他格式文件上传到服务器指定接口。

       ③ 服务器端将MP3格式转换成pcm格式(百度语音推荐格式)

       ④ 服务器将pcm格式文件发送到百度开放平台接口

       ⑤ 接收回馈信息,存入数据库,并返回给用户

 

准备工作:

      pom.xml文件:

     <!-- 文件格式转换包 -->
        <dependency>
            <groupId>com.googlecode.soundlibs</groupId>
            <artifactId>mp3spi</artifactId>
            <version>1.9.5.4</version>
        </dependency>
        <!-- json转换工具包 -->
        <dependency>
            <groupId>org.json</groupId>
            <artifactId>json</artifactId>
            <version>20180130</version>
        </dependency>

        <!-- 百度api工具 -->
        <dependency>
            <groupId>com.baidu.aip</groupId>
            <artifactId>java-sdk</artifactId>
            <version>4.7.0</version>
        </dependency>

开始开发:

import com.baidu.aip.speech.AipSpeech;

public class AudioSingleton {
    /**
     * 百度开放平台获取
     */
    private static final String APP_ID = "你的APP_ID";

    private static final String API_KEY = "你的API_KEY";

    private static final String SECRET_KEY = "你的SECRET_KEY";

    /**
     * 单例模式,jvm保证只生成一个单例
     */
    public static class AudioSingletonInstance {
        public static  AipSpeech aipSpeech = new AipSpeech(APP_ID,API_KEY,SECRET_KEY);
    }

    /**
     * 获取AipSpeech对象
     * @return
     */
    public static AipSpeech getInstance(){
        return AudioSingletonInstance.aipSpeech;
    }
}

       用于转换的Bean

import lombok.Data;

@Data
public class AudioBean {
    /**
     * 错误信息
     */
    private String err_msg;
    /**
     * 标识
     */
    private String sn;
    /**
     * 错误码
     */
    private Integer err_no;
    /**
     * 结果
     */
    private String result;
}
package com.english.listening.utils;

import com.baidu.aip.speech.AipSpeech;
import com.english.listening.exception.CheckException;
import com.english.listening.result.AudioBean;
import javazoom.spi.mpeg.sampled.file.MpegAudioFileReader;
import org.json.JSONObject;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import java.io.File;
import java.io.IOException;

public class AudioUtils {
    /**
     * @param mp3FilePath mp3文件路径
     * @param pcmFilePath 保存pcm文件路径
     */

    public static void mp3ToPcm(String mp3FilePath, String pcmFilePath) {
        //获取MP3文件的流
        AudioInputStream audioInputStream = getPcmAudioInputStream(mp3FilePath);
        try {
            //生成pcm文件
            AudioSystem.write(audioInputStream, AudioFileFormat.Type.WAVE, new File(pcmFilePath));
        } catch (IOException e) {
            e.printStackTrace();
        }

    }

    private static AudioInputStream getPcmAudioInputStream(String mp3filepath) {
        File mp3 = new File(mp3filepath);
        AudioInputStream audioInputStream = null;
        AudioFormat targetFormat = null;
        AudioInputStream in = null;
        try {

            //读取音频文件的类
            MpegAudioFileReader mp = new MpegAudioFileReader();

            in = mp.getAudioInputStream(mp3);
            AudioFormat baseFormat = in.getFormat();
            //设定输出格式为pcm格式的音频文件
            targetFormat = new AudioFormat(AudioFormat.Encoding.PCM_SIGNED, baseFormat.getSampleRate(), 16,
                    baseFormat.getChannels(), baseFormat.getChannels() * 2, baseFormat.getSampleRate(), false);
            //输出到音频
            audioInputStream = AudioSystem.getAudioInputStream(targetFormat, in);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            /**
             * 释放资源
             */
            free(audioInputStream, in);
        }
        return audioInputStream;
    }

    /**
     * 关闭流
     */
    private static void free(AudioInputStream audioInputStream, AudioInputStream in) {

        if (in != null) {
            try {
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (audioInputStream != null) {
            try {
                audioInputStream.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * 检查返回消息
     *
     * @param pcm
     */
    public static void CheckAudio(AudioBean pcm) {
        if (pcm.getErr_no() == 3301) {
            throw new CheckException("语音质量太差,请重新录音");
        }
        if (pcm.getErr_no() == 3309) {
            throw new CheckException("音频数据问题,请重新录音");
        }
    }

    /**
     * 语音识别返回文本
     *
     * @param pcmPath
     * @param voidetype
     * @return
     */

    public static AudioBean getBaiduMessage(String pcmPath, String voidetype) {
        AipSpeech instance = AudioSingleton.getInstance();
        instance.setConnectionTimeoutInMillis(2000);
        instance.setSocketTimeoutInMillis(6000);
        JSONObject asr = instance.asr(pcmPath, voidetype, 16000, null);
        AudioBean audioBean = JsonUtil.jsonToObject(asr.toString(), AudioBean.class);
        return audioBean;
    }


    public static void main(String[] args) {
        try {
            //百度开放平台下载的pcm文件
            String pcmPath = "E:\\16k.pcm";
            //随便找的MP3,用于格式转换
            AudioUtils.mp3ToPcm("E:\\60shongbao64.mp3", "E:\\60shongbao64.pcm");
            //讲返回格式转成bean
            AudioBean pcm = getBaiduMessage(pcmPath, "pcm");
            System.out.println(pcm);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

       这个不是正式服务端测试,直接用main方法调用返回。

测试:

   

总结:

        代码写的很烂,没有很好整理,不过暂时实现就好,不过语音识别有点无语,就是经常说啥语音质量太差,没办法。JsonUtil工具类需要找之前的博客吧,这里接不列出。CheckException这个类是自定义异常,可以删掉的。

 

程序人生,与君共勉~!

 

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值