position: relative !important;
}
}
+
+ /deep/ .video-js.vjs-theater-enabled {
+ width: 100%;
+ height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
+ }
}
#video-not-found {
enableHotkeys: true,
peertubeLink: false,
poster: this.video.previewUrl,
- startTime
+ startTime,
+ theaterMode: true
})
if (this.videojsLocaleLoaded === false) {
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<svg width="24px" height="24px" viewBox="0 0 24 24" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
+ <!-- Generator: Sketch 43.2 (39069) - http://www.bohemiancoding.com/sketch -->
+ <title>theater</title>
+ <defs></defs>
+ <g id="Page-1" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd">
+ <g id="Artboard-4" transform="translate(-576.000000, -159.000000)" stroke="#fff" stroke-width="2">
+ <g id="33" transform="translate(576.000000, 159.000000)">
+ <rect id="Rectangle-433" x="1" y="6" width="22" height="12"></rect>
+ </g>
+ </g>
+ </g>
+</svg>
import './webtorrent-info-button'
import './peertube-videojs-plugin'
import './peertube-load-progress-bar'
+import './theater-button'
import { videojsUntyped } from './peertube-videojs-typings'
import { buildVideoEmbed, buildVideoLink, copyToClipboard } from './utils'
import { getCompleteLocale, getShortLocale, is18nLocale, isDefaultLocale } from '../../../../shared/models/i18n/i18n'
peertubeLink: boolean,
poster: string,
startTime: number
+ theaterMode: boolean
}) {
const videojsOptions = {
controls: true,
function getControlBarChildren (options: {
peertubeLink: boolean
+ theaterMode: boolean
}) {
const children = {
'playToggle': {},
})
}
+ if (options.theaterMode === true) {
+ Object.assign(children, {
+ 'theaterButton': {}
+ })
+ }
+
Object.assign(children, {
'fullscreenToggle': {}
})
private player: any
private currentVideoFile: VideoFile
private torrent: WebTorrent.Torrent
+ private fakeRenderer
private autoResolution = true
private isAutoResolutionObservation = false
// Don't need to destroy renderer, video player will be destroyed
this.flushVideoFile(this.currentVideoFile, false)
+
+ this.destroyFakeRenderer()
}
getCurrentResolutionId () {
console.log('Adding ' + magnetOrTorrentUrl + '.')
const oldTorrent = this.torrent
- let fakeRenderer
const torrentOptions = {
store: (chunkLength, storeOpts) => new CacheChunkStore(new PeertubeChunkStore(chunkLength, storeOpts), {
max: 100
if (options.delay) {
const fakeVideoElem = document.createElement('video')
renderVideo(torrent.files[0], fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => {
- fakeRenderer = renderer
+ this.fakeRenderer = renderer
if (err) console.error('Cannot render new torrent in fake video element.', err)
// Render the video in a few seconds? (on resolution change for example, we wait some seconds of the new video resolution)
this.addTorrentDelay = setTimeout(() => {
- if (fakeRenderer) {
- if (fakeRenderer.destroy) {
- try {
- fakeRenderer.destroy()
- } catch (err) {
- console.log('Cannot destroy correctly fake renderer.', err)
- }
- }
- fakeRenderer = undefined
- }
+ this.destroyFakeRenderer()
const paused = this.player.paused()
return this.videoFiles[Math.floor(this.videoFiles.length / 2)]
}
+ private destroyFakeRenderer () {
+ if (this.fakeRenderer) {
+ if (this.fakeRenderer.destroy) {
+ try {
+ this.fakeRenderer.destroy()
+ } catch (err) {
+ console.log('Cannot destroy correctly fake renderer.', err)
+ }
+ }
+ this.fakeRenderer = undefined
+ }
+ }
+
// Thanks: https://github.com/videojs/video.js/issues/4460#issuecomment-312861657
private initSmoothProgressBar () {
const SeekBar = videojsUntyped.getComponent('SeekBar')
--- /dev/null
+import { VideoJSComponentInterface, videojsUntyped } from './peertube-videojs-typings'
+import { getStoredTheater, saveTheaterInStore } from './utils'
+
+const Button: VideoJSComponentInterface = videojsUntyped.getComponent('Button')
+class TheaterButton extends Button {
+
+ private static readonly THEATER_MODE_CLASS = 'vjs-theater-enabled'
+
+ constructor (player, options) {
+ super(player, options)
+
+ const enabled = getStoredTheater()
+ if (enabled === true) {
+ this.player_.addClass(TheaterButton.THEATER_MODE_CLASS)
+ this.handleTheaterChange()
+ }
+ }
+
+ buildCSSClass () {
+ return `vjs-theater-control ${super.buildCSSClass()}`
+ }
+
+ handleTheaterChange () {
+ if (this.isTheaterEnabled()) {
+ this.controlText('Normal mode')
+ } else {
+ this.controlText('Theater mode')
+ }
+
+ saveTheaterInStore(this.isTheaterEnabled())
+ }
+
+ handleClick () {
+ this.player_.toggleClass(TheaterButton.THEATER_MODE_CLASS)
+
+ this.handleTheaterChange()
+ }
+
+ private isTheaterEnabled () {
+ return this.player_.hasClass(TheaterButton.THEATER_MODE_CLASS)
+ }
+}
+
+TheaterButton.prototype.controlText_ = 'Theater mode'
+
+TheaterButton.registerComponent('TheaterButton', TheaterButton)
return undefined
}
+function getStoredTheater () {
+ const value = getLocalStorage('theater-enabled')
+ if (value !== null && value !== undefined) return value === 'true'
+
+ return undefined
+}
+
function saveVolumeInStore (value: number) {
return setLocalStorage('volume', value.toString())
}
return setLocalStorage('mute', value.toString())
}
+function saveTheaterInStore (enabled: boolean) {
+ return setLocalStorage('theater-enabled', enabled.toString())
+}
+
function saveAverageBandwidth (value: number) {
return setLocalStorage('average-bandwidth', value.toString())
}
videoFileMaxByResolution,
videoFileMinByResolution,
copyToClipboard,
+ getStoredTheater,
+ saveTheaterInStore,
isMobile,
bytes
}
$video-thumbnail-height: 110px;
$video-thumbnail-width: 200px;
+
+$theater-bottom-space: 85px;
.vjs-resolution-control,
.vjs-fullscreen-control,
.vjs-peertube-link,
+ .vjs-theater-control,
.vjs-settings
{
color: $primary-foreground-color !important;
padding: 0 5px;
}
+ .vjs-theater-control {
+ @include disable-outline;
+
+ width: 37px;
+ margin-right: 1px;
+
+ .vjs-icon-placeholder {
+ display: inline-block;
+ width: 22px;
+ height: 22px;
+ vertical-align: middle;
+ background: url('#{$assets-path}/player/images/theater.svg') no-repeat;
+ background-size: contain;
+
+ &::before {
+ content: '';
+ }
+ }
+ }
+
.vjs-fullscreen-control {
@include disable-outline;
}
@media screen and (max-width: 750px) {
+ .vjs-theater-control {
+ display: none;
+ }
+
.vjs-dock-text {
font-size: 16px;
}
enableHotkeys: true,
peertubeLink: true,
poster: window.location.origin + videoInfo.previewPath,
- startTime
+ startTime,
+ theaterMode: false
})
videojs(videoContainerId, videojsOptions, function () {
const player = this