Improving touch input by bringing in `videojs-mobile-ui` (#2719)
* Adding videojs-mobile-ui as a dependency - Using the beta because it fixes an issue with multiple version of videojs loading at once. This is related to MarmadileManteater#56. * Mapping defaultSkipInterval to seekSeconds * Adding CSS to prevent showing duplicate buttons - Added a new variable `usingTouch` to selectively hide the existing `vjs-big-play-button` when the `touch-overlay` is visible. * Renaming CSS class to something more specific * Adding text-shadow behind play / pause button This should make it more visually distinct against a light or colorful background. * Enabling touch-overlay anytime a touch is detected Disabling it whenever mouse input is detected The default behavior of `videojs-mobile-ui` is to only work in Android and iOS, but by forcing the touch behavior to be enabled and selectively showing it only when touch input is detected, it should work on any device with touch input even if the browser doesn't detect that it is running in Android or iOS. * Removing unnecessary code * Removing unintentionally leftover variable * Removing an unnecessary assignment Adding comments to explain why a flag called `forceForTesting` is set to true Disabling the `lockOnRotate` flag. * Moving this flag and wrapper class * Adding whitespace * Making my comment a little more consistent * Changing the punctuation of a comment * Adjusting the CSS to fix a firefox discrepancy * Adding a check for mobile firefox For whatever reason, mobile firefox sometimes triggers onmouseover when a touch occurs, and this is unwanted behavior. * Adding a drop-shadow to the ff and rw icons This should make them easier to see on top of light videos * Hiding the mobile play button according to setting - Added CSS to hide the videojs-mobile-ui play button when the `Display Play Button In Video Player` setting is disabled. * Replacing long computed string with class binding Co-authored-by: absidue <48293849+absidue@users.noreply.github.com> * Adding newline at the end of videoJS.css Co-authored-by: absidue <48293849+absidue@users.noreply.github.com>
This commit is contained in:
parent
12cfe6a3fb
commit
e43fb94a35
|
@ -68,6 +68,7 @@
|
||||||
"video.js": "7.18.1",
|
"video.js": "7.18.1",
|
||||||
"videojs-contrib-quality-levels": "^2.1.0",
|
"videojs-contrib-quality-levels": "^2.1.0",
|
||||||
"videojs-http-source-selector": "^1.1.6",
|
"videojs-http-source-selector": "^1.1.6",
|
||||||
|
"videojs-mobile-ui": "^0.8.0",
|
||||||
"videojs-overlay": "^2.1.4",
|
"videojs-overlay": "^2.1.4",
|
||||||
"videojs-vtt-thumbnails-freetube": "0.0.15",
|
"videojs-vtt-thumbnails-freetube": "0.0.15",
|
||||||
"vue": "^2.7.13",
|
"vue": "^2.7.13",
|
||||||
|
|
|
@ -11,7 +11,8 @@ import 'videojs-overlay/dist/videojs-overlay.css'
|
||||||
import 'videojs-vtt-thumbnails-freetube'
|
import 'videojs-vtt-thumbnails-freetube'
|
||||||
import 'videojs-contrib-quality-levels'
|
import 'videojs-contrib-quality-levels'
|
||||||
import 'videojs-http-source-selector'
|
import 'videojs-http-source-selector'
|
||||||
|
import 'videojs-mobile-ui'
|
||||||
|
import 'videojs-mobile-ui/dist/videojs-mobile-ui.css'
|
||||||
import { IpcChannels } from '../../../constants'
|
import { IpcChannels } from '../../../constants'
|
||||||
import { sponsorBlockSkipSegments } from '../../helpers/sponsorblock'
|
import { sponsorBlockSkipSegments } from '../../helpers/sponsorblock'
|
||||||
import { calculateColorLuminance, colors, showToast } from '../../helpers/utils'
|
import { calculateColorLuminance, colors, showToast } from '../../helpers/utils'
|
||||||
|
@ -105,11 +106,11 @@ export default Vue.extend({
|
||||||
activeAdaptiveFormats: [],
|
activeAdaptiveFormats: [],
|
||||||
mouseTimeout: null,
|
mouseTimeout: null,
|
||||||
touchTimeout: null,
|
touchTimeout: null,
|
||||||
lastTouchTime: null,
|
|
||||||
playerStats: null,
|
playerStats: null,
|
||||||
statsModal: null,
|
statsModal: null,
|
||||||
showStatsModal: false,
|
showStatsModal: false,
|
||||||
statsModalEventName: 'updateStats',
|
statsModalEventName: 'updateStats',
|
||||||
|
usingTouch: false,
|
||||||
dataSetup: {
|
dataSetup: {
|
||||||
fluid: true,
|
fluid: true,
|
||||||
nativeTextTracks: false,
|
nativeTextTracks: false,
|
||||||
|
@ -364,6 +365,22 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
this.player.mobileUi({
|
||||||
|
fullscreen: {
|
||||||
|
enterOnRotate: true,
|
||||||
|
exitOnRotate: true,
|
||||||
|
lockOnRotate: false
|
||||||
|
},
|
||||||
|
// Without this flag, the mobile UI will only activate
|
||||||
|
// if videojs detects it is in Android or iOS
|
||||||
|
// With this flag, the mobile UI could theoretically
|
||||||
|
// work on any device that has a touch input
|
||||||
|
forceForTesting: true,
|
||||||
|
touchControls: {
|
||||||
|
seekSeconds: this.defaultSkipInterval,
|
||||||
|
tapTimeout: 300
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
this.player.volume(this.volume)
|
this.player.volume(this.volume)
|
||||||
this.player.playbackRate(this.defaultPlayback)
|
this.player.playbackRate(this.defaultPlayback)
|
||||||
|
@ -1678,23 +1695,16 @@ export default Vue.extend({
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTouchStart: function (event) {
|
handleTouchStart: function () {
|
||||||
this.touchPauseTimeout = setTimeout(() => {
|
this.usingTouch = true
|
||||||
this.togglePlayPause()
|
|
||||||
}, 1000)
|
|
||||||
|
|
||||||
const touchTime = new Date()
|
|
||||||
|
|
||||||
if (this.lastTouchTime !== null && (touchTime.getTime() - this.lastTouchTime.getTime()) < 250) {
|
|
||||||
this.toggleFullscreen()
|
|
||||||
}
|
|
||||||
|
|
||||||
this.lastTouchTime = touchTime
|
|
||||||
},
|
},
|
||||||
|
|
||||||
handleTouchEnd: function (event) {
|
handleMouseOver: function () {
|
||||||
clearTimeout(this.touchPauseTimeout)
|
// This addresses a discrepancy that only seems to occur in the mobile version of firefox
|
||||||
|
if (navigator.userAgent.search('Firefox') !== -1 && (videojs.browser.IS_ANDROID || videojs.browser.IS_IOS)) { return }
|
||||||
|
this.usingTouch = false
|
||||||
},
|
},
|
||||||
|
|
||||||
toggleShowStatsModal: function() {
|
toggleShowStatsModal: function() {
|
||||||
if (this.format !== 'dash') {
|
if (this.format !== 'dash') {
|
||||||
showToast(this.$t('Video.Stats.Video statistics are not available for legacy videos'))
|
showToast(this.$t('Video.Stats.Video statistics are not available for legacy videos'))
|
||||||
|
|
|
@ -1,5 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="relative">
|
<div
|
||||||
|
class="relative"
|
||||||
|
:class="{
|
||||||
|
'vjs-using-touch': usingTouch,
|
||||||
|
'vjs-hide-play-button': !displayVideoPlayButton
|
||||||
|
}"
|
||||||
|
@mouseover="handleMouseOver"
|
||||||
|
>
|
||||||
<video
|
<video
|
||||||
ref="video"
|
ref="video"
|
||||||
class="ftVideoPlayer video-js vjs-default-skin dark"
|
class="ftVideoPlayer video-js vjs-default-skin dark"
|
||||||
|
@ -9,7 +16,6 @@
|
||||||
:data-setup="JSON.stringify(dataSetup)"
|
:data-setup="JSON.stringify(dataSetup)"
|
||||||
crossorigin="anonymous"
|
crossorigin="anonymous"
|
||||||
@touchstart="handleTouchStart"
|
@touchstart="handleTouchStart"
|
||||||
@touchend="handleTouchEnd"
|
|
||||||
>
|
>
|
||||||
<source
|
<source
|
||||||
v-for="(source, index) in activeSourceList"
|
v-for="(source, index) in activeSourceList"
|
||||||
|
|
|
@ -1848,7 +1848,7 @@ video::-webkit-media-text-track-display {
|
||||||
display: block
|
display: block
|
||||||
}
|
}
|
||||||
|
|
||||||
.video-js .vjs-load-progress div,.vjs-seeking .vjs-big-play-button,.vjs-waiting .vjs-big-play-button {
|
.video-js .vjs-load-progress div,.vjs-seeking .vjs-big-play-button,.vjs-waiting .vjs-big-play-button,.vjs-using-touch .vjs-big-play-button {
|
||||||
display: none!important
|
display: none!important
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2202,3 +2202,36 @@ video::-webkit-media-text-track-display {
|
||||||
display: initial;
|
display: initial;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.videoPlayer .video-js .vjs-touch-overlay {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vjs-using-touch .video-js.vjs-touch-enabled .vjs-touch-overlay {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-js .vjs-touch-overlay .vjs-play-control .vjs-icon-placeholder:before {
|
||||||
|
content: "\f103" !important;
|
||||||
|
text-shadow: 0 0 25px rgb(0 0 0 / 50%), 0 0 10px rgb(0 0 0 / 50%), 2px 2px 8px rgb(206 89 55 / 0%);
|
||||||
|
color: white;
|
||||||
|
font-size: 18vw;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
background-image: none !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-js .vjs-touch-overlay .vjs-play-control.vjs-paused .vjs-icon-placeholder:before {
|
||||||
|
content: "\f101" !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.vjs-hide-play-button .video-js .vjs-touch-overlay .vjs-play-control .vjs-icon-placeholder:before {
|
||||||
|
content: " " !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-js .vjs-touch-overlay.skip {
|
||||||
|
-webkit-filter: drop-shadow(0px 0px 4px black);
|
||||||
|
filter: drop-shadow(0px 0px 4px black);
|
||||||
|
}
|
||||||
|
|
|
@ -8125,6 +8125,13 @@ videojs-http-source-selector@^1.1.6:
|
||||||
video.js "^7.0.0"
|
video.js "^7.0.0"
|
||||||
videojs-contrib-quality-levels "^2.0.4"
|
videojs-contrib-quality-levels "^2.0.4"
|
||||||
|
|
||||||
|
videojs-mobile-ui@^0.8.0:
|
||||||
|
version "0.8.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/videojs-mobile-ui/-/videojs-mobile-ui-0.8.0.tgz#40a1c6f9302071b9bbe95937c934114600916ac5"
|
||||||
|
integrity sha512-Jd+u/ctjUkbZlT1cAA0umTu0LQwSZSFG+02cJxShuwq27B6rfrRALETK/gsuTc7U27lB9fbwcF7HBMaNxW62nA==
|
||||||
|
dependencies:
|
||||||
|
global "^4.4.0"
|
||||||
|
|
||||||
videojs-overlay@^2.1.4:
|
videojs-overlay@^2.1.4:
|
||||||
version "2.1.5"
|
version "2.1.5"
|
||||||
resolved "https://registry.yarnpkg.com/videojs-overlay/-/videojs-overlay-2.1.5.tgz#763b9d89dff87c32d94e9a873451a5fb25f02c8e"
|
resolved "https://registry.yarnpkg.com/videojs-overlay/-/videojs-overlay-2.1.5.tgz#763b9d89dff87c32d94e9a873451a5fb25f02c8e"
|
||||||
|
|
Loading…
Reference in New Issue