1 /** 2 * Hilo 3 * Copyright 2015 alibaba.com 4 * Licensed under the MIT License 5 */ 6 7 /** 8 * @language=zh 9 * @class HTMLAudio声音播放模块。此模块使用HTMLAudioElement播放音频。 10 * 使用限制:iOS平台需用户事件触发才能播放,很多Android浏览器仅能同时播放一个音频。 11 * @param {Object} properties 创建对象的属性参数。可包含此类所有可写属性。 12 * @module hilo/media/HTMLAudio 13 * @requires hilo/core/Hilo 14 * @requires hilo/core/Class 15 * @requires hilo/event/EventMixin 16 * @property {String} src 播放的音频的资源地址。 17 * @property {Boolean} loop 是否循环播放。默认为false。 18 * @property {Boolean} autoPlay 是否自动播放。默认为false。 19 * @property {Boolean} loaded 音频资源是否已加载完成。只读属性。 20 * @property {Boolean} playing 是否正在播放音频。只读属性。 21 * @property {Number} duration 音频的时长。只读属性。 22 * @property {Number} volume 音量的大小。取值范围:0-1。 23 * @property {Boolean} muted 是否静音。默认为false。 24 */ 25 var HTMLAudio = Class.create(/** @lends HTMLAudio.prototype */{ 26 Mixes: EventMixin, 27 constructor: function(properties){ 28 Hilo.copy(this, properties, true); 29 30 this._onAudioEvent = this._onAudioEvent.bind(this); 31 }, 32 33 src: null, 34 loop: false, 35 autoPlay: false, 36 loaded: false, 37 playing: false, 38 duration: 0, 39 volume: 1, 40 muted: false, 41 42 _element: null, //HTMLAudioElement对象 43 44 /** 45 * @language=zh 46 * 加载音频文件。 47 */ 48 load: function(){ 49 if(!this._element){ 50 try{ 51 var elem = this._element = new Audio(); 52 elem.addEventListener('canplaythrough', this._onAudioEvent, false); 53 elem.addEventListener('ended', this._onAudioEvent, false); 54 elem.addEventListener('error', this._onAudioEvent, false); 55 elem.src = this.src; 56 elem.volume = this.volume; 57 elem.load(); 58 } 59 catch(err){ 60 //ie9 某些版本有Audio对象,但是执行play,pause会报错! 61 var elem = this._element = {}; 62 elem.play = elem.pause = function(){ 63 64 }; 65 } 66 } 67 return this; 68 }, 69 70 /** 71 * @language=zh 72 * @private 73 */ 74 _onAudioEvent: function(e){ 75 // console.log('onAudioEvent:', e.type); 76 var type = e.type; 77 78 switch(type){ 79 case 'canplaythrough': 80 e.target.removeEventListener(type, this._onAudioEvent); 81 this.loaded = true; 82 this.duration = this._element.duration; 83 this.fire('load'); 84 if(this.autoPlay) this._doPlay(); 85 break; 86 case 'ended': 87 this.playing = false; 88 this.fire('end'); 89 if(this.loop) this._doPlay(); 90 break; 91 case 'error': 92 this.fire('error'); 93 break; 94 } 95 }, 96 97 /** 98 * @language=zh 99 * @private 100 */ 101 _doPlay: function(){ 102 if(!this.playing){ 103 this._element.volume = this.muted ? 0 : this.volume; 104 this._element.play(); 105 this.playing = true; 106 } 107 }, 108 109 /** 110 * @language=zh 111 * 播放音频。如果正在播放,则会重新开始。 112 * 注意:为了避免第一次播放不成功,建议在load音频后再播放。 113 */ 114 play: function(){ 115 if(this.playing) this.stop(); 116 117 if(!this._element){ 118 this.autoPlay = true; 119 this.load(); 120 }else if(this.loaded){ 121 this._doPlay(); 122 } 123 124 return this; 125 }, 126 127 /** 128 * @language=zh 129 * 暂停音频。 130 */ 131 pause: function(){ 132 if(this.playing){ 133 this._element.pause(); 134 this.playing = false; 135 } 136 return this; 137 }, 138 139 /** 140 * @language=zh 141 * 恢复音频播放。 142 */ 143 resume: function(){ 144 if(!this.playing){ 145 this._doPlay(); 146 } 147 return this; 148 }, 149 150 /** 151 * @language=zh 152 * 停止音频播放。 153 */ 154 stop: function(){ 155 if(this.playing){ 156 this._element.pause(); 157 this._element.currentTime = 0; 158 this.playing = false; 159 } 160 return this; 161 }, 162 163 /** 164 * @language=zh 165 * 设置音量。注意: iOS设备无法设置音量。 166 */ 167 setVolume: function(volume){ 168 if(this.volume != volume){ 169 this.volume = volume; 170 this._element.volume = volume; 171 } 172 return this; 173 }, 174 175 /** 176 * @language=zh 177 * 设置静音模式。注意: iOS设备无法设置静音模式。 178 */ 179 setMute: function(muted){ 180 if(this.muted != muted){ 181 this.muted = muted; 182 this._element.volume = muted ? 0 : this.volume; 183 } 184 return this; 185 }, 186 187 Statics: /** @lends HTMLAudio */ { 188 /** 189 * @language=zh 190 * 浏览器是否支持HTMLAudio。 191 */ 192 isSupported: window.Audio !== null 193 } 194 195 });