# aardio 范例: Edge 大声朗读



```aardio
//Edge 大声朗读
//chrome.edge 大声朗读: https://www.aardio.com/zh-cn/docs/examples/WebUI/Edge/speech.html

import fonts.fontAwesome;
import bass.channel; 
import web.edgeTextToSpeech;
import win.clip.file;
import win.ui;
/*DSG{{*/
var winform = win.form(text="Edge 大声朗读";right=757;bottom=467;bgcolor=0xFFFFFF)
winform.add(
btnPlay={cls="plus";left=268;top=427;right=299;bottom=456;bgcolor=0xFFFFFF;color=0x0045FF;db=1;disabled=1;dl=1;font=LOGFONT(h=-16;name='FontAwesome');iconStyle={align="left";font=LOGFONT(h=-16;name='FontAwesome');padding={left=7;top=3}};iconText='\uF04B';notify=1;z=7};
btnVoice={cls="plus";text="大声朗读（Ctrl + Enter）";left=520;top=427;right=744;bottom=456;align="left";bgcolor=0xFFFFFF;color=0xFF8000;db=1;dr=1;font=LOGFONT(h=-16);iconStyle={align="left";font=LOGFONT(h=-16;name='FontAwesome');padding={left=7;top=3}};iconText='\uF028';notify=1;textPadding={left=28};z=6};
cmbVoice={cls="combobox";left=68;top=431;right=258;bottom=457;db=1;dl=1;edge=1;items={};mode="dropdownlist";z=2};
edit={cls="edit";left=8;top=10;right=741;bottom=414;db=1;dl=1;dr=1;dt=1;edge=1;multiline=1;z=1};
static={cls="static";text="速度：";left=290;top=432;right=346;bottom=456;align="right";center=1;db=1;dl=1;transparent=1;z=4};
static2={cls="static";text="语音：";left=3;top=433;right=59;bottom=457;align="right";center=1;db=1;dl=1;transparent=1;z=5};
tbRate={cls="trackbar";left=369;top=428;right=512;bottom=458;bgcolor=0xFFFFFF;db=1;dl=1;dr=1;max=100;min=0;z=3}
)
/*}}*/

//响应按钮点击事件
winform.btnVoice.oncommand = function(id, event) { 
	
	var text = winform.edit.text;
	if(!string.find(text,":|\a")) return winform.edit.showWarningTip("请输入要朗读的有效文本。");	
     
    //禁用按钮，并循环显示沙漏 （hourglass）不同状态图标，实现出沙漏流动的动画。
    winform.btnVoice.disabledText = ['\uF254','\uF251','\uF252','\uF253','\uF250',text="正在合成 ..."];
	winform.btnPlay.disabled = true;
	
    //创建文本转语音服务，必须先更新 aardio 
    var tts = web.edgeTextToSpeech(text,"\edge-tts.mp3");
    
    //如果设置代理服务器，则必须指定为 HTTP:// 协议
    //tts.SetProxy("HTTP://127.0.0.1:1082","","");
    
    //设置语音
    tts.voiceOptions.name = winform.cmbVoice.selText;
    
    //设置速度
    tts.voiceOptions.rate = (winform.tbRate.pos - 100) + "%"
     
    //识别完成
    tts.OnResponseEnd = function(path){ 
        
        //win.clip.file.write(path); //复制 MP3
        
        //禁用按钮，并循环显示 静音»低音量»高音量 图标，显示发音效果动画
		winform.btnVoice.disabledText = ['\uF026','\uF027','\uF028',text="正在朗读 ..."];
        
        //打开 MP3 
        var audio = bass.channel.open(string.load(path));
        
        audio.syncCallback(function(data){
        	audio.free();
        	
        	//启用按钮，停止动画
        	winform.btnVoice.disabledText = null;
        	winform.btnPlay.disabled = false;
        	
    	},2/*_BASS_SYNC_END*/);
    	
    	//播放声音
    	audio.play();
    }
    
    //显示错误信息
    tts.OnError = function(sender, e){
    	winform.edit.print(e.Message); 
    	winform.btnVoice.disabledText = null;
        winform.btnPlay.disabled = false;
    }
    
    //连接服务器，合成语音
    tts.ConnectAsync();
}

winform.btnVoice.skin({
	color={
		active=0xFF00FF00;
		default=0xFF0080FF;
		disabled=0xFF999999;
		hover=0xFFFF0000		
	}
})

//设置滑块范围（语音速度）
winform.tbRate.setRange(0,200);
winform.tbRate.pos = 100;

//可选语音列表
winform.cmbVoice.items = { 
 "zh-CN-XiaoxiaoNeural";
 "zh-CN-XiaoyiNeural";
 "zh-CN-YunjianNeural";
 "zh-CN-YunxiNeural";
 "zh-CN-YunxiaNeural";
 "zh-CN-YunyangNeural";
 "zh-CN-shaanxi-XiaoniNeural";
 "zh-CN-liaoning-XiaobeiNeural";
 "zh-TW-HsiaoChenNeural";
 "zh-TW-YunJheNeural";
 "zh-TW-HsiaoYuNeural"; 
 "zh-HK-HiuGaaiNeural";
 "zh-HK-HiuMaanNeural";
 "zh-HK-WanLungNeural";
 "en-US-JennyNeural";
 "en-US-GuyNeural";
 "en-US-ChristopherNeural";
 "en-US-EricNeural";
 "en-US-MichelleNeural";
 "en-US-RogerNeural";
 "en-US-SteffanNeural";
 "en-US-AriaNeural";
}

namespace string{
	/*
	检测文本是否以拉丁字母为主（例如英文）。
	考虑英文双单词短语多数情况下多于 6 个字母（含空格），而 2 个汉字的 UTF-8 编码一般为 6 个字节。
	*/
	latinLike = lambda(str) !find(str,":") || (len(str) > #str/1.5)
}
		
winform.edit.onChange = function(){ 

	var text = winform.edit.text;
	if(!string.find(text,":|\a")) return;	
	
	//判读输入是否包含中文字符
	if(string.latinLike(winform.edit.text)){
		if(!string.startsWith(winform.cmbVoice.text,"en-")){
			//切换为英文语音
			winform.cmbVoice.selText = "en-US-JennyNeural"
		}
	}
	else{
		if(!string.startsWith(winform.cmbVoice.text,"zh-")){
			//切换为中文语音
			winform.cmbVoice.selText = "zh-CN-XiaoxiaoNeural"
		}
	}
	
}

winform.cmbVoice.selIndex = 1;

winform.onOk = function(){
	winform.btnVoice.oncommand(); 
}

winform.edit.onOk = function(ctrl,alt,shift){ 
	if(ctrl && !shift && !alt) {
		winform.btnVoice.oncommand();
		return true;  
	}	
}

winform.btnPlay.skin(
	iconColor={
		active=0xFF00FF00;
		disabled=0xFF999999;
		hover=0xFFFF0000		
	}
)
winform.btnPlay.oncommand = function(id,event){
	winform.btnVoice.disabled  = true;
	winform.btnPlay.disabledText = ['\uF026','\uF027','\uF028']
	
    var audio = bass.channel.open(string.load("\edge-tts.mp3"));
        
    audio.syncCallback(function(data){
        audio.free();
        
        //启用按钮，停止动画
        winform.btnVoice.disabled = null;
        winform.btnPlay.disabledText = false;
        
    },2/*_BASS_SYNC_END*/);
    
    //播放声音
    audio.play();	
}

winform.show();
win.loopMessage();

/*
//可使用 web.edgeTextToSpeech.ui 扩展库快速创建上面的界面
import web.edgeTextToSpeech.ui;
var ttsForm = web.edgeTextToSpeech.ui();
ttsForm.edit.selText = "测试语音";
ttsForm.doModal();
*/
```

