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:
Emma 2022-10-24 13:49:52 -04:00 committed by GitHub
parent 12cfe6a3fb
commit e43fb94a35
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 77 additions and 20 deletions

View File

@ -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",

View File

@ -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'))

View File

@ -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"

View File

@ -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
} }
@ -2201,4 +2201,37 @@ video::-webkit-media-text-track-display {
.vjs-full-window .video-js.vjs-full-screen .vjs-control.vjs-button.vjs-button-fullwindow { .vjs-full-window .video-js.vjs-full-screen .vjs-control.vjs-button.vjs-button-fullwindow {
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);
}

View File

@ -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"