语音合成完整版

百度语音集成简介

       近日因项目需要,查阅多方文档最终选择集成了一个百度的语音合成模块。在此为什么要选百度语音合成呢,因为百度重点声明此业务永久免费。这里我只集成了在线语音播放功能,该项目是在百度案例项目基础上二次开发,所以代码还是比较简洁规范的,有需要的朋友可以直接下载该项目集成到自己的项目中。至于离线语音合成就得需要的朋友自己上百度官方查阅相关文档了。

       通过学习本文章还可以重点掌握如何自定义一个preferences.xml

老规矩先贴图

1、项目目录
语音合成完整版_第1张图片

2、开始合成
语音合成完整版_第2张图片

3、相关设置
语音合成完整版_第3张图片

接下来就是干货环节

4、主页面

/**
 * TTS播放类
 * 
 * @author 康驻关
 */
public class demo_activity extends Activity implements OnClickListener, SpeechSynthesizerListener {
    private ImageButton moresetting, startOrPauseSpeech, stopSpeech;
    /** 输入合成文本 **/
    private EditText mInput;
    /** 显示合成状态 **/
    private TextView mShowText;
    /** 定义TTS **/
    private SpeechSynthesizer mSpeechSynthesizer;
    /** MESSAGE消息标识 **/
    private static final int PRINT = 0;
    private static final String TAG = "MainActivity";
    /** 判断当前播放状态,0表示停止播放,1表示播放中,2表示暂停播放 **/
    private static int flag = 0;

    private String description;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.demo_main);
        // 初始化控件
        initialView();
        // 初始化TTS;
        initialTts();

        Intent intent = getIntent();
        description = intent.getStringExtra("description");
    }

    /**
     * 初始化各个控件
     */
    private void initialView() {
        this.moresetting = (ImageButton) this.findViewById(R.id.moresetting);
        this.moresetting.setOnClickListener(this);
        this.startOrPauseSpeech = (ImageButton) this.findViewById(R.id.startOrPauseSpeech);
        this.startOrPauseSpeech.setOnClickListener(this);
        this.stopSpeech = (ImageButton) this.findViewById(R.id.stopSpeech);
        this.stopSpeech.setOnClickListener(this);
        this.mInput = (EditText) this.findViewById(R.id.inputTextView);
        this.mShowText = (TextView) this.findViewById(R.id.logView);
        this.mShowText.setMovementMethod(new ScrollingMovementMethod());
    }

    /**
     * 初始化TTS
     */
    private void initialTts() {
        // 获取tts实例
        this.mSpeechSynthesizer = SpeechSynthesizer.getInstance();
        // 设置app上下文(必需参数)
        this.mSpeechSynthesizer.setContext(this);
        // 设置tts监听器
        this.mSpeechSynthesizer.setSpeechSynthesizerListener(this);
        // 请替换为语音开发者平台注册应用得到的apikey和secretkey (在线授权)
        this.mSpeechSynthesizer.setApiKey("XQ4QTvPpdw0dhutVUSBzxAn5iQtZwcHw", "a0QcGOC4MW1DIqZWn7h0xgSY3pnRqmR8");
        // 初始化tts各参数
        initTTSParam(this.mSpeechSynthesizer);
        // 授权检测接口(可以不使用,只是验证授权是否成功)
        AuthInfo authInfo = this.mSpeechSynthesizer.auth(TtsMode.MIX);
        if (authInfo.isSuccess()) {
            toPrint("auth success");
        } else {
            String errorMsg = authInfo.getTtsError().getDetailMessage();
            toPrint("auth failed errorMsg=" + errorMsg);
        }
        /**
         * 初始化 tts引擎,可以指定使用online在线,或者 mix离在线混合引擎 .
         * mix离在线混合引擎会在online在线不能用的情况下自动使在线offline离线引擎 具体参数清查看文档
         */
        mSpeechSynthesizer.initTts(TtsMode.MIX);
    }

    /**
     * 在调用 在调用 speak 方法开始合成 并朗读之前,可以对参数进行配置(未设置的参数将使用默认值)
     * 
     * @param SpeechSynthesizer
     */
    private void initTTSParam(SpeechSynthesizer speechSynthesizer) {
        // 发音人(在线引擎),可用参数为0,1,2,3。。。(服务器端会动态增加,各值含义参考文档,以文档说明为准。0--普通女声,1--普通男声,2--特别男声,3--情感男声。。。)默认0
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0");
        // 调整音量 ,范围 [0-9],默认为5
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "5");
        // 调整语速 ,范围 [0-9],默认为5
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "5");
        // 调整语调,范围 [0-9],默认为5
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");
        // 设置Mix模式的合成策略,默认MIX_MODE_DEFAULT, 其它参数请参考文档
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_MIX_MODE, SpeechSynthesizer.MIX_MODE_HIGH_SPEED_NETWORK);
        // 设置音频格式,默认AUDIO_ENCODE_AMR
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_ENCODE, SpeechSynthesizer.AUDIO_ENCODE_AMR);
        // 设置比特率,默认AUDIO_BITRATE_AMR_15K
        speechSynthesizer.setParam(SpeechSynthesizer.PARAM_AUDIO_RATE, SpeechSynthesizer.AUDIO_BITRATE_AMR_12K65);
    }

    /*
     * 当退出时销毁TTS
     */
    @Override
    protected void onDestroy() {
        this.mSpeechSynthesizer.release();
        super.onDestroy();
    }

    /**
     * 获取EditView上的文字合成语音
     */
    private void speak() {
        String text = this.mInput.getText().toString(); // 获取EditView上的文字
        // 该接口比较耗时,采用排队策略调后将自动加入合成列并按顺序进行和播放 该接口比较耗时,采用排队策略调后将自动加入合成列并按顺序进行合成和播放

        int result = this.mSpeechSynthesizer.speak(text);

        /**
         * speak(String text,String utteranceId); utteranceId参数用来指定此次文本合成标识
         * 该接口和sprak(String Text)接口功能相同 详细使用请参照开发文档
         */
        // int result = this.mSpeechSynthesizer.speak("你好","1");
        // this.mSpeechSynthesizer.speak("我好","2");
        // this.mSpeechSynthesizer.speak("大家好","3");

        // 判断是否合成成功
        if (result < 0) {
            toPrint("error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
        }
    }

    /**
     * 暂停播放
     */
    private void pause() {
        this.mSpeechSynthesizer.pause();
        flag = 2; // 将播放状态改为暂停播放
    }

    /**
     * 恢复播放
     */
    private void resume() {
        this.mSpeechSynthesizer.resume();
        flag = 1; // 将播放状态改为播放中
    }

    /**
     * 停止播放,清除合成缓存
     */
    private void stop() {
        this.mSpeechSynthesizer.stop();
        flag = 0; // 将播放状态改为停止播放
    }

    /**
     * 此接口实现只合成不播放,可用于网络较差时的缓存策略
     */
    private void synthesize() {
        String text = this.mInput.getText().toString();
        int result = this.mSpeechSynthesizer.synthesize(text);
        if (result < 0) {
            toPrint("error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
        }
    }

    /**
     * 批量合成播放接口
     */
    private void batchSpeak() {
        List bags = new ArrayList();
        bags.add(getSpeechSynthesizeBag("123456", "0"));
        bags.add(getSpeechSynthesizeBag("你好", "1"));
        bags.add(getSpeechSynthesizeBag("使用百度语音合成SDK", "2"));
        bags.add(getSpeechSynthesizeBag("hello", "3"));
        bags.add(getSpeechSynthesizeBag("这是一个demo工程", "4"));
        int result = this.mSpeechSynthesizer.batchSpeak(bags);
        if (result < 0) {
            toPrint("error,please look up error code in doc or URL:http://yuyin.baidu.com/docs/tts/122 ");
        }
    }

    /**
     * @param text
     *            合成文本
     * @param utteranceId
     *            标识ID
     * @return
     */
    private SpeechSynthesizeBag getSpeechSynthesizeBag(String text, String utteranceId) {
        SpeechSynthesizeBag speechSynthesizeBag = new SpeechSynthesizeBag();
        speechSynthesizeBag.setText(text);
        speechSynthesizeBag.setUtteranceId(utteranceId);
        return speechSynthesizeBag;
    }

    /**
     * 开始合成
     * 
     * @param arg0
     *            arg0对应 speak中的utteranceId参数
     */
    @Override
    public void onSynthesizeStart(String utteranceId) {
        toPrint("onSynthesizeStart utteranceId=" + utteranceId);
    }

    /**
     * @param arg0
     * @param arg1
     * @param arg2
     */
    @Override
    public void onSynthesizeDataArrived(String utteranceId, byte[] data, int progress) {
        // toPrint("onSynthesizeDataArrived");
    }

    /**
     * 完成合成
     * 
     * @param arg0
     *            arg0对应 speak中的utteranceId参数
     */
    @Override
    public void onSynthesizeFinish(String utteranceId) {
        toPrint("onSynthesizeFinish utteranceId=" + utteranceId);
    }

    /**
     * 播放开始
     * 
     * @param arg0
     *            arg0对应 speak中的utteranceId参数
     */
    @Override
    public void onSpeechStart(String utteranceId) {
        toPrint("onSpeechStart utteranceId=" + utteranceId);
    }

    /*
     * @param arg0
     * 
     * @param arg1
     */
    @Override
    public void onSpeechProgressChanged(String utteranceId, int progress) {
        // toPrint("onSpeechProgressChanged");
    }

    /**
     * 播放完成
     * 
     * @param arg0
     *            arg0对应 speak中的utteranceId参数
     */
    @Override
    public void onSpeechFinish(String utteranceId) {
        toPrint("onSpeechFinish utteranceId=" + utteranceId);
        flag = 0; // 将播放状态改为停止播放
        setImageButtonBG(this.startOrPauseSpeech, 1);
    }

    /**
     * 合成出错
     * 
     * @param arg0
     * @param arg1
     */
    @Override
    public void onError(String utteranceId, SpeechError error) {
        toPrint("onError error=" + "(" + error.code + ")" + error.description + "--utteranceId=" + utteranceId);
    }

    /**
     * 用于处理UI
     */
    private Handler mHandler = new Handler() {

        /*
         * @param msg
         */
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            int what = msg.what;
            switch (what) {
            case PRINT:
                print(msg); // 将合成信息写入TextView
                break;

            default:
                break;
            }
        }

    };

    /**
     * 将信息封装到Message中发送个handler
     * 
     * @param str
     */
    private void toPrint(String str) {
        Message msg = Message.obtain();
        msg.obj = str;
        this.mHandler.sendMessage(msg);
    }

    /**
     * 将封装到Message中的信息解析成字符串
     * 
     * @param msg
     */
    private void print(Message msg) {
        String message = (String) msg.obj;
        if (message != null) {
            Log.w(TAG, message);
            Toast.makeText(this, message, Toast.LENGTH_SHORT).show();
            scrollLog(message);
        }
    }

    /**
     * 对消息进行处理显示在TextView中
     * 
     * @param message
     */
    private void scrollLog(String message) {
        Spannable colorMessage = new SpannableString(message + "\n");
        // 设置字符串颜色
        colorMessage.setSpan(new ForegroundColorSpan(0xff0000ff), 0, message.length(),
                Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
        mShowText.append(colorMessage);
        Layout layout = mShowText.getLayout();
        if (layout != null) {
            int scrollAmount = layout.getLineTop(mShowText.getLineCount()) - mShowText.getHeight();
            if (scrollAmount > 0) {
                mShowText.scrollTo(0, scrollAmount + mShowText.getCompoundPaddingBottom());
            } else {
                mShowText.scrollTo(0, 0);
            }
        }
    }

    @Override
    public void onClick(View v) {
        int id = v.getId();
        switch (id) {
        case R.id.moresetting: {
            Intent intent = new Intent(demo_activity.this, SettingsActivity.class);
            startActivity(intent);
            break;
        }
        case R.id.startOrPauseSpeech: {
            if (flag == 0) {
                // 开始播放
                speak();
                flag = 1; // 将播放状态改为播放中
                setImageButtonBG(this.startOrPauseSpeech, 0);
            } else if (flag == 1) {
                // 暂停播放
                pause();
                flag = 2; // 将播放状态改为暂停播放
                setImageButtonBG(this.startOrPauseSpeech, 1);
            } else if (flag == 2) {
                // 恢复播放
                resume();
                flag = 1; // 将播放状态改为播放中
                setImageButtonBG(this.startOrPauseSpeech, 0);
            }
            break;
        }
        case R.id.stopSpeech:
            stop();
            break;
        default:
            break;
        }
    }

    /**
     * 给imageButton设置背景图,0表示设置暂停背景,1表示设置播放背景,
     * 
     * @param imageButton
     * @param flag
     */
    private void setImageButtonBG(ImageButton imageButton, int flag) {
        if (flag == 0)
            imageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_pause));
        else if (flag == 1)
            imageButton.setImageDrawable(getResources().getDrawable(R.drawable.ic_action_play));
    }
}

5、设置页面

/**
 * TTS设置类
 * @author 康驻关
 */
public class SettingsActivity extends PreferenceActivity implements SharedPreferences.OnSharedPreferenceChangeListener {
    public static final String KEY_PREF_AUDIO_ENCODE = "pref_audio_encode";
    public static final String KEY_PREF_AUDIO_RATE = "pref_audio_rate";
    public static final String KEY_PREF_SPEAKER = "pref_speaker";
    public static final String KEY_PREF_SPEECH_PITCH = "pref_speech_pitch";
    public static final String KEY_PREF_SPEECH_SPEED = "pref_speech_speed";
    public static final String KEY_PREF_SPEECH_VOLUME = "pref_speech_volume";

    private void changeRateSet() {
        ListPreference localListPreference1 = (ListPreference) findPreference("pref_audio_encode");
        ListPreference localListPreference2 = (ListPreference) findPreference("pref_audio_rate");
        String str = localListPreference1.getValue();
        int i = localListPreference2.findIndexOfValue(localListPreference2.getValue());
        if (str.equals("0")) {
            localListPreference2.setEntries(R.array.pref_bv_rate_entries);
            int n = getResources().getStringArray(R.array.pref_bv_rate_entries).length;
            if (i > n - 1)
                localListPreference2.setValueIndex(n - 1);
        } else if (str.equals("1")) {
            localListPreference2.setEntries(R.array.pref_amr_rate_entries);
            int m = getResources().getStringArray(R.array.pref_amr_rate_entries).length;
            if (i > m - 1)
                localListPreference2.setValueIndex(m - 1);
        } else if (str.equals("2")) {
            localListPreference2.setEntries(R.array.pref_opus_rate_entries);
            int m = getResources().getStringArray(R.array.pref_opus_rate_entries).length;
            if (i > m - 1)
                localListPreference2.setValueIndex(m - 1);
        } else if (str.equals("3")) {
            localListPreference2.setEntries(R.array.pref_mp3_rate_entries);
            int m = getResources().getStringArray(R.array.pref_mp3_rate_entries).length;
            if (i > m - 1)
                localListPreference2.setValueIndex(m - 1);
        }

    }

    private void setSummaryForListPref(SharedPreferences paramSharedPreferences, String paramString) {
        ListPreference localListPreference = (ListPreference) findPreference(paramString);
        int i = localListPreference.findIndexOfValue(paramSharedPreferences.getString(paramString, "0"));
        String str = localListPreference.getEntries()[i].toString();
        localListPreference.setSummary("当前设置为:" + str);
    }

    private void setSummaryForNumPickerPref(SharedPreferences paramSharedPreferences, String paramString) {
        Preference localPreference = findPreference(paramString);
        if (Build.VERSION.SDK_INT >= 11) {
            String str = paramSharedPreferences.getString(paramString, "5");
            localPreference.setSummary("当前设置为:" + str);
            return;
        }
        String str = paramSharedPreferences.getString(paramString, "5");
        localPreference.setSummary("当前设置为:" + str);
    }

    public void onCreate(Bundle paramBundle) {
        super.onCreate(paramBundle);
        addPreferencesFromResource(R.xml.preferences);
    }

    public void onPause() {
        getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);
        super.onPause();
    }

    public void onResume() {
        getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);
        super.onResume();
        SharedPreferences localSharedPreferences = getPreferenceScreen().getSharedPreferences();
        setSummaryForNumPickerPref(localSharedPreferences, "pref_speech_volume");
        setSummaryForNumPickerPref(localSharedPreferences, "pref_speech_speed");
        setSummaryForNumPickerPref(localSharedPreferences, "pref_speech_pitch");
        setSummaryForListPref(localSharedPreferences, "pref_speaker");
        setSummaryForListPref(localSharedPreferences, "pref_audio_encode");
        changeRateSet();
        setSummaryForListPref(localSharedPreferences, "pref_audio_rate");
    }

    public void onSharedPreferenceChanged(SharedPreferences paramSharedPreferences, String paramString) {
        if ((paramString.equals("pref_speech_speed")) || (paramString.equals("pref_speech_pitch"))
                || (paramString.equals("pref_speech_volume")))
            setSummaryForNumPickerPref(paramSharedPreferences, paramString);
        if ((paramString.equals("pref_audio_encode")) || (paramString.equals("pref_speaker"))
                || (paramString.equals("pref_audio_rate")))
            setSummaryForListPref(paramSharedPreferences, paramString);
        if (paramString.equals("pref_audio_encode")) {
            changeRateSet();
            setSummaryForListPref(paramSharedPreferences, "pref_audio_rate");
        }
    }
    @Override
    protected void onStop() {
        super.onStop();
        this.finish();
    }
}

资源文件

6、自定义preferences

"1.0" encoding="utf-8"?>
"http://schemas.android.com/apk/res/android"
    xmlns:custom="http://schemas.android.com/apk/res-auto" >

    "pref_common_settings"
        android:title="@string/pref_common_settings_title" >
        "@string/pref_speaker_default"
            android:dialogTitle="@string/pref_speaker"
            android:entries="@array/pref_speaker_entries"
            android:entryValues="@array/pref_speaker_values"
            android:key="pref_speaker"
            android:title="@string/pref_speaker" />
        "@string/pref_speech_volume_default"
            android:dialogTitle="@string/pref_speech_volume"
            android:entries="@array/pref_speech_volume_entries"
            android:entryValues="@array/pref_speech_volume_values"
            android:key="pref_speech_volume"
            android:title="@string/pref_speech_volume" />
        "@string/pref_speech_speed_default"
            android:dialogTitle="@string/pref_speech_speed"
            android:entries="@array/pref_speech_speed_entries"
            android:entryValues="@array/pref_speech_speed_values"
            android:key="pref_speech_speed"
            android:title="@string/pref_speech_speed" />
        "@string/pref_speech_pitch_default"
            android:dialogTitle="@string/pref_speech_pitch"
            android:entries="@array/pref_speech_pitch_entries"
            android:entryValues="@array/pref_speech_pitch_values"
            android:key="pref_speech_pitch"
            android:title="@string/pref_speech_pitch" />
    </PreferenceCategory>
    " >
        @string/pref_audio_encode_default"
            android:dialogTitle="@string/pref_audio_encode"
            android:entries="@array/pref_audioEncode_entries"
            android:entryValues="@array/pref_audioEncode_values"
            android:key="pref_audio_encode"
            android:title="@string/pref_audio_encode" />
        @string/pref_amr_rate_default"
            android:dialogTitle="@string/pref_audio_rate"
            android:entries="@array/pref_amr_rate_entries"
            android:entryValues="@array/pref_amr_rate_values"
            android:key="pref_audio_rate"
            android:title="@string/pref_audio_rate" />
    

7、主界面


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:orientation="vertical"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin" 
    android:focusable="true"
    android:focusableInTouchMode="true"
    >

    <TextView
        android:id="@+id/logView"
        android:layout_width="fill_parent"
        android:layout_height="0.0dip"
        android:layout_weight="2.0"
        android:background="@+drawable/back_border"
        android:freezesText="true"
        android:hint="@string/logViewHint"
        android:padding="12.0dip"
        android:scrollbars="vertical" />

    <EditText
        android:id="@+id/inputTextView"
        android:layout_width="fill_parent"
        android:layout_height="0.0dip"
        android:layout_weight="2.0"
        android:gravity="center|left|top"
        android:hint="@string/inputHint" />

    <LinearLayout
        android:id="@+id/controlBar"
        android:layout_width="fill_parent"
        android:layout_height="0.0dip"
        android:layout_weight="1.0" >

        <ImageButton
            android:id="@+id/moresetting"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:background="?android:selectableItemBackground"
            android:contentDescription="@string/start"
            android:src="@+drawable/ic_action_settings" />

        <ImageButton
            android:id="@+id/startOrPauseSpeech"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:background="?android:selectableItemBackground"
            android:contentDescription="@string/start"
            android:src="@+drawable/ic_action_play" />

        <ImageButton
            android:id="@+id/stopSpeech"
            android:layout_width="0.0dip"
            android:layout_height="fill_parent"
            android:layout_weight="1.0"
            android:background="?android:selectableItemBackground"
            android:contentDescription="@string/start"
            android:src="@+drawable/ic_action_stop" />
    LinearLayout>

LinearLayout>

       其他资源文件就不一一列出了,需要的朋友直接下载完整项目,本人还是比较喜欢百度提供的开发平台,毕竟免费就是坑比较多需要自己慢慢研究

项目下载地址  http://download.csdn.net/detail/kzg_ip/9584611

你可能感兴趣的:(安卓)