import videojs from 'video.js'
+import { isMobile } from '../utils'
function getPauseBezel () {
return `
constructor (player: videojs.Player, options?: videojs.ComponentOptions) {
super(player, options)
+ // Hide bezels on mobile since we already have our mobile overlay
+ if (isMobile()) return
+
player.on('pause', (_: any) => {
if (player.seeking() || player.ended()) return
this.container.innerHTML = getPauseBezel()
--- /dev/null
+import videojs from 'video.js'
+
+import debug from 'debug'
+
+const logger = debug('peertube:player:mobile')
+
+const Component = videojs.getComponent('Component')
+class PeerTubeMobileButtons extends Component {
+
+ createEl () {
+ const container = super.createEl('div', {
+ className: 'vjs-mobile-buttons-overlay'
+ }) as HTMLDivElement
+
+ container.addEventListener('click', () => {
+ logger('Set user as inactive')
+
+ this.player_.userActive(false)
+ })
+
+ const mainButton = super.createEl('div', {
+ className: 'main-button'
+ }) as HTMLDivElement
+
+ mainButton.addEventListener('click', e => {
+ e.stopPropagation()
+
+ if (this.player_.paused() || this.player_.ended()) {
+ this.player_.play()
+ return
+ }
+
+ this.player_.pause()
+ })
+
+ container.appendChild(mainButton)
+
+ return container
+ }
+}
+
+videojs.registerComponent('PeerTubeMobileButtons', PeerTubeMobileButtons)
--- /dev/null
+import videojs from 'video.js'
+import './peertube-mobile-buttons'
+
+const Plugin = videojs.getPlugin('plugin')
+
+class PeerTubeMobilePlugin extends Plugin {
+
+ constructor (player: videojs.Player, options: videojs.PlayerOptions) {
+ super(player, options)
+
+ player.addChild('PeerTubeMobileButtons')
+ }
+}
+
+videojs.registerPlugin('peertubeMobile', PeerTubeMobilePlugin)
+export { PeerTubeMobilePlugin }
import './videojs-components/settings-panel-child'
import './videojs-components/theater-button'
import './playlist/playlist-plugin'
+import './mobile/peertube-mobile-plugin'
import videojs from 'video.js'
import { HlsJsEngineSettings } from '@peertube/p2p-media-loader-hlsjs'
import { PluginsManager } from '@root-helpers/plugins-manager'
VideoJSPluginOptions
} from './peertube-videojs-typings'
import { TranslationsManager } from './translations-manager'
-import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isSafari } from './utils'
+import { buildVideoOrPlaylistEmbed, getRtcConfig, isIOS, isMobile, isSafari } from './utils'
// Change 'Playback Rate' to 'Speed' (smaller for our settings menu)
(videojs.getComponent('PlaybackRateMenuButton') as any).prototype.controlText_ = 'Speed'
videoEmbedTitle: options.common.embedTitle
})
+ if (isMobile()) player.peertubeMobile()
+
player.bezels()
+
player.stats({
videoUUID: options.common.videoUUID,
videoIsLive: options.common.isLive,
import { PeerTubePluginOptions, UserWatching, VideoJSCaption } from './peertube-videojs-typings'
import { isMobile } from './utils'
import { SettingsButton } from './videojs-components/settings-menu-button'
+import debug from 'debug'
+
+const logger = debug('peertube:player:peertube')
const Plugin = videojs.getPlugin('plugin')
}
private alterInactivity () {
- if (this.menuOpened || this.mouseInSettings || this.mouseInControlBar || this.isTouchEnabled()) {
+ if (this.menuOpened || this.mouseInSettings || this.mouseInControlBar) {
this.setInactivityTimeout(0)
return
}
private setInactivityTimeout (timeout: number) {
(this.player as any).cache_.inactivityTimeout = timeout
this.player.options_.inactivityTimeout = timeout
+
+ logger('Set player inactivity to ' + timeout)
}
private isTouchEnabled () {
bezels (): void
+ peertubeMobile (): void
+
stats (options?: StatsCardOptions): StatsForNerdsPlugin
textTracks (): TextTrackList & {
update () {
const disabled = this.nextPreviousVideoButtonOptions.isDisabled()
- console.log(disabled)
if (disabled) this.addClass('vjs-disabled')
else this.removeClass('vjs-disabled')
$control-bar-height: 38px;
$control-bar-icon-size: 26px;
$control-bar-volume-slider-height: 14px;
+$control-bar-slider-top: -10px;
$control-bar-font-size: 14px;
$control-bar-play-font-size: 34px;
$control-bar-next-previous-play-font-size: 14px;
$control-bar-button-width: 38px;
+$control-bar-total-height: $control-bar-height - $control-bar-slider-top;
+
$slider-bg-color: lighten($primary-background-color, 33%);
$progress-margin: 10px;
@use './_player-variables' as *;
.video-js.vjs-peertube-skin .vjs-control-bar {
+ z-index: 100;
+
height: $control-bar-height;
background: linear-gradient(rgba(0, 0, 0, 0.2), rgba(0, 0, 0, 0.6));
box-shadow: 0 -15px 40px 10px rgba(0, 0, 0, 0.2);
@include margin-left($progress-margin);
position: absolute;
- top: -10px;
+ top: $control-bar-slider-top;
z-index: 100; // On top of the progress bar
width: calc(100% - (2 * #{$progress-margin}));
height: 14px;
+@use 'sass:math';
@use '_variables' as *;
@use '_mixins' as *;
+@use './_player-variables' as *;
/* Special mobile style */
}
}
}
+
+.vjs-mobile-buttons-overlay {
+ display: none;
+
+ position: absolute;
+ background-color: rgba(0, 0, 0, 0.4);
+ width: 100%;
+ height: 100%;
+ top: 0;
+
+ .vjs-user-active,
+ .vjs-paused {
+ display: block;
+ }
+
+ .main-button {
+ font-family: VideoJS;
+ font-weight: normal;
+ font-style: normal;
+ font-size: 5em;
+ width: fit-content;
+ margin: auto;
+ position: relative;
+ top: calc(50% - 10px);
+ transform: translateY(-50%);
+ }
+}
+
+.vjs-paused {
+ .main-button {
+ &:before {
+ content: '\f101';
+ }
+ }
+}
+
+.vjs-playing {
+ .main-button {
+ &:before {
+ content: '\f103';
+ }
+ }
+}
+
+.vjs-ended {
+ .main-button {
+ &:before {
+ content: '\f116';
+ }
+ }
+}
+
+.vjs-has-started {
+
+ &.vjs-user-active,
+ &.vjs-paused {
+ .vjs-mobile-buttons-overlay {
+ display: block;
+ }
+ }
+
+ &.vjs-seeking,
+ &.vjs-scrubbing,
+ &.vjs-waiting {
+ .vjs-mobile-buttons-overlay {
+ display: none;
+ }
+ }
+}
opacity: $primary-foreground-opacity;
margin: 0 auto;
font-size: $font-size !important;
+ z-index: 100;
width: auto;
overflow: hidden;