diff options
Diffstat (limited to 'client')
-rw-r--r-- | client/src/assets/player/peertube-videojs-typings.ts | 2 | ||||
-rw-r--r-- | client/src/standalone/player/definitions.ts | 7 | ||||
-rw-r--r-- | client/src/standalone/player/player.ts | 17 | ||||
-rw-r--r-- | client/src/standalone/videos/embed-api.ts | 25 | ||||
-rw-r--r-- | client/src/standalone/videos/test-embed.html | 6 | ||||
-rw-r--r-- | client/src/standalone/videos/test-embed.ts | 32 |
6 files changed, 85 insertions, 4 deletions
diff --git a/client/src/assets/player/peertube-videojs-typings.ts b/client/src/assets/player/peertube-videojs-typings.ts index a4e4c580c..cb7d6f6b4 100644 --- a/client/src/assets/player/peertube-videojs-typings.ts +++ b/client/src/assets/player/peertube-videojs-typings.ts | |||
@@ -38,7 +38,7 @@ declare module 'video.js' { | |||
38 | 38 | ||
39 | textTracks (): TextTrackList & { | 39 | textTracks (): TextTrackList & { |
40 | on: Function | 40 | on: Function |
41 | tracks_: { kind: string, mode: string, language: string }[] | 41 | tracks_: (TextTrack & { id: string, label: string, src: string })[] |
42 | } | 42 | } |
43 | 43 | ||
44 | audioTracks (): AudioTrackList | 44 | audioTracks (): AudioTrackList |
diff --git a/client/src/standalone/player/definitions.ts b/client/src/standalone/player/definitions.ts index 9fe903260..cc5203ed5 100644 --- a/client/src/standalone/player/definitions.ts +++ b/client/src/standalone/player/definitions.ts | |||
@@ -16,3 +16,10 @@ export interface PeerTubeResolution { | |||
16 | src?: string | 16 | src?: string |
17 | width?: number | 17 | width?: number |
18 | } | 18 | } |
19 | |||
20 | export type PeerTubeTextTrack = { | ||
21 | id: string | ||
22 | label: string | ||
23 | src: string | ||
24 | mode: 'showing' | 'disabled' | ||
25 | } | ||
diff --git a/client/src/standalone/player/player.ts b/client/src/standalone/player/player.ts index 71c412950..119f5e035 100644 --- a/client/src/standalone/player/player.ts +++ b/client/src/standalone/player/player.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import * as Channel from 'jschannel' | 1 | import * as Channel from 'jschannel' |
2 | import { EventHandler, PeerTubeResolution, PeerTubeTextTrack, PlayerEventType } from './definitions' | ||
2 | import { EventRegistrar } from './events' | 3 | import { EventRegistrar } from './events' |
3 | import { EventHandler, PlayerEventType, PeerTubeResolution } from './definitions' | ||
4 | 4 | ||
5 | const PASSTHROUGH_EVENTS = [ | 5 | const PASSTHROUGH_EVENTS = [ |
6 | 'pause', | 6 | 'pause', |
@@ -105,6 +105,21 @@ export class PeerTubePlayer { | |||
105 | } | 105 | } |
106 | 106 | ||
107 | /** | 107 | /** |
108 | * Tell the embed to change the current caption | ||
109 | * @param value Caption id | ||
110 | */ | ||
111 | async setCaption (value: string) { | ||
112 | await this.sendMessage('setCaption', value) | ||
113 | } | ||
114 | |||
115 | /** | ||
116 | * Get video captions | ||
117 | */ | ||
118 | async getCaptions (): Promise<PeerTubeTextTrack[]> { | ||
119 | return this.sendMessage<void, PeerTubeTextTrack[]>('getCaptions') | ||
120 | } | ||
121 | |||
122 | /** | ||
108 | * Tell the embed to seek to a specific position (in seconds) | 123 | * Tell the embed to seek to a specific position (in seconds) |
109 | * @param seconds | 124 | * @param seconds |
110 | */ | 125 | */ |
diff --git a/client/src/standalone/videos/embed-api.ts b/client/src/standalone/videos/embed-api.ts index 194465d4a..a9263555d 100644 --- a/client/src/standalone/videos/embed-api.ts +++ b/client/src/standalone/videos/embed-api.ts | |||
@@ -1,7 +1,7 @@ | |||
1 | import './embed.scss' | 1 | import './embed.scss' |
2 | 2 | ||
3 | import * as Channel from 'jschannel' | 3 | import * as Channel from 'jschannel' |
4 | import { PeerTubeResolution } from '../player/definitions' | 4 | import { PeerTubeResolution, PeerTubeTextTrack } from '../player/definitions' |
5 | import { PeerTubeEmbed } from './embed' | 5 | import { PeerTubeEmbed } from './embed' |
6 | 6 | ||
7 | /** | 7 | /** |
@@ -44,6 +44,9 @@ export class PeerTubeEmbedApi { | |||
44 | channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId)) | 44 | channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId)) |
45 | channel.bind('getResolutions', (txn, params) => this.resolutions) | 45 | channel.bind('getResolutions', (txn, params) => this.resolutions) |
46 | 46 | ||
47 | channel.bind('getCaptions', (txn, params) => this.getCaptions()) | ||
48 | channel.bind('setCaption', (txn, id) => this.setCaption(id)), | ||
49 | |||
47 | channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate)) | 50 | channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate)) |
48 | channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate()) | 51 | channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate()) |
49 | channel.bind('getPlaybackRates', (txn, params) => this.embed.player.options_.playbackRates) | 52 | channel.bind('getPlaybackRates', (txn, params) => this.embed.player.options_.playbackRates) |
@@ -71,6 +74,26 @@ export class PeerTubeEmbedApi { | |||
71 | this.embed.player.p2pMediaLoader().getHLSJS().nextLevel = resolutionId | 74 | this.embed.player.p2pMediaLoader().getHLSJS().nextLevel = resolutionId |
72 | } | 75 | } |
73 | 76 | ||
77 | private getCaptions (): PeerTubeTextTrack[] { | ||
78 | return this.embed.player.textTracks().tracks_.map(t => { | ||
79 | return { | ||
80 | id: t.id, | ||
81 | src: t.src, | ||
82 | label: t.label, | ||
83 | mode: t.mode as any | ||
84 | } | ||
85 | }) | ||
86 | } | ||
87 | |||
88 | private setCaption (id: string) { | ||
89 | const tracks = this.embed.player.textTracks().tracks_ | ||
90 | |||
91 | for (const track of tracks) { | ||
92 | if (track.id === id) track.mode = 'showing' | ||
93 | else track.mode = 'disabled' | ||
94 | } | ||
95 | } | ||
96 | |||
74 | /** | 97 | /** |
75 | * Let the host know that we're ready to go! | 98 | * Let the host know that we're ready to go! |
76 | */ | 99 | */ |
diff --git a/client/src/standalone/videos/test-embed.html b/client/src/standalone/videos/test-embed.html index 20cdbdc5f..9e1d6fc61 100644 --- a/client/src/standalone/videos/test-embed.html +++ b/client/src/standalone/videos/test-embed.html | |||
@@ -38,6 +38,12 @@ | |||
38 | </fieldset> | 38 | </fieldset> |
39 | 39 | ||
40 | <fieldset> | 40 | <fieldset> |
41 | <legend>Captions:</legend> | ||
42 | <div id="caption-list"></div> | ||
43 | <br/> | ||
44 | </fieldset> | ||
45 | |||
46 | <fieldset> | ||
41 | <legend>Rates:</legend> | 47 | <legend>Rates:</legend> |
42 | <div id="rate-list"></div> | 48 | <div id="rate-list"></div> |
43 | </fieldset> | 49 | </fieldset> |
diff --git a/client/src/standalone/videos/test-embed.ts b/client/src/standalone/videos/test-embed.ts index a4b54782c..24cb62230 100644 --- a/client/src/standalone/videos/test-embed.ts +++ b/client/src/standalone/videos/test-embed.ts | |||
@@ -1,6 +1,6 @@ | |||
1 | import './test-embed.scss' | 1 | import './test-embed.scss' |
2 | import { PeerTubePlayer } from '../player/player' | 2 | import { PeerTubePlayer } from '../player/player' |
3 | import { PeerTubeResolution, PlayerEventType } from '../player/definitions' | 3 | import { PeerTubeResolution, PlayerEventType, PeerTubeTextTrack } from '../player/definitions' |
4 | 4 | ||
5 | window.addEventListener('load', async () => { | 5 | window.addEventListener('load', async () => { |
6 | const urlParts = window.location.href.split('/') | 6 | const urlParts = window.location.href.split('/') |
@@ -67,6 +67,36 @@ window.addEventListener('load', async () => { | |||
67 | updateRates() | 67 | updateRates() |
68 | }) | 68 | }) |
69 | 69 | ||
70 | const updateCaptions = async () => { | ||
71 | const captions = await player.getCaptions() | ||
72 | |||
73 | const captionEl = document.querySelector('#caption-list') | ||
74 | captionEl.innerHTML = '' | ||
75 | |||
76 | captions.forEach(c => { | ||
77 | console.log(c) | ||
78 | |||
79 | if (c.mode === 'showing') { | ||
80 | const itemEl = document.createElement('strong') | ||
81 | itemEl.innerText = `${c.label} (active)` | ||
82 | itemEl.style.display = 'block' | ||
83 | captionEl.appendChild(itemEl) | ||
84 | } else { | ||
85 | const itemEl = document.createElement('a') | ||
86 | itemEl.href = 'javascript:;' | ||
87 | itemEl.innerText = c.label | ||
88 | itemEl.addEventListener('click', () => { | ||
89 | player.setCaption(c.id) | ||
90 | updateCaptions() | ||
91 | }) | ||
92 | itemEl.style.display = 'block' | ||
93 | captionEl.appendChild(itemEl) | ||
94 | } | ||
95 | }) | ||
96 | } | ||
97 | |||
98 | updateCaptions() | ||
99 | |||
70 | const updateResolutions = ((resolutions: PeerTubeResolution[]) => { | 100 | const updateResolutions = ((resolutions: PeerTubeResolution[]) => { |
71 | const resolutionListEl = document.querySelector('#resolution-list') | 101 | const resolutionListEl = document.querySelector('#resolution-list') |
72 | resolutionListEl.innerHTML = '' | 102 | resolutionListEl.innerHTML = '' |