Add theatre mode
This commit is contained in:
parent
54a3a12ed2
commit
054a103b28
|
@ -21,6 +21,11 @@
|
|||
position: relative !important;
|
||||
}
|
||||
}
|
||||
|
||||
/deep/ .video-js.vjs-theater-enabled {
|
||||
width: 100%;
|
||||
height: calc(100vh - #{$header-height} - #{$theater-bottom-space});
|
||||
}
|
||||
}
|
||||
|
||||
#video-not-found {
|
||||
|
|
|
@ -368,7 +368,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
|
|||
enableHotkeys: true,
|
||||
peertubeLink: false,
|
||||
poster: this.video.previewUrl,
|
||||
startTime
|
||||
startTime,
|
||||
theaterMode: true
|
||||
})
|
||||
|
||||
if (this.videojsLocaleLoaded === false) {
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
<?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>
|
After Width: | Height: | Size: 702 B |
|
@ -10,6 +10,7 @@ import './settings-menu-button'
|
|||
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'
|
||||
|
@ -28,6 +29,7 @@ function getVideojsOptions (options: {
|
|||
peertubeLink: boolean,
|
||||
poster: string,
|
||||
startTime: number
|
||||
theaterMode: boolean
|
||||
}) {
|
||||
const videojsOptions = {
|
||||
controls: true,
|
||||
|
@ -63,6 +65,7 @@ function getVideojsOptions (options: {
|
|||
|
||||
function getControlBarChildren (options: {
|
||||
peertubeLink: boolean
|
||||
theaterMode: boolean
|
||||
}) {
|
||||
const children = {
|
||||
'playToggle': {},
|
||||
|
@ -105,6 +108,12 @@ function getControlBarChildren (options: {
|
|||
})
|
||||
}
|
||||
|
||||
if (options.theaterMode === true) {
|
||||
Object.assign(children, {
|
||||
'theaterButton': {}
|
||||
})
|
||||
}
|
||||
|
||||
Object.assign(children, {
|
||||
'fullscreenToggle': {}
|
||||
})
|
||||
|
|
|
@ -55,6 +55,7 @@ class PeerTubePlugin extends Plugin {
|
|||
private player: any
|
||||
private currentVideoFile: VideoFile
|
||||
private torrent: WebTorrent.Torrent
|
||||
private fakeRenderer
|
||||
private autoResolution = true
|
||||
private isAutoResolutionObservation = false
|
||||
|
||||
|
@ -123,6 +124,8 @@ class PeerTubePlugin extends Plugin {
|
|||
|
||||
// Don't need to destroy renderer, video player will be destroyed
|
||||
this.flushVideoFile(this.currentVideoFile, false)
|
||||
|
||||
this.destroyFakeRenderer()
|
||||
}
|
||||
|
||||
getCurrentResolutionId () {
|
||||
|
@ -185,7 +188,6 @@ class PeerTubePlugin extends Plugin {
|
|||
console.log('Adding ' + magnetOrTorrentUrl + '.')
|
||||
|
||||
const oldTorrent = this.torrent
|
||||
let fakeRenderer
|
||||
const torrentOptions = {
|
||||
store: (chunkLength, storeOpts) => new CacheChunkStore(new PeertubeChunkStore(chunkLength, storeOpts), {
|
||||
max: 100
|
||||
|
@ -205,7 +207,7 @@ class PeerTubePlugin extends Plugin {
|
|||
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)
|
||||
|
||||
|
@ -217,16 +219,7 @@ class PeerTubePlugin extends Plugin {
|
|||
|
||||
// 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()
|
||||
|
||||
|
@ -567,6 +560,19 @@ class PeerTubePlugin extends Plugin {
|
|||
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')
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
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)
|
|
@ -51,6 +51,13 @@ function getAverageBandwidth () {
|
|||
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())
|
||||
}
|
||||
|
@ -59,6 +66,10 @@ function saveMuteInStore (value: boolean) {
|
|||
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())
|
||||
}
|
||||
|
@ -133,6 +144,8 @@ export {
|
|||
videoFileMaxByResolution,
|
||||
videoFileMinByResolution,
|
||||
copyToClipboard,
|
||||
getStoredTheater,
|
||||
saveTheaterInStore,
|
||||
isMobile,
|
||||
bytes
|
||||
}
|
||||
|
|
|
@ -31,3 +31,5 @@ $footer-border-color: $header-border-color;
|
|||
|
||||
$video-thumbnail-height: 110px;
|
||||
$video-thumbnail-width: 200px;
|
||||
|
||||
$theater-bottom-space: 85px;
|
||||
|
|
|
@ -135,6 +135,7 @@
|
|||
.vjs-resolution-control,
|
||||
.vjs-fullscreen-control,
|
||||
.vjs-peertube-link,
|
||||
.vjs-theater-control,
|
||||
.vjs-settings
|
||||
{
|
||||
color: $primary-foreground-color !important;
|
||||
|
@ -394,6 +395,26 @@
|
|||
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;
|
||||
|
||||
|
@ -440,6 +461,10 @@
|
|||
}
|
||||
|
||||
@media screen and (max-width: 750px) {
|
||||
.vjs-theater-control {
|
||||
display: none;
|
||||
}
|
||||
|
||||
.vjs-dock-text {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
|
|
@ -99,7 +99,8 @@ loadLocale(window.location.origin, videojs, navigator.language)
|
|||
enableHotkeys: true,
|
||||
peertubeLink: true,
|
||||
poster: window.location.origin + videoInfo.previewPath,
|
||||
startTime
|
||||
startTime,
|
||||
theaterMode: false
|
||||
})
|
||||
videojs(videoContainerId, videojsOptions, function () {
|
||||
const player = this
|
||||
|
|
Loading…
Reference in New Issue