constructor (node, o) {

		const
			t = this,
			element = typeof node === 'string' ? document.getElementById(node) : node
		;

		// enforce object, even without "new" (via John Resig)
		if (!(t instanceof MediaElementPlayer)) {
			return new MediaElementPlayer(element, o);
		}

		// these will be reset after the MediaElement.success fires
		// t.media will be the fake node to emulate all HTML5 events, methods, etc
		// t.node will be the node to be restored
		t.node = t.media = element;

		if (!t.node) {
			return;
		}

		// check for existing player
		if (t.media.player) {
			return t.media.player;
		}

		t.hasFocus = false;

		t.controlsAreVisible = true;

		t.controlsEnabled = true;

		t.controlsTimer = null;

		t.currentMediaTime = 0;

		t.proxy = null;

		// try to get options from data-mejsoptions
		if (o === undefined) {
			const options = t.node.getAttribute('data-mejsoptions');
			o = options ? JSON.parse(options) : {};
		}

		// extend default options
		t.options = Object.assign({}, config, o);

		// Check `loop` attribute to modify options
		if (t.options.loop && !t.media.getAttribute('loop')) {
			t.media.loop = true;
			t.node.loop = true;
		} else if (t.media.loop) {
			t.options.loop = true;
		}

		if (!t.options.timeFormat) {
			// Generate the time format according to options
			t.options.timeFormat = 'mm:ss';
			if (t.options.alwaysShowHours) {
				t.options.timeFormat = 'hh:mm:ss';
			}
			if (t.options.showTimecodeFrameCount) {
				t.options.timeFormat += ':ff';
			}
		}

		calculateTimeFormat(0, t.options, t.options.framesPerSecond || 25);

		// unique ID
		t.id = `mep_${mejs.mepIndex++}`;

		// add to player array (for focus events)
		mejs.players[t.id] = t;

		t.init();

		return t;
	}
Wrap a MediaElement object in player controls

@constructor
@param {HTMLElement|String} node
@param {Object} o
@return {?MediaElementPlayer}