Improve media player:
- Always show overlay if the user is using it. - Pause the video during seeking for easier access.
This commit is contained in:
+93
-33
@@ -213,32 +213,52 @@ class XMediaPlayer {
|
||||
this._controls.appendChild(this._controlFullscreen);
|
||||
|
||||
// Now begin listening to all events that are relevant.
|
||||
for (let event of ["Abort", "CanPlay", "CanPlayThrough", "DurationChange", "Emptied", "Encrypted", "Ended", "Error", "LoadedData", "LoadedMetaData", "LoadStart", "Pause", "Play", "Playing", "Progress", "RateChange", "Seeked", "Seeking", "Stalled", "Suspend", "TimeUpdate", "VolumeChange", "Waiting", "DblClick", "Click", "KeyDown"]) {
|
||||
this._media.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["FullscreenChange", "FullscreenError", "KeyDown", "MouseEnter", "MouseLeave", "MouseMove", "Wheel"]) {
|
||||
this._container.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Click", "KeyDown"]) {
|
||||
this._controlPlay.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Input", "KeyDown", "Wheel"]) {
|
||||
this._controlProgress.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Click", "KeyDown"]) {
|
||||
this._controlMute.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Input", "KeyDown", "Wheel"]) {
|
||||
this._controlVolume.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Input"]) {
|
||||
this._variants.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Click", "KeyDown"]) {
|
||||
this._controlVariant.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
}
|
||||
for (let event of ["Click", "KeyDown"]) {
|
||||
this._controlFullscreen.addEventListener(event.toLowerCase(), (ev) => { this[`_on${event}`](ev); });
|
||||
for (let event of [
|
||||
"Abort",
|
||||
"CanPlay",
|
||||
"CanPlayThrough",
|
||||
"Click",
|
||||
"DblClick",
|
||||
"DurationChange",
|
||||
"Emptied",
|
||||
"Encrypted",
|
||||
"Ended",
|
||||
"Error",
|
||||
"FullscreenChange",
|
||||
"FullscreenError",
|
||||
"Input",
|
||||
"KeyDown",
|
||||
"LoadedData",
|
||||
"LoadedMetaData",
|
||||
"LoadStart",
|
||||
"MouseEnter",
|
||||
"MouseLeave",
|
||||
"MouseMove",
|
||||
"MouseDown",
|
||||
"MouseUp",
|
||||
"Pause",
|
||||
"Play",
|
||||
"Playing",
|
||||
"Progress",
|
||||
"RateChange",
|
||||
"Seeked",
|
||||
"Seeking",
|
||||
"Stalled",
|
||||
"Suspend",
|
||||
"TimeUpdate",
|
||||
"VolumeChange",
|
||||
"Waiting",
|
||||
"Wheel"
|
||||
]) {
|
||||
for (let element of [this._media, this._container, this._controlPlay, this._controlProgress, this._controlMute, this._controlVolume, this._variants, this._controlVariant, this._controlFullscreen]) {
|
||||
element.addEventListener(event.toLocaleLowerCase(), (ev) => {
|
||||
try {
|
||||
this[`_on${event}`](ev);
|
||||
} catch (ex) {
|
||||
console.error(`Event '${event}' handler encountered exception: ${ex}`);
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// And update all controls once.
|
||||
@@ -372,7 +392,31 @@ class XMediaPlayer {
|
||||
this.showOverlay();
|
||||
}
|
||||
_onMouseLeave(ev) { }
|
||||
_onMouseDown(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
if (ev.target == this._controlProgress) {
|
||||
if ((ev.button == 0) && (!this._isSeeking)) {
|
||||
this._isSeeking = true;
|
||||
this._isSeekingPaused = this._media.paused;
|
||||
this._media.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
_onMouseUp(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
if (ev.target == this._controlProgress) {
|
||||
if ((ev.button == 0) && (this._isSeeking)) {
|
||||
if (!this._isSeekingPaused) // Resume playback after dragging the dot.
|
||||
this._media.play();
|
||||
this._isSeeking = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
_onKeyDown(ev) {
|
||||
this.showOverlay();
|
||||
|
||||
// Ignore IME compositing.
|
||||
if (ev.isComposing || ev.keyCode === 229) {
|
||||
return;
|
||||
@@ -421,10 +465,12 @@ class XMediaPlayer {
|
||||
}
|
||||
|
||||
// Prevent default behavior and stop propagation.
|
||||
this.showOverlay();
|
||||
ev.preventDefault();
|
||||
ev.stopPropagation();
|
||||
}
|
||||
_onWheel(ev) {
|
||||
this.showOverlay();
|
||||
}
|
||||
_onInput(ev) {
|
||||
this.toggleVariants(false);
|
||||
if (ev.target == this._controlProgress) {
|
||||
@@ -496,10 +542,14 @@ class XMediaPlayer {
|
||||
|
||||
// Control Functions
|
||||
togglePlayPause() {
|
||||
if (this._media.paused) {
|
||||
this._media.play();
|
||||
if (this._isSeeking) {
|
||||
this._isSeekingPaused = !this._isSeekingPaused;
|
||||
} else {
|
||||
this._media.pause();
|
||||
if (this._media.paused) {
|
||||
this._media.play();
|
||||
} else {
|
||||
this._media.pause();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -539,11 +589,21 @@ class XMediaPlayer {
|
||||
clearTimeout(this._overlayTimeout);
|
||||
}
|
||||
|
||||
if (!this._media.paused && !this._media.ended && !this._media.error) {
|
||||
this._container.classList.add("hide");
|
||||
// Prevent overlay from hiding during special operations.
|
||||
if (
|
||||
this._media.paused ||
|
||||
this._media.ended ||
|
||||
this._media.error ||
|
||||
(this._media.readyState !== 4) ||
|
||||
(!this._variants.classList.contains("hide")) ||
|
||||
this._isSeeking) {
|
||||
this.showOverlay();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// In all other cases, just continue.
|
||||
this._container.classList.add("hide");
|
||||
}
|
||||
}
|
||||
|
||||
(function () {
|
||||
|
||||
Reference in New Issue
Block a user