Add ability to update embed captions
authorChocobozzz <me@florianbigard.com>
Wed, 6 May 2020 09:54:33 +0000 (11:54 +0200)
committerChocobozzz <me@florianbigard.com>
Wed, 6 May 2020 09:54:33 +0000 (11:54 +0200)
client/src/assets/player/peertube-videojs-typings.ts
client/src/standalone/player/definitions.ts
client/src/standalone/player/player.ts
client/src/standalone/videos/embed-api.ts
client/src/standalone/videos/test-embed.html
client/src/standalone/videos/test-embed.ts
support/doc/api/embeds.md

index a4e4c580c12c4eb5e7153b0846886ceefc3eb985..cb7d6f6b48a6425d04b02eb57fc6b36d3d35efb5 100644 (file)
@@ -38,7 +38,7 @@ declare module 'video.js' {
 
     textTracks (): TextTrackList & {
       on: Function
-      tracks_: { kind: string, mode: string, language: string }[]
+      tracks_: (TextTrack & { id: string, label: string, src: string })[]
     }
 
     audioTracks (): AudioTrackList
index 9fe9032607ebab3fb33793b92a366196d70596a6..cc5203ed534ce93c01197a3217b1f8c4c1c27b1a 100644 (file)
@@ -16,3 +16,10 @@ export interface PeerTubeResolution {
   src?: string
   width?: number
 }
+
+export type PeerTubeTextTrack = {
+  id: string
+  label: string
+  src: string
+  mode: 'showing' | 'disabled'
+}
index 71c41295076db65bdc1a8e36c1e97510deaa6007..119f5e035e55f5a46690d205c3f00885560b4645 100644 (file)
@@ -1,6 +1,6 @@
 import * as Channel from 'jschannel'
+import { EventHandler, PeerTubeResolution, PeerTubeTextTrack, PlayerEventType } from './definitions'
 import { EventRegistrar } from './events'
-import { EventHandler, PlayerEventType, PeerTubeResolution } from './definitions'
 
 const PASSTHROUGH_EVENTS = [
   'pause',
@@ -104,6 +104,21 @@ export class PeerTubePlayer {
     return this.sendMessage<void, number>('getVolume')
   }
 
+  /**
+   * Tell the embed to change the current caption
+   * @param value Caption id
+   */
+  async setCaption (value: string) {
+    await this.sendMessage('setCaption', value)
+  }
+
+  /**
+   * Get video captions
+   */
+  async getCaptions (): Promise<PeerTubeTextTrack[]> {
+    return this.sendMessage<void, PeerTubeTextTrack[]>('getCaptions')
+  }
+
   /**
    * Tell the embed to seek to a specific position (in seconds)
    * @param seconds
index 194465d4a4bcba934cb651f83f23b1290e63ebd7..a9263555d839e400b6e12292a3e000eff8eafff9 100644 (file)
@@ -1,7 +1,7 @@
 import './embed.scss'
 
 import * as Channel from 'jschannel'
-import { PeerTubeResolution } from '../player/definitions'
+import { PeerTubeResolution, PeerTubeTextTrack } from '../player/definitions'
 import { PeerTubeEmbed } from './embed'
 
 /**
@@ -44,6 +44,9 @@ export class PeerTubeEmbedApi {
     channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId))
     channel.bind('getResolutions', (txn, params) => this.resolutions)
 
+    channel.bind('getCaptions', (txn, params) => this.getCaptions())
+    channel.bind('setCaption', (txn, id) => this.setCaption(id)),
+
     channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate))
     channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate())
     channel.bind('getPlaybackRates', (txn, params) => this.embed.player.options_.playbackRates)
@@ -71,6 +74,26 @@ export class PeerTubeEmbedApi {
     this.embed.player.p2pMediaLoader().getHLSJS().nextLevel = resolutionId
   }
 
+  private getCaptions (): PeerTubeTextTrack[] {
+    return this.embed.player.textTracks().tracks_.map(t => {
+      return {
+        id: t.id,
+        src: t.src,
+        label: t.label,
+        mode: t.mode as any
+      }
+    })
+  }
+
+  private setCaption (id: string) {
+    const tracks = this.embed.player.textTracks().tracks_
+
+    for (const track of tracks) {
+      if (track.id === id) track.mode = 'showing'
+      else track.mode = 'disabled'
+    }
+  }
+
   /**
    * Let the host know that we're ready to go!
    */
index 20cdbdc5f1238917c24296de287f08e1fec18892..9e1d6fc612af0405a140295fafad9600cf7668e0 100644 (file)
           <br/>
         </fieldset>
 
+        <fieldset>
+          <legend>Captions:</legend>
+          <div id="caption-list"></div>
+          <br/>
+        </fieldset>
+
         <fieldset>
           <legend>Rates:</legend>
           <div id="rate-list"></div>
index a4b54782c7e8927ab078c4750ba0bf3f1eb742ad..24cb62230bcf1b6b35df0e7613aca8a12514f51e 100644 (file)
@@ -1,6 +1,6 @@
 import './test-embed.scss'
 import { PeerTubePlayer } from '../player/player'
-import { PeerTubeResolution, PlayerEventType } from '../player/definitions'
+import { PeerTubeResolution, PlayerEventType, PeerTubeTextTrack } from '../player/definitions'
 
 window.addEventListener('load', async () => {
   const urlParts = window.location.href.split('/')
@@ -67,6 +67,36 @@ window.addEventListener('load', async () => {
     updateRates()
   })
 
+  const updateCaptions = async () => {
+    const captions = await player.getCaptions()
+
+    const captionEl = document.querySelector('#caption-list')
+    captionEl.innerHTML = ''
+
+    captions.forEach(c => {
+      console.log(c)
+
+      if (c.mode === 'showing') {
+        const itemEl = document.createElement('strong')
+        itemEl.innerText = `${c.label} (active)`
+        itemEl.style.display = 'block'
+        captionEl.appendChild(itemEl)
+      } else {
+        const itemEl = document.createElement('a')
+        itemEl.href = 'javascript:;'
+        itemEl.innerText = c.label
+        itemEl.addEventListener('click', () => {
+          player.setCaption(c.id)
+          updateCaptions()
+        })
+        itemEl.style.display = 'block'
+        captionEl.appendChild(itemEl)
+      }
+    })
+  }
+
+  updateCaptions()
+
   const updateResolutions = ((resolutions: PeerTubeResolution[]) => {
     const resolutionListEl = document.querySelector('#resolution-list')
     resolutionListEl.innerHTML = ''
index 7085b4b0ad569e2592eafd143a433fb350ac7712..e3df35efcdd7a58b7595f9b5518dc67fbc29259a 100644 (file)
@@ -4,8 +4,8 @@ PeerTube lets you embed videos and programmatically control their playback. This
 
 ## Playground
 
-Any PeerTube embed URL (ie `https://my-instance.example.com/videos/embed/52a10666-3a18-4e73-93da-e8d3c12c305a`) can be viewed as an embedding playground which 
-allows you to test various aspects of PeerTube embeds. Simply replace `/embed` with `/test-embed` and visit the URL in a browser. 
+Any PeerTube embed URL (ie `https://my-instance.example.com/videos/embed/52a10666-3a18-4e73-93da-e8d3c12c305a`) can be viewed as an embedding playground which
+allows you to test various aspects of PeerTube embeds. Simply replace `/embed` with `/test-embed` and visit the URL in a browser.
 For instance, the playground URL for the above embed URL is `https://my-instance.example.com/videos/test-embed/52a10666-3a18-4e73-93da-e8d3c12c305a`.
 
 ## Quick Start
@@ -95,11 +95,11 @@ Get the available playback rates, where `1` represents normal speed, `0.5` is ha
 
 Get the current playback rate. See `getPlaybackRates()` for more information.
 
-## `setPlaybackRate(rate : number) : Promise<void>`
+## `setPlaybackRate(rate: number) : Promise<void>`
 
 Set the current playback rate. The passed rate should be a value as returned by `getPlaybackRates()`.
 
-## `setVolume(factor : number) : Promise<void>`
+## `setVolume(factor: number) : Promise<void>`
 
 Set the playback volume. Value should be between `0` and `1`.
 
@@ -107,13 +107,21 @@ Set the playback volume. Value should be between `0` and `1`.
 
 Get the playback volume. Returns a value between `0` and `1`.
 
+## `setCaption(id: string) : Promise<void>`
+
+Update current caption using the caption id.
+
+## `getCaptions(): Promise<{ id: string, label: string, src: string, mode: 'disabled' | 'showing' }>`
+
+Get video captions.
+
 # Events
 
 You can subscribe to events by using `addEventListener()`. See above for details.
 
 ## Event `playbackStatusUpdate`
 
-Fired every half second to provide the current status of playback. 
+Fired every half second to provide the current status of playback.
 The parameter of the callback will resemble:
 
 ```json