三方

android录音并通过百度识别将语音转文字遇到的坑

2019-09-14  本文已影响0人  大胡子的机器人

由于百度语音识别的语音文件格式必须固定且符合:

百度语音识别规则:原始 PCM 的录音参数必须符合 16k 采样率、16bit 位深、单声道,支持的格式有:pcm(不压缩)、wav(不压缩,pcm编码)、amr(压缩格式)。

因此,我尝试了3种方式(最终实现可行的方法在最后一个方法中):

一、通过 Ffmpeg 将录音文件amr转wav格式

在32位android系统没有问题,但是我们定制的android系统是64位,
Ffmpeg 的32位so库克参考这里下载(别人编译好的so库):
https://github.com/huangjingqiang/ffmpeg-library

然后通过以下类进行转换:

package cn.dxjia.ffmpeg.library;

import android.util.Log;

/**
 * 警告:该文件不可修改,包括包名和类名
 * 参考:https://github.com/huangjingqiang/ffmpeg-library
 */
public class FFmpegNativeHelper {
public FFmpegNativeHelper() {
}

static {
    System.loadLibrary("avutil-54");
    System.loadLibrary("swresample-1");
    System.loadLibrary("avcodec-56");
    System.loadLibrary("avformat-56");
    System.loadLibrary("swscale-3");
    System.loadLibrary("avfilter-5");
    System.loadLibrary("avdevice-56");
    System.loadLibrary("ffmpegjni");

}

public static String runCommand(String command) {
    if(command == null || command.length() == 0) {
        return "Command can`t be empty.";
    }
    String[] args = command.split(" ");
    for(int i = 0; i < args.length; i++) {
        Log.d("ffmpeg-jni", args[i]);
    }
    try {
        return ffmpeg_run(args);
    } catch (Exception e) {
        throw e;
    }
}

private static native int ffmpeg_init();
private static native int ffmpeg_uninit();
private static native String ffmpeg_run(String[] args);
}

//使用方法:
//final String command = "ffmpeg -i " + source + " -vn -acodec pcm_s16le -ab 256k -ac 1 -ar 16000 -f wav -y " + target;
//FFmpegNativeHelper.runCommand(command)

因此,想通过Ffmpeg编译64位的so库文件,编译方法参考:
https://blog.csdn.net/bobcat_kay/article/details/88843778
方法太过复杂,而且文档中说坑比较多,为了高效率,放弃该方法。

二、详查百度语音文档,尝试REST/sdk集成的方法

百度语音文档:https://ai.baidu.com/docs#/ASR-Online-Java-SDK/top

通过将amr文件通过json格式上传,但百度语音返回format错误,该错误一直误导我以为是format格式错误,反而被一直在找参数问题,更改header中的参数,更改format参数,但一直无效,最终想到了第三个方法,可能可以从录音文件源头下手


image.png
三、通过改写录音格式,从而解决问题

通过以下录音启动代码可以得到PCM编码、16k 采样率、16bit 位深的amr文件

this.muteAudioFocus(this.mAudioManager, true);
        this.mAudioManager.setMode(0);
        this.mMediaRecorder = new MediaRecorder();

        try {
            int bps = 7950;
            this.mMediaRecorder.setAudioSamplingRate(16000);  //设置录制的音频采样率
            this.mMediaRecorder.setAudioEncodingBitRate(bps);  //音频编码比特率
        } catch (Resources.NotFoundException var3) {
            var3.printStackTrace();
        }

        ////百度语音强调的是单声道,但我尝试单声道参数AudioFormat.CHANNEL_IN_MONO反而是录制启动就失败,报参数错误
        this.mMediaRecorder.setAudioChannels(AudioFormat.CHANNEL_IN_DEFAULT);
        this.mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
        this.mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.AMR_WB);//注意AMR_NB是8000采样率
        this.mMediaRecorder.setAudioEncoder(AudioFormat.ENCODING_PCM_16BIT);
        this.mAudioPath = Uri.fromFile(new File(SAVE_PATH, System.currentTimeMillis() + ".voice"));
        this.mMediaRecorder.setOutputFile(this.mAudioPath.getPath());
        this.mMediaRecorder.prepare();
        this.mMediaRecorder.start();
上一篇下一篇

猜你喜欢

热点阅读