文字转语音代码记录

一、百度语音合成部分
package com.example.raisesail.zftts;

import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.media.AudioManager;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Button;
import android.widget.TextView;

import com.baidu.tts.auth.AuthInfo;
import com.baidu.tts.client.SpeechSynthesizer;
import com.baidu.tts.client.TtsMode;

import java.io.File;
import java.util.Random;
import android.net.wifi.WifiManager;
import android.content.BroadcastReceiver;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.WifiInfo;

/**
* Created by zyl on 18-2-27.
*/

public class ZFTtsService extends Service {
private static final String TEXT = “语音合成”;
// ================== 初始化参数设置开始 ==========================
/**重要!!!
* 发布时请替换成自己申请的appId appKey 和 secretKey。注意如果需要离线合成功能,请在您申请的应用中填写包名。
* 本demo的包名是com.baidu.tts.sample,定义在build.gradle中。
*/
private String appId = “10856726”;

private String appKey = "j9eaUFW7OsDnK8bSnCUfQrNz";

private String secretKey = "53c5e276dfcbb7d9ed6184a5b122ea24";
// TtsMode.MIX; 离在线融合,在线优先; TtsMode.ONLINE 纯在线; 没有纯离线
private TtsMode ttsMode = TtsMode.MIX;

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

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

private static String MODEL_FILENAME = TEMP_DIR + "/" + "bd_etts_speech_female.dat"; // 请确保该PATH下有这个文件 male是男声 female女声

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

protected SpeechSynthesizer mSpeechSynthesizer;

// =========== 以下为UI部分 ==================================================
private Button mSpeak, mStop;

private TextView mShowText;

protected Handler mainHandler;

private final Random generator = new Random();
private Thread thread = null;
private boolean is_authorized = false;
private Context mContext;
/*public class MyBinder extends Binder{
    public ZFTtsService getService(){
        return ZFTtsService.this;
    }
}
private MyBinder binder = new MyBinder();*/
public class MyBinder extends IZFTtsAidlInterface.Stub{
    @Override
    public void ZFSpeak(String str) throws RemoteException
    {
        speak(str);
        return;
    }
}
private MyBinder binder = new MyBinder();

@Override
public void onCreate(){
    super.onCreate();
    mContext = this;
    //
    //2018.03.05初始化设置优先的网络类型为wifi,以保证可以正常去授权 !!!


    Log.i("zyl log 0228","Zfttsservice---------oncreate");
     thread= new Thread(new Runnable() {
        @Override
        public void run() {
            initTTs();
        }
    });
    thread.run();

    IntentFilter mFilter = new IntentFilter() ;
    mFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
    mFilter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
    registerReceiver(mReceiver, mFilter);
}



@Override
public boolean onUnbind(Intent intent){
    //释放资源
    if (mSpeechSynthesizer != null){
        mSpeechSynthesizer.stop();
        mSpeechSynthesizer.release();
        mSpeechSynthesizer = null;
        if(mReceiver != null){
            unregisterReceiver(mReceiver);
        }
        Log.i("zyl log 0228","onUnbind");
    }
    if(thread != null) thread.interrupt();
    return false;
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_NOT_STICKY;
}

@Override
public void onDestroy() {
    super.onDestroy();
}

@Nullable
@Override
public IBinder onBind(Intent intent) {
    Log.i("zyl log 0228","Zfttsservice---------onBind");
    return binder;
}

//测试:在Service中暴露出去的方法,供client调用
public int getRandomNumber(){
    return generator.nextInt();
}

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

    int result =  mSpeechSynthesizer.setAppId(appId);
    checkResult(result, "setAppId");
    result = mSpeechSynthesizer.setApiKey(appKey, secretKey);
    checkResult(result, "setApiKey");
    if (isMix) {
        // 检查离线授权文件是否下载成功,离线授权文件联网时SDK自动下载管理,有效期3年,3年后的最后一个月自动更新。
        isSuccess = checkAuth();
        if (!isSuccess) {
            return;
        }
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_TEXT_MODEL_FILE, TEXT_FILENAME); // 文本模型文件路径 (离线引擎使用)
        mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_TTS_SPEECH_MODEL_FILE, MODEL_FILENAME); // 声学模型文件路径 (离线引擎使用)
    }

    // 以下setParam 参数选填。不填写则默认值生效
    mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEAKER, "0"); // 设置在线发声音人: 0 普通女声(默认) 1 普通男声 2 特别男声 3 情感男声<度逍遥> 4 情感儿童声<度丫丫>
    mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_VOLUME, "7"); // 设置合成的音量,0-9 ,默认 5
    mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_SPEED, "3");// 设置合成的语速,0-9 ,默认 5
    mSpeechSynthesizer.setParam(SpeechSynthesizer.PARAM_PITCH, "5");// 设置合成的语调,0-9 ,默认 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);
    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();
        Log.i("zyl log 0228","【error】鉴权失败 errorMsg=" + errorMsg);
        return false;
    } else {
        Log.i("zyl log 0228","验证通过,离线正式授权文件存在。");
        is_authorized = true;//置为true,避免重复授权
        //zyl 2018.03.05
        //1.授权成功后,将网络优先类型设置为数据流量,那么在MIX_MODE_DEFAULT模式下,非wifi即离线,客户端请求识别时,将采用离线识别模式,
        //以避免设备过多并且请求次数过多而引起请求次数超额(200000次)
        //2.具体验证是否可以设置网络优先级或者是否设置成功,可以将在线识别发生模式更改,以和离线模式区别
        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()) {
            Log.i("zyl log 0228","[ERROR] 文件不存在或者不可读取,请从assets目录复制改文件到:" + path);
            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自动转离线
     */

    Log.i("zyl log 0228","合成并播放 按钮已经点击");
    if(null == string || string.equals("")){
        string = TEXT;
    }
    if(null != mSpeechSynthesizer){
        int result = mSpeechSynthesizer.speak(string);
        checkResult(result, "speak");
    }

}

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

private BroadcastReceiver mReceiver = new BroadcastReceiver(){
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if(action.equals(WifiManager.NETWORK_STATE_CHANGED_ACTION)){
            Log.i("zyl log 0228","NETWORK_STATE_CHANGED_ACTION");
            Log.i("zyl log 0228","**************************************************");
            Log.i("zyl log 0228","isWifiConnected(mContext) = " + isWifiConnected(mContext,intent));

            if(!is_authorized && isWifiConnected(mContext,intent)){
                if(thread != null) thread.interrupt();

                thread= new Thread(new Runnable() {
                    @Override
                    public void run() {
                        initTTs();
                    }
                });
                thread.run();                   

            }
        }
    }

};

/**
 * 判断WIFI是否链接
 * @param context
 * @return
 */
public static boolean isWifiConnected(Context context,Intent intent) {
    if (context != null) {
        //ConnectivityManager mConnectivityManager = (ConnectivityManager) context
                //.getSystemService(Context.CONNECTIVITY_SERVICE);
        //NetworkInfo mWiFiNetworkInfo = mConnectivityManager
                //.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        //if (mWiFiNetworkInfo != null) {
            //return mWiFiNetworkInfo.isAvailable();
        //}
        NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
        if(info.getState().equals(NetworkInfo.State.DISCONNECTED)){  
            Log.i("zyl log 0228","isWifiConnected---->>>>>>>>>>>>>>wifi网络连接断开");  
        }  
        else if(info.getState().equals(NetworkInfo.State.CONNECTED)){  

            WifiManager wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);  
            WifiInfo wifiInfo = wifiManager.getConnectionInfo();                  

            //获取当前wifi名称  
            Log.i("zyl log 0228","连接到网络 " + wifiInfo.getSSID());  
            return true;  
        }
    }
    return false;
}

}
二、frameworks部分添加调用接口
frameworks/base/core/java/com/android/internal/statusbar/IStatusBar.aidl
frameworks/base/core/java/com/android/internal/statusbar/IStatusBarService.aidl frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/CommandQueue.java frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java frameworks/base/packages/SystemUI/src/com/android/systemui/statusbar/tv/TvStatusBar.java frameworks/base/services/core/java/com/android/server/statusbar/StatusBarManagerService.java

三、调用服务
//zftts begin
private IZFTtsAidlInterface mttsinterface;
private ServiceConnection zftts_conn = new ServiceConnection() {

    @Override
    public void onServiceConnected(ComponentName name, IBinder service) {
        mttsinterface = IZFTtsAidlInterface.Stub.asInterface(service);
        if(mttsinterface != null){
            Log.i("zyl log 0228","SystemBars---------------onServiceConnected  successed");
            //zftts test
            /*try {
                mttsinterface.ZFSpeak("展帆语音测试180302");
            } catch (RemoteException e) {
                e.printStackTrace();
            }*/
            if(mStatusBar != null){
                mStatusBar.setZFTtsinterface(mttsinterface);
            }
        }
    }
    //client 和service连接意外丢失时,会调用该方法
    @Override
    public void onServiceDisconnected(ComponentName name) {

    }
};
//end

你可能感兴趣的:(文字转语音代码记录)