"expect-webdriverio": "^3.4.0",
"focus-visible": "^5.0.2",
"geckodriver": "^3.2.0",
- "hls.js": "1.2.7",
+ "hls.js": "1.2.9",
"html-loader": "^4.1.0",
"html-webpack-plugin": "^5.3.1",
"https-browserify": "^1.0.0",
import './shared/control-bar/peertube-link-button'
import './shared/control-bar/peertube-load-progress-bar'
import './shared/control-bar/theater-button'
+import './shared/control-bar/peertube-live-display'
import './shared/settings/resolution-menu-button'
import './shared/settings/resolution-menu-item'
import './shared/settings/settings-dialog'
export * from './next-previous-video-button'
export * from './p2p-info-button'
export * from './peertube-link-button'
+export * from './peertube-live-display'
export * from './peertube-load-progress-bar'
export * from './theater-button'
--- /dev/null
+import videojs from 'video.js'
+import { PeerTubeLinkButtonOptions } from '../../types'
+
+const ClickableComponent = videojs.getComponent('ClickableComponent')
+
+class PeerTubeLiveDisplay extends ClickableComponent {
+ private interval: any
+
+ private contentEl_: any
+
+ constructor (player: videojs.Player, options?: PeerTubeLinkButtonOptions) {
+ super(player, options as any)
+
+ this.interval = this.setInterval(() => this.updateClass(), 1000)
+
+ this.show()
+ this.updateSync(true)
+ }
+
+ dispose () {
+ if (this.interval) {
+ this.clearInterval(this.interval)
+ this.interval = undefined
+ }
+
+ this.contentEl_ = null
+
+ super.dispose()
+ }
+
+ createEl () {
+ const el = super.createEl('div', {
+ className: 'vjs-live-control vjs-control'
+ })
+
+ this.contentEl_ = videojs.dom.createEl('div', {
+ className: 'vjs-live-display'
+ }, {
+ 'aria-live': 'off'
+ })
+
+ this.contentEl_.appendChild(videojs.dom.createEl('span', {
+ className: 'vjs-control-text',
+ textContent: `${this.localize('Stream Type')}\u00a0`
+ }))
+
+ this.contentEl_.appendChild(document.createTextNode(this.localize('LIVE')))
+
+ el.appendChild(this.contentEl_)
+ return el
+ }
+
+ handleClick () {
+ const hlsjs = this.getHLSJS()
+ if (!hlsjs) return
+
+ this.player().currentTime(hlsjs.liveSyncPosition)
+ this.updateSync(true)
+ }
+
+ private updateClass () {
+ const hlsjs = this.getHLSJS()
+ if (!hlsjs) return
+
+ const isSync = Math.abs(this.player().currentTime() - hlsjs.liveSyncPosition) < 10
+ this.updateSync(isSync)
+ }
+
+ private updateSync (isSync: boolean) {
+ if (isSync) {
+ this.addClass('synced-with-live-edge')
+ this.removeAttribute('title')
+ this.disable()
+ } else {
+ this.removeClass('synced-with-live-edge')
+ this.setAttribute('title', this.localize('Go back to the live'))
+ this.enable()
+ }
+ }
+
+ private getHLSJS () {
+ const p2pMediaLoader = this.player()?.p2pMediaLoader
+ if (!p2pMediaLoader) return undefined
+
+ return p2pMediaLoader().getHLSJS()
+ }
+}
+
+videojs.registerComponent('PeerTubeLiveDisplay', PeerTubeLiveDisplay)
}
Object.assign(children, {
- currentTimeDisplay: {},
- timeDivider: {},
- durationDisplay: {},
- liveDisplay: {},
+ ...this.getTimeControls(),
flexibleWidthSpacer: {},
}
}
+ private getTimeControls () {
+ if (this.options.isLive) {
+ return {
+ peerTubeLiveDisplay: {}
+ }
+ }
+
+ return {
+ currentTimeDisplay: {},
+ timeDivider: {},
+ durationDisplay: {}
+ }
+ }
+
private getProgressControl () {
+ if (this.options.isLive) return {}
+
const loadProgressBar = this.mode === 'webtorrent'
? 'peerTubeLoadProgressBar'
: 'loadProgressBar'
}
.vjs-live-control {
- line-height: $control-bar-height;
- min-width: 4em;
+ padding: 5px 7px;
+ border-radius: 3px;
+ height: fit-content;
+ margin: auto 10px;
+ font-weight: bold;
+ max-width: fit-content;
+ opacity: 1 !important;
+ line-height: normal;
+ position: relative;
+ top: -1px;
+
+ &.synced-with-live-edge {
+ background: #d7281c;
+ }
+
+ &:not(.synced-with-live-edge) {
+ cursor: pointer;
+ background: #80807f;
+ }
}
.vjs-peertube {
resolved "https://registry.yarnpkg.com/he/-/he-1.2.0.tgz#84ae65fa7eafb165fddb61566ae14baf05664f0f"
integrity sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==
-hls.js@1.2.7:
- version "1.2.7"
- resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.2.7.tgz#f421e258b10aa797cffb5ab2c3786675ead617f5"
- integrity sha512-mD4Po7Q5TPNIYX6G8sDD+RS/xfrWjMjrtp+xPw3Thw8Tq557Vn0wdXIX/Zii28F9ncUMMQPZsGkoCWFna9CZCw==
+hls.js@1.2.9:
+ version "1.2.9"
+ resolved "https://registry.yarnpkg.com/hls.js/-/hls.js-1.2.9.tgz#2f25e42ec4c2ea8c88ab23c0f854f39062d45ac9"
+ integrity sha512-SPjm8ix0xe6cYzwDvdVGh2QvQPDkCYrGWpZu6bRaKNNVyEGWM9uF0pooh/Lqj/g8QBQgPFEx1vHzW8SyMY9rqg==
hosted-git-info@^2.1.4:
version "2.8.9"
'Volume': 'Volume',
'Codecs': 'Codecs',
'Color': 'Color',
+ 'Go back to the live': 'Go back to the live',
'Connection Speed': 'Connection Speed',
'Network Activity': 'Network Activity',
'Total Transfered': 'Total Transfered',