百度语音合成

1.在百度语音的控制台创建一个应用,输入应用名称、包名等信息
2.进入应用会看到sdk下载,进去后选择 语音合成–离在线融合SDK(这里只使用语音合成功能),下载该sdk
3.下载后打开里面是一个as的应用,可以自己运行然后看看代码逻辑。
4.将app–lib下的jar包拷贝到自己项目的app-lib下。然后鼠标右键添加到自己项目的库中
5.将app-src-main下的jniLibs整个文件夹拷贝到自己项目对应的位置,如果自己的项目有了该文件夹,就将jniLibs文件夹下个各个文件夹中so库分别复制到对应文件夹。
6.将app-src下的assets文件拷贝到自己项目对应位置,如果自己的项目有了该文件夹,就将assets文件夹下所有文件拷贝到对应文件夹。
7.将app-src下的control、listener、util文件夹拷贝到项目中,MainHandlerConstant.Java文件拷贝到项目中。
4.这里只是使用了精简版的语音合成,自己提取了一个工具类,然后外部直接调用方法传递需要合成的文字就可以
AndroidManifest.xml

 //添加以下权限
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
    <uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_SETTINGS"/>
    <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>

SpeakVoiceUtil.Java

/**
 * Created by YSG on 2018/3/8.
 */

public class SpeakVoiceUtil {
    private static final String TEXT = "欢迎使用百度语音合成,请在代码中修改合成文本";


    // ================== 初始化参数设置开始 ==========================
    /**
     * 发布时请替换成自己申请的appId appKey 和 secretKey。注意如果需要离线合成功能,请在您申请的应用中填写包名。
     * 本demo的包名是com.baidu.tts.sample,定义在build.gradle中。
     */
    protected String appId = "*******";

    protected String appKey = "*******";

    protected String secretKey = "*******";

    /**
     * TtsMode.MIX; 离在线融合,在线优先; TtsMode.ONLINE 纯在线; 没有纯离线
     */
    private TtsMode ttsMode = TtsMode.ONLINE;

    /**
     * ================选择TtsMode.ONLINE  不需要设置以下参数; 选择TtsMode.MIX 需要设置下面2个离线资源文件的路径
     * 重要!请手动将assets目录下的3个dat 文件复制到该目录
     */
    private static final String TEMP_DIR = "/sdcard/baiduTTS";

    /**
     * 请确保该PATH下有这个文件
     */
    private static final String TEXT_FILENAME = TEMP_DIR + "/" + "bd_etts_text.dat";

    /**
     * 请确保该PATH下有这个文件 ,m15是离线男声
     */
    private static final String MODEL_FILENAME = TEMP_DIR + "/" +
            "bd_etts_common_speech_m15_mand_eng_high_am-mix_v3.0.0_20170505.dat";

    /**
     * ===============初始化参数设置完毕,更多合成参数请至getParams()方法中设置 =================
     */

    protected SpeechSynthesizer mSpeechSynthesizer;

    // =========== 以下为UI部分 ==================================================

    private static SpeakVoiceUtil speakVoiceUtil;

    public static SpeakVoiceUtil getInstance(Context context) {
        if (speakVoiceUtil == null) {
            synchronized (SpeakVoiceUtil.class) {
                if (speakVoiceUtil == null) {
                    speakVoiceUtil = new SpeakVoiceUtil(context);
                }
            }
        }
        return speakVoiceUtil;
    }

    public SpeakVoiceUtil(final Context context) {
        initTTs(context);
    }

    /**
     * 注意此处为了说明流程,故意在UI线程中调用。
     * 实际集成中,该方法一定在新线程中调用,并且该线程不能结束。具体可以参考NonBlockSyntherizer的写法
     *
     * @param context
     */
    private void initTTs(Context context) {
        // 日志打印在logcat中
        LoggerProxy.printable(true);
        boolean isMix = ttsMode.equals(TtsMode.MIX);
        boolean isSuccess;
        if (isMix) {
            // 检查2个离线资源是否可读
            isSuccess = checkOfflineResources();
            if (!isSuccess) {
                return;
            } else {
                print("离线资源存在并且可读, 目录:" + TEMP_DIR);
            }
        }
        // 日志更新在UI中,可以换成MessageListener,在logcat中查看日志
        SpeechSynthesizerListener listener = new MessageListener();

        // 1. 获取实例
        mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        mSpeechSynthesizer.setContext(context);

        // 2. 设置listener
        mSpeechSynthesizer.setSpeechSynthesizerListener(listener);

        // 3. 设置appId,appKey.secretKey
        int result = mSpeechSynthesizer.setAppId(appId);
        checkResult(result, "setAppId");
        result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
        checkResult(result, "setApiKey");

        // 4. 支持离线的话,需要设置离线模型
        if (isMix) {
            // 检查离线授权文件是否下载成功,离线授权文件联网时SDK自动下载管理,有效期3年,3年后的最后一个月自动更新。
            isSuccess = checkAuth();
            if (!isSuccess) {
                return;
            }
            // 文本模型文件路径 (离线引擎使用), 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            // 声学模型文件路径 (离线引擎使用), 注意TEXT_FILENAME必须存在并且可读
            mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE,
                    MODEL_FILENAME);
        }

        // 5. 以下setParam 参数选填。不填写则默认值生效
        // 设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 设置合成的音量,0-9 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "9");
        // 设置合成的语速,0-9 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 设置合成的语调,0-9 ,默认 5
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");

        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer
                .MIX_MODE_DEFAULT);
        // 该参数设置为TtsMode.MIX生效。即纯在线模式不生效。
        // MIX_MODE_DEFAULT 默认 ,wifi状态下使用在线,非wifi离线。在线状态下,请求超时6s自动转离线
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线,非wifi离线。在线状态下, 请求超时1.2s自动转离线
        // MIX_MODE_HIGH_SPEED_NETWORK , 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线
        // MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线

        mSpeechSynthesizer.setAudioStreamType(AudioManager.MODE_IN_CALL);

        // x. 额外 : 自动so文件是否复制正确及上面设置的参数
        Map params = new HashMap<>();
        // 复制下上面的 mSpeechSynthesizer.setParam参数
        // 上线时请删除AutoCheck的调用
        if (isMix) {
            params.put(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME);
            params.put(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME);
        }
        InitConfig initConfig = new InitConfig(appId, appKey, secretKey, ttsMode, params, listener);
        AutoCheck.getInstance(context).check(initConfig, new Handler() {
            @Override
            /**
             * 开新线程检查,成功后回调
             */ public void handleMessage(Message msg) {
                if (msg.what == 100) {
                    AutoCheck autoCheck = (AutoCheck) msg.obj;
                    synchronized (autoCheck) {
                        String message = autoCheck.obtainDebugMessage();
                        //                        print(message); // 可以用下面一行替代,在logcat中查看代码
                        Log.w("AutoCheckMessage", message);
                    }
                }
            }

        });

        // 6. 初始化
        result = mSpeechSynthesizer.initTts(ttsMode);
        checkResult(result, "initTts");

    }

    /**
     * 检查appId ak sk 是否填写正确,另外检查官网应用内设置的包名是否与运行时的包名一致。本demo的包名定义在build.gradle文件中
     *
     * @return
     */
    private boolean checkAuth() {
        AuthInfo authInfo = mSpeechSynthesizer.auth(ttsMode);
        if (!authInfo.isSuccess()) {
            // 离线授权需要网站上的应用填写包名。本demo的包名是com.baidu.tts.sample,定义在build.gradle中
            String errorMsg = authInfo.getTtsError().getDetailMessage();
            print("【error】鉴权失败 errorMsg=" + errorMsg);
            return false;
        } else {
            print("验证通过,离线正式授权文件存在。");
            return true;
        }
    }

    /**
     * 检查 TEXT_FILENAME, MODEL_FILENAME 这2个文件是否存在,不存在请自行从assets目录里手动复制
     *
     * @return
     */
    private boolean checkOfflineResources() {
        String[] filenames = {TEXT_FILENAME, MODEL_FILENAME};
        for (String path : filenames) {
            File f = new File(path);
            if (!f.canRead()) {
                print("[ERROR] 文件不存在或者不可读取,请从assets目录复制同名文件到:" + path);
                print("[ERROR] 初始化失败!!!");
                return false;
            }
        }
        return true;
    }

    public void speak(String string) {
        /* 以下参数每次合成时都可以修改
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
         *  设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "5"); 设置合成的音量,0-9 ,默认 5
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5"); 设置合成的语速,0-9 ,默认 5
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5"); 设置合成的语调,0-9 ,默认 5
         *
         *  mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer
         *  .MIX_MODE_DEFAULT);
         *  MIX_MODE_DEFAULT 默认 ,wifi状态下使用在线,非wifi离线。在线状态下,请求超时6s自动转离线
         *  MIX_MODE_HIGH_SPEED_SYNTHESIZE_WIFI wifi状态下使用在线,非wifi离线。在线状态下, 请求超时1.2s自动转离线
         *  MIX_MODE_HIGH_SPEED_NETWORK , 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线
         *  MIX_MODE_HIGH_SPEED_SYNTHESIZE, 2G 3G 4G wifi状态下使用在线,其它状态离线。在线状态下,请求超时1.2s自动转离线
         */

        if (mSpeechSynthesizer == null) {
            print("[ERROR], 初始化失败");
            return;
        }
        int result = mSpeechSynthesizer.speak(string);
        print("合成并播放 按钮已经点击");
        checkResult(result, "speak");
    }

    private void print(String message) {
        LogUtil.logD(message);
    }

    private void checkResult(int result, String method) {
        if (result != 0) {
            print("error code :" + result + " method:" + method + ", 错误码文档:http://yuyin.baidu" +
                    ".com/docs/tts/122 ");
        }
    }

    public void cancelResource() {
        if (mSpeechSynthesizer != null) {
            mSpeechSynthesizer.stop();
            mSpeechSynthesizer.release();
            mSpeechSynthesizer = null;
            LogUtil.logD("释放资源成功");
        }
    }

}

注意:需要修改appid、appKey、secretKey 将这三个数据替换为自己的,这里只是将demo中的代码提取出来做了个简单的工具类
SpeakVoiceUtil.getInstance(getApplicationContext()).speak(“需要合成的文字”);

你可能感兴趣的:(语音开发)