实现input数字语音播报,可扩展成任何语音audio实现,IE8兼容转flash实现

本文介绍了一个简单的数字语音播放器实现方案,支持中英文数字语音播放,可通过自定义URL播放不同语言的数字发音。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

<!DOCTYPE>
<html>
 <head>
  <title> New Document </title>
   <meta charset="utf-8">

  <meta name="Generator" content="EditPlus">
  <meta name="Author" content="">
  <meta name="Keywords" content="">
  <meta name="Description" content="">
  <meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1">
  <meta name=”viewport” content=”width=device-width; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;” />
 </head>

	<script type="text/javascript" src="http://www.linuxidc.com/inc/jquery.js"></script>
	<script src="http://api.html5media.info/1.1.6/html5media.min.js"></script>
	<script src="http://vjs.zencdn.net/ie8/1.1.2/videojs-ie8.min.js"></script>
<script type="text/javascript">
<!--
	
	var SpeechVideo = function(){
		this.urls = [];
		this.canload = true;
		this.setInterval = null;
		this.audio = null;
	};

	SpeechVideo.prototype.__load = function(){
		var me    = this;
		if(this.canload == false){ return; }
		
		var url   = this.urls.shift();
		if(url == null && this.setInterval != null){ clearInterval(this.setInterval); this.setInterval = null; return; }else{ this.play(url); }

		if(this.setInterval == null){
			this.setInterval = setInterval(function(){
				me.__load();
			},10);
		}
		
	}

	SpeechVideo.prototype.play = function(url){
	    this.canload = false;
		if(this.audio == null){ 
			if(typeof Audio != 'undefined'){ this.audio = new Audio(); }else{
				//兼容IE9-
				if(typeof $ !== 'undefined'){
					var $audio = $('<audio  src="'+ url +'" controls preload></audio>').hide();
					$audio.appendTo(document.body);
					this.audio = $audio[0];
				}else{
					var audio = document.createElement('audio');
						audio.style.display="none";
					document.body.appendChild(audio);
					this.audio = audio;
				}
			}
		}

		if(typeof Audio != 'undefined'){
			var audio = this.audio,me = this;
			audio.src = url;
			
			if(window.attachEvent){
				audio.onloadstart = function(){ me.canload = false;};
				audio.onended = function()    { me.canload = true; };
				audio.onerror = function()    { me.canload = true; };
			}else{
				audio.addEventListener('loadstart',function(){ me.canload = false;});
				audio.addEventListener('ended',function()    { audio.currentTime = 0; me.canload = true; });
				audio.addEventListener('error',function()    { audio.currentTime = 0; me.canload = true; });
			}
			
			audio.play();
		}else{
			//兼容IE9-【暂时没找到合适的方法,以网易云音乐为例的话,估计有眉目】
		}
		
	}

	SpeechVideo.prototype.next = function(url){
		this.urls.push(url);
		this.__load();
	};
	
	SpeechVideo.prototype.remove = function(ele){
		if(typeof ele == 'undefined'){ this.urls.pop(); }else
		if(typeof ele == 'number'){ 
			if(ele > this.urls.length - 1){ ele = this.urls.length - 1; } 
			this.urls.splice(ele,1);
		}else{
			var index = -1;
			for (var i = 0; i < this.urls.length; i++) {
				if (this.urls[i] == ele) return index = i;
			}
			if(index > -1){ this.urls.splice(index,1); }
		}
	}


	var NumberSpeech = function(cfg){
		var dfCfg = {
			input : null, reg : null ,
			srcsMap : { //英文发音
				'1' : 'http://fanyi.baidu.com/gettts?lan=en&text=One&spd=3&source=web',
				'2' : 'http://fanyi.baidu.com/gettts?lan=en&text=Two&spd=3&source=web',
				'3' : 'http://fanyi.baidu.com/gettts?lan=en&text=Three&spd=3&source=web',
				'4' : 'http://fanyi.baidu.com/gettts?lan=en&text=Four&spd=3&source=web',
				'5' : 'http://fanyi.baidu.com/gettts?lan=en&text=Five&spd=3&source=web',
				'6' : 'http://fanyi.baidu.com/gettts?lan=en&text=Six&spd=3&source=web',
				'7' : 'http://fanyi.baidu.com/gettts?lan=en&text=Seven&spd=3&source=web',
				'8' : 'http://fanyi.baidu.com/gettts?lan=en&text=Eight&spd=3&source=web',
				'9' : 'http://fanyi.baidu.com/gettts?lan=en&text=Nine&spd=3&source=web',
				'0' : 'http://fanyi.baidu.com/gettts?lan=en&text=Zero&spd=3&source=web'
			}	//输入容器【支持ID 和 jquery对象两种形式】 , 输入规则 , 发音资源
		};
		
		var type = navigator.appName,lang = (type == "Netscape" ?  navigator.language : navigator.userLanguage).substr(0, 2);
	  if (lang == "zh"){
			dfCfg.srcsMap = { //中文发音
				'1' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%B8%80&spd=5&source=web',
				'2' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%BA%8C&spd=5&source=web',
				'3' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%B8%89&spd=5&source=web',
				'4' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E5%9B%9B&spd=5&source=web',
				'5' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%BA%94&spd=5&source=web',
				'6' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E5%85%AD&spd=5&source=web',
				'7' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%B8%83&spd=5&source=web',
				'8' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E5%85%AB&spd=5&source=web',
				'9' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E4%B9%9D&spd=5&source=web',
				'0' : 'http://fanyi.baidu.com/gettts?lan=zh&text=%E9%9B%B6&spd=5&source=web',
			};
		}

		if(typeof $ !== 'undefined'){
			dfCfg = $.extend(true, dfCfg, cfg || {});
		}else{
			//浅层次copy
			var srcs = cfg.srcsMap || {};
			delete cfg.srcsMap;
			for(var key in (cfg || {})){ dfCfg[key] = cfg[key]; }
			for(var key in srcs){
				dfCfg.srcsMap[key] = srcs[key];
			}
		}
		

		if(dfCfg.input == null){ throw '请指定当前容器'; }
		var $input = dfCfg.input,speechVideo = new SpeechVideo(),oldLength = 0,isIE = typeof window.attachEvent !== 'undefined';
		if(typeof $ !== 'undefined'){ //TODO  !==  为测试原生方式暂设置 ==
			if(typeof dfCfg.input == 'string'){ $input = $('#'+dfCfg.input);}

			$input.bind('keydown',function(event){
				if(event.keyCode == 8 && isIE){ 
					//var curValue = $(this).val();
					//var len = oldLength - curValue.length;
					//for(var i=0;i<len;i++){
						speechVideo.remove(); oldLength--; if(oldLength < 0){ oldLength = 0;}
					//}
				}
			});
			$input.bind("input propertychange change",function(){
				var curValue = $(this).val();
				
				if(oldLength > curValue.length){ speechVideo.remove(); }else{
					var last = curValue.substring(curValue.length - 1);
					if(dfCfg.srcsMap[last]){
						speechVideo.next(dfCfg.srcsMap[last]);
					}
				}
				oldLength = curValue.length;
			});


		}else{
			var inputObj = document.getElementById(dfCfg.input),objEvent;
			oldLength = inputObj.value.length;
			inputObj.onkeypress = function(event){
				var keyCode = event.keyCode;
				event.returnValue = (keyCode >= 48 && keyCode <= 57);
			};
			inputObj.onkeydown = function(event){
				if(event.keyCode == 8 && isIE){ speechVideo.remove(); oldLength--; if(oldLength < 0){ oldLength = 0;}}
			}
			
			objEvent = function(event){
				
				var curValue = '';
				if (typeof event.srcElement != 'undefined' && event.propertyName == "value") {
					curValue = event.srcElement.value;
				}else if(typeof event.target != 'undefined'){ curValue = event.target.value; }

				if(oldLength > curValue.length){ speechVideo.remove(); }else{
					
					var last = curValue.substring(curValue.length - 1);
					if(dfCfg.srcsMap[last]){
						speechVideo.next(dfCfg.srcsMap[last]);
					}
				}
				oldLength = curValue.length;
			}
			//input.onpropertychange = input.oninput = input.onchange
			if(isIE){ inputObj.onpropertychange = objEvent; }else{ inputObj.oninput = objEvent; }
			
		}
		

	}

	window.onload = function(){
		new NumberSpeech({
			input : 'numberspeech'
		});
	}

//-->
</script>
 <body>
  
  <input type="text" id="numberspeech"/>
	
  <!-- 
	<audio src="http://m10.music.126.net/20170517151725/6fb69d17ac9d6e0a5364a5c4b2511d19/ymusic/4be2/deb8/b5a3/49b598f9f8b7a160c1fd43afaf52e646.mp3" controls preload></audio>
  -->
 </body>
</html>

实现思路:

1、语音对象,用于语音播放,可实现按url插入顺序播放,实现未播放url删除不读。

        2、input数字控制对象,用于控制输入内容。

支持:

1、中英文数字语音播放,默认使用百度翻译语音程序。

        2、支持自定义数字语音路径。

        3、方便控制混合app开发时,语音路径置换为app本地路径,减少网络请求,提高读取速度。

        4、原生和jquery两种方式实现。

实现缘由:

      小伙伴业务需求,就顺带帮助实现~

未尽事项:

 IE9- 的支持,使用audio.js 不过这里不深究,毕竟应用场景在APP端,跟微软IE关系没多大。这里demo已引用支持,可自行实现。

若应用于PC端,多选移除时,内部oldValue计算方式不合理,这暂不在考虑范围内,可自行优化,难度不大~


思路扩展:

利用百度语音(以“http://fanyi.baidu.com/gettts?lan=zh&text=%E4%BA%94&spd=5&source=web”为例,text对应的值,即为语音内容),实现语音播放时很轻松的。





评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值