docs: function(ql) {
  				var fm       = ql.fm,
  			preview  = ql.preview,
  			mimes    = {
  				'video/mp4'       : 'mp4',
  				'video/x-m4v'     : 'mp4',
  				'video/quicktime' : 'mp4',
  				'video/ogg'       : 'ogg',
  				'application/ogg' : 'ogg',
  				'video/webm'      : 'webm',
  				'video/x-matroska': 'mkv',
  				'video/3gpp'      : '3gp',
  				'application/vnd.apple.mpegurl' : 'm3u8',
  				'application/x-mpegurl' : 'm3u8',
  				'application/dash+xml'  : 'mpd',
  				'video/x-flv'     : 'flv'
  			},
  			node,
  			win  = ql.window,
  			navi = ql.navbar,
  			cHls, cDash, pDash, cFlv, autoplay, tm,
  			setNavi = function() {
  				if (fm.UA.iOS) {
  					if (win.hasClass('elfinder-quicklook-fullscreen')) {
  						preview.css('height', '-webkit-calc(100% - 50px)');
  						navi._show();
  					} else {
  						preview.css('height', '');
  					}
  				} else {
  					navi.css('bottom', win.hasClass('elfinder-quicklook-fullscreen')? '50px' : '');
  				}
  			},
  			render = function(file, opts) {
  				var errTm = function(e) {
  						if (err > 1) {
  							tm && clearTimeout(tm);
  							tm = setTimeout(function() {
  								!canPlay && reset(true);
  							}, 800);
  						}
  					},
  					err = 0, 
  					canPlay;
  				//reset();
  				pDash = null;
  				opts = opts || {};
  				ql.hideinfo();
  				node = $('<video class="elfinder-quicklook-preview-video" controls preload="auto" autobuffer playsinline>'
  						+'</video>')
  					.on('change', function(e) {
  						// Firefox fire change event on seek or volume change
  						e.stopPropagation();
  					})
  					.on('timeupdate progress', errTm)
  					.on('canplay', function() {
  						canPlay = true;
  					})
  					.data('hash', file.hash);
  				// can not handling error event with jQuery `on` event handler
  				node[0].addEventListener('error', function(e) {
  					if (opts.src && fm.convAbsUrl(opts.src) === fm.convAbsUrl(e.target.src)) {
  						++err;
  						errTm();
  					}
  				}, true);
  
  				if (opts.src) {
  					node.append('<source src="'+opts.src+'" type="'+file.mime+'"/><source src="'+opts.src+'"/>');
  				}
  				
  				node.appendTo(preview);
  
  				win.on('viewchange.video', setNavi);
  				setNavi();
  			},
  			loadHls = function(file) {
  				var hls;
  				render(file);
  				hls = new cHls();
  				hls.loadSource(fm.openUrl(file.hash));
  				hls.attachMedia(node[0]);
  				if (autoplay) {
  					hls.on(cHls.Events.MANIFEST_PARSED, function() {
  						play(node[0]);
  					});
  				}
  			},
  			loadDash = function(file) {
  				render(file);
  				pDash = window.dashjs.MediaPlayer().create();
  				pDash.getDebug().setLogToBrowserConsole(false);
  				pDash.initialize(node[0], fm.openUrl(file.hash), autoplay);
  				pDash.on('error', function(e) {
  					reset(true);
  				});
  			},
  			loadFlv = function(file) {
  				if (!cFlv.isSupported()) {
  					cFlv = false;
  					return;
  				}
  				var player = cFlv.createPlayer({
  					type: 'flv',
  					url: fm.openUrl(file.hash)
  				});
  				render(file);
  				player.on(cFlv.Events.ERROR, function() {
  					player.destroy();
  					reset(true);
  				});
  				player.attachMediaElement(node[0]);
  				player.load();
  				play(player);
  			},
  			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(true);
  						}
  					});
  				}
  			},
  			reset = function(showInfo) {
  				tm && clearTimeout(tm);
  				if (node && node.parent().length) {
  					var elm = node[0];
  					win.off('viewchange.video');
  					pDash && pDash.reset();
  					try {
  						elm.pause();
  						node.empty();
  						elm.src = '';
  						elm.load();
  					} catch(e) {}
  					node.remove();
  					node = null;
  				}
  				showInfo && ql.info.show();
  			};
  
  		preview.on(ql.evUpdate, function(e) {
  			var file = e.file,
  				mime = file.mime.toLowerCase(),
  				type = mimes[mime],
  				stock, playPromise;
  			
  			if (mimes[mime] && ql.dispInlineRegex.test(file.mime) && (((type === 'm3u8' || (type === 'mpd' && !fm.UA.iOS) || type === 'flv') && !fm.UA.ltIE10) || ql.support.video[type])) {
  				autoplay = ql.autoPlay();
  				if (ql.support.video[type] && (type !== 'm3u8' || fm.UA.Safari)) {
  					e.stopImmediatePropagation();
  					render(file, { src: fm.openUrl(file.hash) });
  					play(node[0]);
  				} else {
  					if (cHls !== false && fm.options.cdns.hls && type === 'm3u8') {
  						e.stopImmediatePropagation();
  						if (cHls) {
  							loadHls(file);
  						} else {
  							stock = window.Hls;
  							delete window.Hls;
  							fm.loadScript(
  								[ fm.options.cdns.hls ],
  								function(res) { 
  									cHls = res || window.Hls || false;
  									window.Hls = stock;
  									cHls && loadHls(file);
  								},
  								{
  									tryRequire: true,
  									error : function() {
  										cHls = false;
  									}
  								}
  							);
  						}
  					} else if (cDash !== false && fm.options.cdns.dash && type === 'mpd') {
  						e.stopImmediatePropagation();
  						if (cDash) {
  							loadDash(file);
  						} else {
  							fm.loadScript(
  								[ fm.options.cdns.dash ],
  								function() {
  									// dashjs require window.dashjs in global scope
  									cDash = window.dashjs? true : false;
  									cDash && loadDash(file);
  								},
  								{
  									tryRequire: true,
  									error : function() {
  										cDash = false;
  									}
  								}
  							);
  						}
  					} else if (cFlv !== false && fm.options.cdns.flv && type === 'flv') {
  						e.stopImmediatePropagation();
  						if (cFlv) {
  							loadFlv(file);
  						} else {
  							stock = window.flvjs;
  							delete window.flvjs;
  							fm.loadScript(
  								[ fm.options.cdns.flv ],
  								function(res) { 
  									cFlv = res || window.flvjs || false;
  									window.flvjs = stock;
  									cFlv && loadFlv(file);
  								},
  								{
  									tryRequire: true,
  									error : function() {
  										cFlv = false;
  									}
  								}
  							);
  						}
  					}
  				}
  			}
  		}).on('change', reset);
  	}