Set last subtitle or subtitle in URL
authorChocobozzz <me@florianbigard.com>
Mon, 17 Dec 2018 13:14:54 +0000 (14:14 +0100)
committerChocobozzz <me@florianbigard.com>
Mon, 17 Dec 2018 13:15:30 +0000 (14:15 +0100)
client/src/assets/player/peertube-player-local-storage.ts
client/src/assets/player/peertube-player.ts
client/src/assets/player/peertube-videojs-plugin.ts
client/src/assets/player/peertube-videojs-typings.ts
client/src/assets/player/utils.ts
client/src/standalone/videos/embed.ts

index 7e381357041a345e1e294ab3159ddb60dd7e598c..059fca3083866b19f1b7ed9095e6b2aaca3d9d26 100644 (file)
@@ -60,6 +60,14 @@ function getAverageBandwidthInStore () {
   return undefined
 }
 
+function saveLastSubtitle (language: string) {
+  return setLocalStorage('last-subtitle', language)
+}
+
+function getStoredLastSubtitle () {
+  return getLocalStorage('last-subtitle')
+}
+
 // ---------------------------------------------------------------------------
 
 export {
@@ -71,7 +79,9 @@ export {
   saveMuteInStore,
   saveTheaterInStore,
   saveAverageBandwidth,
-  getAverageBandwidthInStore
+  getAverageBandwidthInStore,
+  saveLastSubtitle,
+  getStoredLastSubtitle
 }
 
 // ---------------------------------------------------------------------------
index aaa1170b6287d9c3df1abac333df74c042529d70..e0e0638387f3a90ac0011250e071254c4b5057ba 100644 (file)
@@ -26,23 +26,24 @@ videojsUntyped.getComponent('CaptionsButton').prototype.controlText_ = 'Subtitle
 videojsUntyped.getComponent('CaptionsButton').prototype.label_ = ' '
 
 function getVideojsOptions (options: {
-  autoplay: boolean,
-  playerElement: HTMLVideoElement,
-  videoViewUrl: string,
-  videoDuration: number,
-  videoFiles: VideoFile[],
-  enableHotkeys: boolean,
-  inactivityTimeout: number,
-  peertubeLink: boolean,
-  poster: string,
+  autoplay: boolean
+  playerElement: HTMLVideoElement
+  videoViewUrl: string
+  videoDuration: number
+  videoFiles: VideoFile[]
+  enableHotkeys: boolean
+  inactivityTimeout: number
+  peertubeLink: boolean
+  poster: string
   startTime: number | string
-  theaterMode: boolean,
-  videoCaptions: VideoJSCaption[],
+  theaterMode: boolean
+  videoCaptions: VideoJSCaption[]
 
-  language?: string,
-  controls?: boolean,
-  muted?: boolean,
+  language?: string
+  controls?: boolean
+  muted?: boolean
   loop?: boolean
+  subtitle?: string
 
   userWatching?: UserWatching
 }) {
@@ -50,8 +51,10 @@ function getVideojsOptions (options: {
     // We don't use text track settings for now
     textTrackSettings: false,
     controls: options.controls !== undefined ? options.controls : true,
-    muted: options.controls !== undefined ? options.muted : false,
     loop: options.loop !== undefined ? options.loop : false,
+
+    muted: options.muted !== undefined ? options.muted : undefined, // Undefined so the player knows it has to check the local storage
+
     poster: options.poster,
     autoplay: false,
     inactivityTimeout: options.inactivityTimeout,
@@ -65,7 +68,8 @@ function getVideojsOptions (options: {
         videoViewUrl: options.videoViewUrl,
         videoDuration: options.videoDuration,
         startTime: options.startTime,
-        userWatching: options.userWatching
+        userWatching: options.userWatching,
+        subtitle: options.subtitle
       }
     },
     controlBar: {
index 4fd5a9be22d5fa04a4e98e814849cb7e0468029c..4a280b7efed111f6153011941697209e31705b09 100644 (file)
@@ -11,10 +11,12 @@ import { isMobile, timeToInt, videoFileMaxByResolution, videoFileMinByResolution
 import { PeertubeChunkStore } from './peertube-chunk-store'
 import {
   getAverageBandwidthInStore,
+  getStoredLastSubtitle,
   getStoredMute,
   getStoredVolume,
   getStoredWebTorrentEnabled,
   saveAverageBandwidth,
+  saveLastSubtitle,
   saveMuteInStore,
   saveVolumeInStore
 } from './peertube-player-local-storage'
@@ -67,10 +69,11 @@ class PeerTubePlugin extends Plugin {
   private currentVideoFile: VideoFile
   private torrent: WebTorrent.Torrent
   private videoCaptions: VideoJSCaption[]
+  private defaultSubtitle: string
 
   private renderer: any
   private fakeRenderer: any
-  private destoyingFakeRenderer = false
+  private destroyingFakeRenderer = false
 
   private autoResolution = true
   private forbidAutoResolution = false
@@ -106,11 +109,34 @@ class PeerTubePlugin extends Plugin {
     if (this.autoplay === true) this.player.addClass('vjs-has-autoplay')
 
     this.player.ready(() => {
+      const playerOptions = this.player.options_
+
       const volume = getStoredVolume()
       if (volume !== undefined) this.player.volume(volume)
-      const muted = getStoredMute()
+
+      const muted = playerOptions.muted !== undefined ? playerOptions.muted : getStoredMute()
       if (muted !== undefined) this.player.muted(muted)
 
+      this.defaultSubtitle = options.subtitle || getStoredLastSubtitle()
+
+      this.player.on('volumechange', () => {
+        saveVolumeInStore(this.player.volume())
+        saveMuteInStore(this.player.muted())
+      })
+
+      this.player.textTracks().on('change', () => {
+        const showing = this.player.textTracks().tracks_.find((t: { kind: string, mode: string }) => {
+          return t.kind === 'captions' && t.mode === 'showing'
+        })
+
+        if (!showing) {
+          saveLastSubtitle('off')
+          return
+        }
+
+        saveLastSubtitle(showing.language)
+      })
+
       this.player.duration(options.videoDuration)
 
       this.initializePlayer()
@@ -124,11 +150,6 @@ class PeerTubePlugin extends Plugin {
         this.runAutoQualitySchedulerTimer = setTimeout(() => this.runAutoQualityScheduler(), this.CONSTANTS.AUTO_QUALITY_SCHEDULER)
       })
     })
-
-    this.player.on('volumechange', () => {
-      saveVolumeInStore(this.player.volume())
-      saveMuteInStore(this.player.muted())
-    })
   }
 
   dispose () {
@@ -657,14 +678,14 @@ class PeerTubePlugin extends Plugin {
   }
 
   private renderFileInFakeElement (file: WebTorrent.TorrentFile, delay: number) {
-    this.destoyingFakeRenderer = false
+    this.destroyingFakeRenderer = false
 
     const fakeVideoElem = document.createElement('video')
     renderVideo(file, fakeVideoElem, { autoplay: false, controls: false }, (err, renderer) => {
       this.fakeRenderer = renderer
 
       // The renderer returns an error when we destroy it, so skip them
-      if (this.destoyingFakeRenderer === false && err) {
+      if (this.destroyingFakeRenderer === false && err) {
         console.error('Cannot render new torrent in fake video element.', err)
       }
 
@@ -675,7 +696,7 @@ class PeerTubePlugin extends Plugin {
 
   private destroyFakeRenderer () {
     if (this.fakeRenderer) {
-      this.destoyingFakeRenderer = true
+      this.destroyingFakeRenderer = true
 
       if (this.fakeRenderer.destroy) {
         try {
@@ -695,7 +716,8 @@ class PeerTubePlugin extends Plugin {
         label: caption.label,
         language: caption.language,
         id: caption.language,
-        src: caption.src
+        src: caption.src,
+        default: this.defaultSubtitle === caption.language
       }, false)
     }
   }
index d127230fa73e850e3624a175dd4708606605940d..634c7fdc9df0e38484c31cebe5ed2b0b1b721c49 100644 (file)
@@ -39,6 +39,7 @@ type PeertubePluginOptions = {
   autoplay: boolean,
   videoCaptions: VideoJSCaption[]
 
+  subtitle?: string
   userWatching?: UserWatching
 }
 
index c872874820b2a316bd677f290655daf1031b3183..8b9f34b994033f628b41245287a22836ca648b35 100644 (file)
@@ -39,6 +39,7 @@ function buildVideoLink (time?: number, url?: string) {
 }
 
 function timeToInt (time: number | string) {
+  if (!time) return 0
   if (typeof time === 'number') return time
 
   const reg = /^((\d+)h)?((\d+)m)?((\d+)s?)?$/
index 7daa03f23b631058ba2ea0aab641c17c4b390b89..3a09f285e81508c9062e89864abde7451232cdad 100644 (file)
@@ -157,10 +157,11 @@ class PeerTubeEmbed {
   player: any
   playerOptions: any
   api: PeerTubeEmbedApi = null
-  autoplay = false
-  controls = true
-  muted = false
-  loop = false
+  autoplay: boolean
+  controls: boolean
+  muted: boolean
+  loop: boolean
+  subtitle: string
   enableApi = false
   startTime: number | string = 0
   scope = 'peertube'
@@ -214,11 +215,11 @@ class PeerTubeEmbed {
     this.displayError(text)
   }
 
-  getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) {
+  getParamToggle (params: URLSearchParams, name: string, defaultValue?: boolean) {
     return params.has(name) ? (params.get(name) === '1' || params.get(name) === 'true') : defaultValue
   }
 
-  getParamString (params: URLSearchParams, name: string, defaultValue: string) {
+  getParamString (params: URLSearchParams, name: string, defaultValue?: string) {
     return params.has(name) ? params.get(name) : defaultValue
   }
 
@@ -241,15 +242,15 @@ class PeerTubeEmbed {
     try {
       let params = new URL(window.location.toString()).searchParams
 
-      this.autoplay = this.getParamToggle(params, 'autoplay', this.autoplay)
-      this.controls = this.getParamToggle(params, 'controls', this.controls)
-      this.muted = this.getParamToggle(params, 'muted', this.muted)
-      this.loop = this.getParamToggle(params, 'loop', this.loop)
+      this.autoplay = this.getParamToggle(params, 'autoplay')
+      this.controls = this.getParamToggle(params, 'controls')
+      this.muted = this.getParamToggle(params, 'muted')
+      this.loop = this.getParamToggle(params, 'loop')
       this.enableApi = this.getParamToggle(params, 'api', this.enableApi)
-      this.scope = this.getParamString(params, 'scope', this.scope)
 
-      const startTimeParamString = params.get('start')
-      if (startTimeParamString) this.startTime = startTimeParamString
+      this.scope = this.getParamString(params, 'scope', this.scope)
+      this.subtitle = this.getParamString(params, 'subtitle')
+      this.startTime = this.getParamString(params, 'start')
     } catch (err) {
       console.error('Cannot get params from URL.', err)
     }
@@ -291,6 +292,7 @@ class PeerTubeEmbed {
       muted: this.muted,
       loop: this.loop,
       startTime: this.startTime,
+      subtitle: this.subtitle,
 
       videoCaptions,
       inactivityTimeout: 1500,