From 0e7c4b03c3908ad81427921c96b06c1efae4da54 Mon Sep 17 00:00:00 2001 From: Chocobozzz Date: Tue, 20 Dec 2022 16:28:15 +0100 Subject: Add back to live feature --- client/package.json | 2 +- .../src/assets/player/peertube-player-manager.ts | 1 + .../src/assets/player/shared/control-bar/index.ts | 1 + .../shared/control-bar/peertube-live-display.ts | 89 ++++++++++++++++++++++ .../manager-options/control-bar-options-builder.ts | 21 ++++- client/src/sass/player/control-bar.scss | 21 ++++- client/yarn.lock | 8 +- scripts/i18n/create-custom-files.ts | 1 + 8 files changed, 133 insertions(+), 11 deletions(-) create mode 100644 client/src/assets/player/shared/control-bar/peertube-live-display.ts diff --git a/client/package.json b/client/package.json index 4b86fb947..a026d61c1 100644 --- a/client/package.json +++ b/client/package.json @@ -96,7 +96,7 @@ "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", diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts index 56310c4e9..710c9dc87 100644 --- a/client/src/assets/player/peertube-player-manager.ts +++ b/client/src/assets/player/peertube-player-manager.ts @@ -11,6 +11,7 @@ import './shared/control-bar/p2p-info-button' 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' diff --git a/client/src/assets/player/shared/control-bar/index.ts b/client/src/assets/player/shared/control-bar/index.ts index db5b8938d..e71e90713 100644 --- a/client/src/assets/player/shared/control-bar/index.ts +++ b/client/src/assets/player/shared/control-bar/index.ts @@ -1,5 +1,6 @@ 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' diff --git a/client/src/assets/player/shared/control-bar/peertube-live-display.ts b/client/src/assets/player/shared/control-bar/peertube-live-display.ts new file mode 100644 index 000000000..8724ff294 --- /dev/null +++ b/client/src/assets/player/shared/control-bar/peertube-live-display.ts @@ -0,0 +1,89 @@ +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) diff --git a/client/src/assets/player/shared/manager-options/control-bar-options-builder.ts b/client/src/assets/player/shared/manager-options/control-bar-options-builder.ts index 27f366732..df1e8eabe 100644 --- a/client/src/assets/player/shared/manager-options/control-bar-options-builder.ts +++ b/client/src/assets/player/shared/manager-options/control-bar-options-builder.ts @@ -30,10 +30,7 @@ export class ControlBarOptionsBuilder { } Object.assign(children, { - currentTimeDisplay: {}, - timeDivider: {}, - durationDisplay: {}, - liveDisplay: {}, + ...this.getTimeControls(), flexibleWidthSpacer: {}, @@ -90,7 +87,23 @@ export class ControlBarOptionsBuilder { } } + 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' diff --git a/client/src/sass/player/control-bar.scss b/client/src/sass/player/control-bar.scss index 0082378e4..96b3adf66 100644 --- a/client/src/sass/player/control-bar.scss +++ b/client/src/sass/player/control-bar.scss @@ -153,8 +153,25 @@ } .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 { diff --git a/client/yarn.lock b/client/yarn.lock index eac68d35e..633f90fa8 100644 --- a/client/yarn.lock +++ b/client/yarn.lock @@ -6136,10 +6136,10 @@ he@1.2.0, he@^1.2.0: 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" diff --git a/scripts/i18n/create-custom-files.ts b/scripts/i18n/create-custom-files.ts index bcd7fe2a2..3b5045954 100755 --- a/scripts/i18n/create-custom-files.ts +++ b/scripts/i18n/create-custom-files.ts @@ -41,6 +41,7 @@ const playerKeys = { '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', -- cgit v1.2.3