Add caption button to player control bar

This commit is contained in:
Chocobozzz 2024-02-19 15:58:11 +01:00
parent 7b86b9b458
commit c97b8fd2ea
No known key found for this signature in database
GPG key ID: 583A612D890159BE
8 changed files with 124 additions and 4 deletions

View file

@ -55,6 +55,8 @@ function getAverageBandwidthInStore () {
return undefined
}
// ---------------------------------------------------------------------------
function saveLastSubtitle (language: string) {
return setLocalStorage('last-subtitle', language)
}
@ -63,6 +65,16 @@ function getStoredLastSubtitle () {
return getLocalStorage('last-subtitle')
}
function savePreferredSubtitle (language: string) {
return setLocalStorage('preferred-subtitle', language)
}
function getStoredPreferredSubtitle () {
return getLocalStorage('preferred-subtitle')
}
// ---------------------------------------------------------------------------
function saveVideoWatchHistory (videoUUID: string, duration: number) {
return setLocalStorage(`video-watch-history`, JSON.stringify({
...getStoredVideoWatchHistory(),
@ -128,7 +140,9 @@ export {
getStoredLastSubtitle,
saveVideoWatchHistory,
getStoredVideoWatchHistory,
cleanupVideoWatch
cleanupVideoWatch,
savePreferredSubtitle,
getStoredPreferredSubtitle
}
// ---------------------------------------------------------------------------

View file

@ -6,6 +6,7 @@ import './shared/stats/stats-plugin'
import './shared/bezels/bezels-plugin'
import './shared/peertube/peertube-plugin'
import './shared/resolutions/peertube-resolutions-plugin'
import './shared/control-bar/caption-toggle-button'
import './shared/control-bar/storyboard-plugin'
import './shared/control-bar/chapters-plugin'
import './shared/control-bar/time-tooltip'

View file

@ -0,0 +1,59 @@
import videojs from 'video.js'
import { TheaterButtonOptions } from '../../types'
import { getStoredPreferredSubtitle } from '../../peertube-player-local-storage'
const Button = videojs.getComponent('Button')
class CaptionToggleButton extends Button {
constructor (player: videojs.Player, options: TheaterButtonOptions & videojs.ComponentOptions) {
super(player, options)
player.on('texttrackchange', () => this.update())
}
buildCSSClass () {
// Inherits vjs-captions-button for the icon
return `vjs-caption-toggle-control vjs-captions-button ${super.buildCSSClass()}`
}
handleClick (event: any) {
super.handleClick(event)
const toEnable = this.getShowing()
? undefined
: this.getCaptionToEnable()?.id
for (const track of this.player_.textTracks().tracks_) {
if (toEnable && track.id === toEnable) track.mode = 'showing'
else track.mode = 'disabled'
}
}
private update () {
if (this.getShowing()) {
this.controlText('Disable subtitles')
this.addClass('enabled')
return
}
this.controlText(this.player_.localize('Enable {1} subtitle', [ this.getCaptionToEnable()?.label ]))
this.removeClass('enabled')
}
private getShowing () {
return this.listCaptions().find(t => t.mode === 'showing')
}
private getCaptionToEnable () {
const captionToEnable = getStoredPreferredSubtitle() || this.listCaptions()[0]?.id
const captions = this.listCaptions()
return captions.find(t => t.id === captionToEnable) || captions[0]
}
private listCaptions () {
return this.player_.textTracks().tracks_.filter(t => t.kind === 'captions')
}
}
videojs.registerComponent('CaptionToggleButton', CaptionToggleButton)

View file

@ -1,3 +1,4 @@
export * from './caption-toggle-button'
export * from './chapters-plugin'
export * from './next-previous-video-button'
export * from './p2p-info-button'

View file

@ -10,6 +10,7 @@ import {
getStoredVolume,
saveLastSubtitle,
saveMuteInStore,
savePreferredSubtitle,
saveVideoWatchHistory,
saveVolumeInStore
} from '../../peertube-player-local-storage'
@ -113,6 +114,7 @@ class PeerTubePlugin extends Plugin {
this.currentSubtitle = showing.language
saveLastSubtitle(showing.language)
savePreferredSubtitle(showing.language)
})
this.player.on('video-change', () => {
@ -382,6 +384,8 @@ class PeerTubePlugin extends Plugin {
this.player.tech(true).clearTracks('text')
this.player.removeClass('vjs-has-captions')
for (const caption of this.options.videoCaptions()) {
this.player.addRemoteTextTrack({
kind: 'captions',
@ -391,6 +395,8 @@ class PeerTubePlugin extends Plugin {
src: caption.src,
default: this.currentSubtitle === caption.language
}, true)
this.player.addClass('vjs-has-captions')
}
this.player.trigger('captions-changed')

View file

@ -34,9 +34,12 @@ export class ControlBarOptionsBuilder {
...this.getProgressControl(),
p2PInfoButton: {},
muteToggle: {},
volumeControl: {},
captionToggleButton: {},
...this.getSettingsButton(),
...this.getPeerTubeLinkButton(),

View file

@ -40,6 +40,7 @@
.vjs-fullscreen-control,
.vjs-peertube-link,
.vjs-theater-control,
.vjs-caption-toggle-control,
.vjs-settings {
color: pvar(--embedForegroundColor) !important;
@ -297,7 +298,7 @@
.vjs-volume-control {
@include margin(0, 5px, 0, 5px);
width: $control-bar-icon-size;
width: 28px;
display: flex;
align-items: center;
}
@ -369,7 +370,7 @@
@include disable-outline;
cursor: pointer;
width: $control-bar-button-width;
width: $control-bar-button-width - 5px;
.vjs-icon-placeholder {
display: inline-block;
@ -418,6 +419,31 @@
}
}
.vjs-caption-toggle-control {
// Redefined if the player parent has captions class
display: none;
width: $control-bar-button-width - 4px;
&,
&:hover {
opacity: 0.5;
}
&.enabled,
&.enabled:hover {
opacity: $primary-foreground-opacity;
}
&:focus {
text-shadow: none;
}
> .vjs-icon-placeholder::before {
font-size: 2.3em;
line-height: 1.3;
}
}
.vjs-fullscreen-control {
@include disable-outline;
@ -456,6 +482,10 @@
display: none;
}
.vjs-mute-control {
@include margin(0, 5px, 0, 5px);
}
.vjs-peertube {
padding: 0 !important;
@ -519,3 +549,7 @@
height: 100%;
top: 0;
}
.vjs-peertube-skin.vjs-has-captions .vjs-caption-toggle-control {
display: block !important;
}

View file

@ -76,7 +76,9 @@ const playerKeys = {
'Cancel': 'Cancel',
'Up Next': 'Up Next',
'Autoplay is suspended': 'Autoplay is suspended',
'{1} (from edge: {2})': '{1} (from edge: {2})'
'{1} (from edge: {2})': '{1} (from edge: {2})',
'Disable subtitles': 'Disable subtitles',
'Enable {1} subtitle': 'Enable {1} subtitle'
}
Object.assign(playerKeys, videojs)