docs: function(ql) {
  				var fm       = ql.fm,
  			preview  = ql.preview,
  			mimes    = {
  				'audio/mpeg'    : 'mp3',
  				'audio/mpeg3'   : 'mp3',
  				'audio/mp3'     : 'mp3',
  				'audio/x-mpeg3' : 'mp3',
  				'audio/x-mp3'   : 'mp3',
  				'audio/x-wav'   : 'wav',
  				'audio/wav'     : 'wav',
  				'audio/x-m4a'   : 'm4a',
  				'audio/aac'     : 'm4a',
  				'audio/mp4'     : 'm4a',
  				'audio/x-mp4'   : 'm4a',
  				'audio/ogg'     : 'ogg',
  				'audio/webm'    : 'webm',
  				'audio/flac'    : 'flac',
  				'audio/x-flac'  : 'flac',
  				'audio/amr'     : 'amr'
  			},
  			node, curHash,
  			win  = ql.window,
  			navi = ql.navbar,
  			AMR, autoplay,
  			setNavi = function() {
  				navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? '50px' : '');
  			},
  			getNode = function(src, hash) {
  				return $('<audio class="elfinder-quicklook-preview-audio ui-front" controls preload="auto" autobuffer><source src="'+src+'" /></audio>')
  					.on('change', function(e) {
  						// Firefox fire change event on seek or volume change
  						e.stopPropagation();
  					})
  					.on('error', function(e) {
  						node && node.data('hash') === hash && reset();
  					})
  					.data('hash', hash)
  					.appendTo(preview);
  			},
  			amrToWavUrl = function(hash) {
  				var dfd = $.Deferred(),
  					loader = $.Deferred().done(function() {
  						fm.getContents(hash).done(function(data) {
  							try {
  								var buffer = AMR.toWAV(new Uint8Array(data));
  								if (buffer) {
  									dfd.resolve(URL.createObjectURL(new Blob([buffer], { type: 'audio/x-wav' })));
  								} else {
  									dfd.reject();
  								}
  							} catch(e) {
  								dfd.reject();
  							}
  						}).fail(function() {
  							dfd.reject();
  						});
  					}).fail(function() {
  						AMR = false;
  						dfd.reject();
  					}),
  					_AMR;
  				if (window.TextEncoder && window.URL && URL.createObjectURL && typeof AMR === 'undefined') {
  					// previous window.AMR
  					_AMR = window.AMR;
  					delete window.AMR;
  					fm.loadScript(
  						[ fm.options.cdns.amr ],
  						function() { 
  							AMR = window.AMR? window.AMR : false;
  							// restore previous window.AMR
  							window.AMR = _AMR;
  							loader[AMR? 'resolve':'reject']();
  						},
  						{
  							error: function() {
  								loader.reject();
  							}
  						}
  					);
  				} else {
  					loader[AMR? 'resolve':'reject']();
  				}
  				return dfd;
  			},
  			play = function(player) {
  				var hash = node.data('hash'),
  					playPromise;
  				autoplay && (playPromise = player.play());
  				if (playPromise && playPromise.catch) {
  					playPromise.catch(function(e) {
  						if (!player.paused) {
  							node && node.data('hash') === hash && reset();
  						}
  					});
  				}
  			},
  			reset = function() {
  				if (node && node.parent().length) {
  					var elm = node[0],
  						url = node.children('source').attr('src');
  					win.off('viewchange.audio');
  					try {
  						elm.pause();
  						node.empty();
  						if (url.match(/^blob:/)) {
  							URL.revokeObjectURL(url);
  						}
  						elm.src = '';
  						elm.load();
  					} catch(e) {}
  					node.remove();
  					node = null;
  				}
  			};
  
  		preview.on(ql.evUpdate, function(e) {
  			var file = e.file,
  				type = mimes[file.mime],
  				html5, srcUrl;
  
  			if (mimes[file.mime] && ql.dispInlineRegex.test(file.mime) && ((html5 = ql.support.audio[type]) || (type === 'amr'))) {
  				autoplay = ql.autoPlay();
  				curHash = file.hash;
  				srcUrl = html5? fm.openUrl(curHash) : '';
  				if (!html5) {
  					if (fm.options.cdns.amr && type === 'amr' && AMR !== false) {
  						e.stopImmediatePropagation();
  						node = getNode(srcUrl, curHash);
  						amrToWavUrl(file.hash).done(function(url) {
  							if (curHash === file.hash) {
  								var elm = node[0];
  								try {
  									node.children('source').attr('src', url);
  									elm.pause();
  									elm.load();
  									play(elm);
  									win.on('viewchange.audio', setNavi);
  									setNavi();
  								} catch(e) {
  									URL.revokeObjectURL(url);
  									node.remove();
  								}
  							} else {
  								URL.revokeObjectURL(url);
  							}
  						}).fail(function() {
  							node.remove();
  						});
  					}
  				} else {
  					e.stopImmediatePropagation();
  					node = getNode(srcUrl, curHash);
  					play(node[0]);
  					win.on('viewchange.audio', setNavi);
  					setNavi();
  				}
  			}
  		}).on('change', reset);
  	}