|
66 | 66 | this.infoUpdateId = null, //to sotore the setTimeout ID and clear the interval |
67 | 67 | this.animationId = null, |
68 | 68 | this.status = 0, //flag for sound is playing 1 or stopped 0 |
69 | | - this.forceStop = false |
| 69 | + this.forceStop = false, |
| 70 | + this.allCapsReachBottom = false |
70 | 71 | }; |
71 | 72 | Visualizer.prototype = { |
72 | 73 | ini: function() { |
|
179 | 180 | audioBufferSouceNode.stop = audioBufferSouceNode.noteOff //in old browsers use noteOn method |
180 | 181 | }; |
181 | 182 | //stop the previous sound if any |
182 | | - if (this.source !== null) { |
| 183 | + if (this.animationId !== null) { |
183 | 184 | cancelAnimationFrame(this.animationId); |
| 185 | + } |
| 186 | + if (this.source !== null) { |
184 | 187 | this.source.stop(0); |
185 | 188 | } |
186 | 189 | audioBufferSouceNode.start(0); |
|
214 | 217 | var drawMeter = function() { |
215 | 218 | var array = new Uint8Array(analyser.frequencyBinCount); |
216 | 219 | analyser.getByteFrequencyData(array); |
| 220 | + if (that.status === 0) { |
| 221 | + //fix when some sounds end the value still not back to zero |
| 222 | + for (var i = array.length - 1; i >= 0; i--) { |
| 223 | + array[i] = 0; |
| 224 | + }; |
| 225 | + allCapsReachBottom = true; |
| 226 | + for (var i = capYPositionArray.length - 1; i >= 0; i--) { |
| 227 | + allCapsReachBottom = allCapsReachBottom && (capYPositionArray[i] === 0); |
| 228 | + }; |
| 229 | + if (allCapsReachBottom) { |
| 230 | + cancelAnimationFrame(that.animationId);//since the sound is top and animation finished, stop the requestAnimation to prevent potential memory leak,THIS IS VERY IMPORTANT! |
| 231 | + return; |
| 232 | + }; |
| 233 | + }; |
217 | 234 | var step = Math.round(array.length / meterNum); //sample limited data from the total array |
218 | 235 | ctx.clearRect(0, 0, cwidth, cheight); |
219 | 236 | for (var i = 0; i < meterNum; i++) { |
220 | 237 | var value = array[i * step]; |
221 | | - if (that.status === 0) { |
222 | | - value = 0; //fix when some sounds end the value still not back to zero |
223 | | - }; |
224 | 238 | if (capYPositionArray.length < Math.round(meterNum)) { |
225 | 239 | capYPositionArray.push(value); |
226 | 240 | }; |
|
235 | 249 | ctx.fillStyle = gradient; //set the filllStyle to gradient for a better look |
236 | 250 | ctx.fillRect(i * 12 /*meterWidth+gap*/ , cheight - value + capHeight, meterWidth, cheight); //the meter |
237 | 251 | } |
238 | | - this.animationId = requestAnimationFrame(drawMeter); |
| 252 | + that.animationId = requestAnimationFrame(drawMeter); |
239 | 253 | } |
240 | 254 | this.animationId = requestAnimationFrame(drawMeter); |
241 | 255 | }, |
|
246 | 260 | return; |
247 | 261 | }; |
248 | 262 | this.status = 0; |
249 | | - console.log('audio ended'); |
250 | 263 | var text = 'HTML5 Audio API showcase | An Audio Viusalizer'; |
251 | 264 | document.getElementById('fileWrapper').style.opacity = 1; |
252 | 265 | document.getElementById('info').innerHTML = text; |
|
0 commit comments