Last active
December 12, 2015 00:28
-
-
Save vincenting/4683784 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Author: Vincent Tin | |
* Date: 13-2-1 | |
* Time: 上午11:43 | |
*/ | |
(function (window, document, $,_){ | |
/** | |
* 用于处理拓词发音的封装包,其中ToVoice只能实例化一次,使用requireJs直接返回实例化对象 | |
*/ | |
var _getIdByWord , _isBadBrowser , loadedQueue={} , ToVoice; | |
/** | |
* 将单词发音的URL转化为ID | |
* @param fileUrl 需要转化的URL地址 | |
* @return {String} 最后的ID字符串 | |
* @private | |
*/ | |
_getIdByWord = function(fileUrl){ | |
var fileNamePieces = fileUrl.split('/'), | |
_fileName = fileNamePieces[fileNamePieces.length-1].split('.')[0]; | |
return _fileName.replace(/-/g,'x').replace(/\$/g,'_').replace(/\s+/g,'_').replace(/\(/g,'_').replace(/\)/g,'_').replace(/'/,"_"); | |
}; | |
_isBadBrowser = (/** | |
*是否为VISTA以前的系统(主要针对XP),并且使用了IE内核的浏览器 | |
* @return {Boolean} | |
* @private | |
*/ | |
function(){ | |
var _u = window.navigator.userAgent.toLowerCase(),_i = _u.indexOf("windows nt"); | |
if(_i===-1){ | |
return false; | |
}else{ | |
try{ | |
var _version = _u.substring(_i + 11, _i + 14); | |
return (_version < 6&&_u.indexOf('msie')!==-1); | |
}catch(e){ | |
return true; | |
} | |
} | |
})(); | |
/** | |
* @param user_config 自定义参数,为关联数组 | |
* @param readyCallback 播放器初始化成功调用函数 | |
* @constructor | |
*/ | |
ToVoice = function(user_config,readyCallback){ | |
this.init.apply(this,arguments); | |
}; | |
ToVoice.fn = ToVoice.prototype; | |
/** | |
* @note 如果不是旧式浏览器,尝试使用SoundManager2来实现发音,初始化失败采用自带播放器播放 | |
* 2013-2-18添加如果是MAC下无FLASH的情况,使用HTML5模式 | |
* | |
*/ | |
ToVoice.fn.init = function(userConfig,readyCallback){ | |
readyCallback = readyCallback ? readyCallback : $.noop; | |
try{ | |
if(navigator.userAgent.toLowerCase().indexOf("mac")!==-1&&!window.swfobject.ua.pv[0]){ | |
this.setHtml5Mode.call(this,readyCallback); | |
return; | |
} | |
}catch(e) {} | |
this.setSMMode.apply(this); | |
var config = this.autoConfig.apply(this,arguments); | |
this.localSwfUrl = config.url; | |
if(!_isBadBrowser){ | |
soundManager.setup(config); | |
}else{ | |
this.setSWFMode.call(this,readyCallback); | |
} | |
}; | |
/** | |
* @note 根据自定义配置最后产生SoundManager2的配置 | |
* | |
*/ | |
ToVoice.fn.autoConfig = function(userConfig,readyCallback){ | |
var _this = this, | |
config = { | |
url: 'swf/', | |
flashVersion : 9, | |
preferFlash : true, | |
useFlashBlock : false, | |
useHighPerformance : true, | |
useFastPolling : true, | |
autoLoad : true, | |
debugMode:false, | |
onready: function(){ | |
readyCallback.call(_this); | |
}, | |
ontimeout: function() { | |
$("#sm2-container").remove(); | |
_this.setSWFMode.call(_this,readyCallback); | |
} | |
}; | |
_.map(userConfig,function(value,item){ | |
config[item] = value; | |
}); | |
return config; | |
}; | |
/** | |
* 将播放器设置为HTML5模式 | |
*/ | |
ToVoice.fn.setHtml5Mode = function(readyCallback){ | |
$("body").append("<div id = 'toVoiceSpeaker'></div><div id='toVoicePreLoad'></div>"); | |
this.$speaker = $("#toVoiceSpeaker"); | |
this.$preLoad = $("#toVoicePreLoad"); | |
this.play = _h5Play; | |
this.preLoad = _h5PreLoad; | |
this.deleteDom = _swfDeleteDom; | |
this.destruct = _swfDestruct; | |
var _this = this; | |
setTimeout(function(){ | |
readyCallback.apply(_this,arguments); | |
},50); | |
}; | |
/** | |
* 将播放器设为使用soundManager2的播放模式 | |
*/ | |
ToVoice.fn.setSMMode = function(){ | |
this.play = _smPlay; | |
this.preLoad = _smPreLoad; | |
this.deleteDom = _smDeleteDom; | |
this.destruct = _smDestruct; | |
}; | |
/** | |
* 将播放器设为使用本地播放器的播放模式 | |
*/ | |
ToVoice.fn.setSWFMode = function(readyCallback){ | |
$("body").append("<div id = 'toVoiceSpeaker'></div><div id='toVoicePreLoad'></div>"); | |
this.play = _swfPlay; | |
this.preLoad = _swfPreLoad; | |
this.deleteDom = _swfDeleteDom; | |
this.destruct = _swfDestruct; | |
this.$speaker = $("#toVoiceSpeaker"); | |
this.$preLoad = $("#toVoicePreLoad"); | |
readyCallback.apply(this,arguments); | |
}; | |
/** | |
* 使用HTML的方式播放 | |
* @param url | |
* @private | |
*/ | |
var _h5Play = function(url){ | |
var audio = document.createElement('audio'); | |
audio.src = url; | |
this.$speaker.html(audio); | |
audio.play(); | |
}; | |
/** | |
* 使用HTML的方式对单个URL进行预载入 | |
* @param url | |
* @private | |
*/ | |
var _h5LoadOne = function(url){ | |
var audio = document.createElement('audio'); | |
audio.src = url; | |
audio.id = _getIdByWord(url); | |
this.$preLoad[0].appendChild(audio); | |
audio.volume = 0; | |
audio.muted= true; | |
audio.preload="auto"; | |
audio.play(); | |
}; | |
/** | |
* 使用HTML的方式对URL列表进行预载入 | |
* @param list | |
* @private | |
*/ | |
var _h5PreLoad = function(list){ | |
if (!_.isArray(list)) list = [list]; | |
_.each(list,_h5LoadOne,this); | |
}; | |
/** | |
* 使用soundManager2进行播放 | |
* @param url | |
* @private | |
*/ | |
var _smPlay = function(url){ | |
var mp3Id = _getIdByWord(url); | |
if(_.has(loadedQueue,mp3Id)){ | |
loadedQueue[mp3Id].play(); | |
}else{ | |
/** | |
* @note 如果没有载入成功,将重新载入 | |
*/ | |
_preLoadOne(url,true); | |
} | |
}; | |
/** | |
* 使用soundManager2对声音文件进行预先载入 | |
* @param url 需要预先载入的MP3地址 | |
* @param isAutoPlay 是否在载入后就进行播放 | |
* @private | |
*/ | |
var _preLoadOne = function(url,isAutoPlay){ | |
if(soundManager.canPlayURL(url)){ | |
var mp3Id = _getIdByWord(url), | |
tmpObject = soundManager.createSound({ | |
id: mp3Id, | |
url: url, | |
autoLoad: true, | |
autoPlay: !!isAutoPlay, | |
onload: function() { | |
loadedQueue[mp3Id] = tmpObject; | |
} | |
}); | |
} | |
}; | |
/** | |
* 使用soundManager2对多个MP3进行预先载入 | |
* @param list 需要预先载入的MP3地址列表 | |
* @private | |
*/ | |
var _smPreLoad = function(list){ | |
if (!_.isArray(list)) list = [list]; | |
_.each(list,function(url){ | |
_preLoadOne(url,false); | |
}); | |
}; | |
/** | |
* 删除soundManager2中已经存在的对象 | |
* @param url 需要删除的MP3地址 | |
* @private | |
*/ | |
var _smDeleteDom = function(url){ | |
var mp3Id = _getIdByWord(url), | |
soundObj = soundManager.getSoundById(mp3Id); | |
if(soundObj){ | |
soundObj.unload(); | |
soundObj.destruct(); | |
} | |
if(_.has(loadedQueue,mp3Id)){ | |
delete loadedQueue[mp3Id]; | |
} | |
}; | |
/** | |
* 删除soundManager2中所有已经存在的对象 | |
* @private | |
*/ | |
var _smDestruct = function(){ | |
_.map(loadedQueue, function (mp3Object,mp3Id) { | |
mp3Object.unload(); | |
mp3Object.destruct(); | |
delete loadedQueue[mp3Id]; | |
}); | |
}; | |
/** | |
* 将MP3地址转化为可以播放的HTML字符串 | |
* @param url MP3地址 | |
* @param isPreLoad 是否载入模式 | |
* @return {string} | |
* @private | |
*/ | |
var _getSwfObject = function(url,isPreLoad){ | |
//noinspection JSUnresolvedFunction | |
var localSwfUrl = this.localSwfUrl , | |
swfTemplate = _.template('<embed id = "<%= mp3Id %>" wmode="transparent" type="application/x-shockwave-flash" width="1" height="1" pluginspage="http://www.macromedia.com/go/getflashplayer" menu="false" quality="high" src="<%= swfUrl %><% if(isPreLoad) {%>towords.loader.swf<% }else{ %>towords.speaker.swf<% } %>" FlashVars="url=<%= mp3Url %>&auto=1"/>'); | |
return swfTemplate({ | |
mp3Id : _getIdByWord(url) , | |
swfUrl : localSwfUrl , | |
mp3Url : url , | |
'isPreLoad' : isPreLoad | |
}); | |
}; | |
/** | |
* 使用本地播放器播放MP3 | |
* @param url MP3地址 | |
* @private | |
*/ | |
var _swfPlay = function(url){ | |
var html = _getSwfObject.call(this,url,false); | |
this.$speaker.html(html); | |
}; | |
/** | |
* @note 使用本地播放器生成HTML时缓存 | |
*/ | |
var temSwfList = []; | |
/** | |
* 使用本地播放器对系列MP3进行预先载入操作 | |
* @param list 需要预先载入的MP3地址列表 | |
* @private | |
*/ | |
var _swfPreLoad = function(list){ | |
if (!_.isArray(list)) list = [list]; | |
temSwfList.length = 0; | |
_.each(list,function(url){ | |
var html = _getSwfObject.call(this,url,true); | |
temSwfList.push(html); | |
},this); | |
this.$preLoad.append(temSwfList.join("")); | |
}; | |
/** | |
* 删除Dom中MP3预先载入产生的DIV节点 | |
* @param url 需要删除的MP3地址 | |
* @private | |
*/ | |
var _swfDeleteDom = function(url){ | |
var mp3Id = _getIdByWord(url); | |
$("#"+mp3Id).remove(); | |
}; | |
/** | |
* 删除Dom中所有预先载入产生的DIV节点 | |
* @private | |
*/ | |
var _swfDestruct = function(){ | |
this.$preLoad.html(""); | |
}; | |
/** | |
* @note 将ToVoice暴露在全局变量中 | |
*/ | |
window.ToVoice = ToVoice; | |
/** | |
* @note 如果使用了requireJs就返回ToVoice实例对象 | |
*/ | |
var toVoice = false; | |
if ( typeof define === "function" && define.amd) { | |
define(["config","soundManager"], | |
/** | |
* 根据ToVoice的实例化情况返回相应的匿名函数 | |
* @param config 系统配置文件 | |
* @return {Function} | |
*/ | |
function (config) { | |
if(toVoice){ | |
return function(callback){ | |
if(_.isFunction(callback))callback.call(toVoice); | |
return toVoice; | |
} | |
} | |
return function(callback){ | |
toVoice = new ToVoice({ | |
url: config.swfUrl | |
},callback); | |
return toVoice; | |
}; | |
} | |
); | |
} | |
}(window,document,jQuery,_)); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment