diff options
-rw-r--r-- | client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts | 4 | ||||
-rw-r--r-- | client/src/assets/player/webtorrent/webtorrent-plugin.ts | 4 | ||||
-rw-r--r-- | client/src/standalone/player/definitions.ts | 8 | ||||
-rw-r--r-- | client/src/standalone/player/player.ts | 5 | ||||
-rw-r--r-- | client/src/standalone/videos/embed-api.ts | 76 | ||||
-rw-r--r-- | client/src/standalone/videos/embed.ts | 1 | ||||
-rw-r--r-- | client/src/standalone/videos/test-embed.html | 7 | ||||
-rw-r--r-- | client/src/standalone/videos/test-embed.ts | 9 |
8 files changed, 96 insertions, 18 deletions
diff --git a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts index c44c184d5..c3f863f72 100644 --- a/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts +++ b/client/src/assets/player/p2p-media-loader/p2p-media-loader-plugin.ts | |||
@@ -77,6 +77,10 @@ class P2pMediaLoaderPlugin extends Plugin { | |||
77 | clearInterval(this.networkInfoInterval) | 77 | clearInterval(this.networkInfoInterval) |
78 | } | 78 | } |
79 | 79 | ||
80 | getHLSJS () { | ||
81 | return this.hlsjs | ||
82 | } | ||
83 | |||
80 | private initialize () { | 84 | private initialize () { |
81 | initHlsJsPlayer(this.hlsjs) | 85 | initHlsJsPlayer(this.hlsjs) |
82 | 86 | ||
diff --git a/client/src/assets/player/webtorrent/webtorrent-plugin.ts b/client/src/assets/player/webtorrent/webtorrent-plugin.ts index 5101b5162..35cf85c99 100644 --- a/client/src/assets/player/webtorrent/webtorrent-plugin.ts +++ b/client/src/assets/player/webtorrent/webtorrent-plugin.ts | |||
@@ -229,6 +229,10 @@ class WebTorrentPlugin extends Plugin { | |||
229 | this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() }) | 229 | this.trigger('resolutionChange', { auto: this.autoResolution, resolutionId: this.getCurrentResolutionId() }) |
230 | } | 230 | } |
231 | 231 | ||
232 | isAutoResolutionPossible () { | ||
233 | return this.autoResolutionPossible | ||
234 | } | ||
235 | |||
232 | getTorrent () { | 236 | getTorrent () { |
233 | return this.torrent | 237 | return this.torrent |
234 | } | 238 | } |
diff --git a/client/src/standalone/player/definitions.ts b/client/src/standalone/player/definitions.ts index afd10541b..9fe903260 100644 --- a/client/src/standalone/player/definitions.ts +++ b/client/src/standalone/player/definitions.ts | |||
@@ -4,11 +4,15 @@ export type PlayerEventType = | |||
4 | 'pause' | 'play' | | 4 | 'pause' | 'play' | |
5 | 'playbackStatusUpdate' | | 5 | 'playbackStatusUpdate' | |
6 | 'playbackStatusChange' | | 6 | 'playbackStatusChange' | |
7 | 'resolutionUpdate' | 7 | 'resolutionUpdate' | |
8 | 'volumeChange' | ||
8 | 9 | ||
9 | export interface PeerTubeResolution { | 10 | export interface PeerTubeResolution { |
10 | id: any | 11 | id: any |
11 | label: string | 12 | label: string |
12 | src: string | ||
13 | active: boolean | 13 | active: boolean |
14 | height: number | ||
15 | |||
16 | src?: string | ||
17 | width?: number | ||
14 | } | 18 | } |
diff --git a/client/src/standalone/player/player.ts b/client/src/standalone/player/player.ts index 91a5e73f3..f33539134 100644 --- a/client/src/standalone/player/player.ts +++ b/client/src/standalone/player/player.ts | |||
@@ -7,7 +7,8 @@ const PASSTHROUGH_EVENTS = [ | |||
7 | 'play', | 7 | 'play', |
8 | 'playbackStatusUpdate', | 8 | 'playbackStatusUpdate', |
9 | 'playbackStatusChange', | 9 | 'playbackStatusChange', |
10 | 'resolutionUpdate' | 10 | 'resolutionUpdate', |
11 | 'volumeChange' | ||
11 | ] | 12 | ] |
12 | 13 | ||
13 | /** | 14 | /** |
@@ -100,7 +101,7 @@ export class PeerTubePlayer { | |||
100 | * @param value A number from 0 to 1 | 101 | * @param value A number from 0 to 1 |
101 | */ | 102 | */ |
102 | async getVolume (): Promise<number> { | 103 | async getVolume (): Promise<number> { |
103 | return this.sendMessage<void, number>('setVolume') | 104 | return this.sendMessage<void, number>('getVolume') |
104 | } | 105 | } |
105 | 106 | ||
106 | /** | 107 | /** |
diff --git a/client/src/standalone/videos/embed-api.ts b/client/src/standalone/videos/embed-api.ts index 259113215..61e5d0b9a 100644 --- a/client/src/standalone/videos/embed-api.ts +++ b/client/src/standalone/videos/embed-api.ts | |||
@@ -11,7 +11,7 @@ import { PeerTubeEmbed } from './embed' | |||
11 | export class PeerTubeEmbedApi { | 11 | export class PeerTubeEmbedApi { |
12 | private channel: Channel.MessagingChannel | 12 | private channel: Channel.MessagingChannel |
13 | private isReady = false | 13 | private isReady = false |
14 | private resolutions: PeerTubeResolution[] = null | 14 | private resolutions: PeerTubeResolution[] = [] |
15 | 15 | ||
16 | constructor (private embed: PeerTubeEmbed) { | 16 | constructor (private embed: PeerTubeEmbed) { |
17 | } | 17 | } |
@@ -35,28 +35,40 @@ export class PeerTubeEmbedApi { | |||
35 | channel.bind('play', (txn, params) => this.embed.player.play()) | 35 | channel.bind('play', (txn, params) => this.embed.player.play()) |
36 | channel.bind('pause', (txn, params) => this.embed.player.pause()) | 36 | channel.bind('pause', (txn, params) => this.embed.player.pause()) |
37 | channel.bind('seek', (txn, time) => this.embed.player.currentTime(time)) | 37 | channel.bind('seek', (txn, time) => this.embed.player.currentTime(time)) |
38 | |||
38 | channel.bind('setVolume', (txn, value) => this.embed.player.volume(value)) | 39 | channel.bind('setVolume', (txn, value) => this.embed.player.volume(value)) |
39 | channel.bind('getVolume', (txn, value) => this.embed.player.volume()) | 40 | channel.bind('getVolume', (txn, value) => this.embed.player.volume()) |
41 | |||
40 | channel.bind('isReady', (txn, params) => this.isReady) | 42 | channel.bind('isReady', (txn, params) => this.isReady) |
43 | |||
41 | channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId)) | 44 | channel.bind('setResolution', (txn, resolutionId) => this.setResolution(resolutionId)) |
42 | channel.bind('getResolutions', (txn, params) => this.resolutions) | 45 | channel.bind('getResolutions', (txn, params) => this.resolutions) |
46 | |||
43 | channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate)) | 47 | channel.bind('setPlaybackRate', (txn, playbackRate) => this.embed.player.playbackRate(playbackRate)) |
44 | channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate()) | 48 | channel.bind('getPlaybackRate', (txn, params) => this.embed.player.playbackRate()) |
45 | channel.bind('getPlaybackRates', (txn, params) => this.embed.playerOptions.playbackRates) | 49 | channel.bind('getPlaybackRates', (txn, params) => this.embed.player.options_.playbackRates) |
46 | this.channel = channel | 50 | this.channel = channel |
47 | } | 51 | } |
48 | 52 | ||
49 | private setResolution (resolutionId: number) { | 53 | private setResolution (resolutionId: number) { |
50 | if (resolutionId === -1 && this.embed.player.webtorrent().isAutoResolutionForbidden()) return | 54 | console.log('set resolution %d', resolutionId) |
55 | |||
56 | if (this.isWebtorrent()) { | ||
57 | if (resolutionId === -1 && this.embed.player.webtorrent().isAutoResolutionPossible() === false) return | ||
58 | |||
59 | // Auto resolution | ||
60 | if (resolutionId === -1) { | ||
61 | this.embed.player.webtorrent().enableAutoResolution() | ||
62 | return | ||
63 | } | ||
64 | |||
65 | this.embed.player.webtorrent().disableAutoResolution() | ||
66 | this.embed.player.webtorrent().updateResolution(resolutionId) | ||
51 | 67 | ||
52 | // Auto resolution | ||
53 | if (resolutionId === -1) { | ||
54 | this.embed.player.webtorrent().enableAutoResolution() | ||
55 | return | 68 | return |
56 | } | 69 | } |
57 | 70 | ||
58 | this.embed.player.webtorrent().disableAutoResolution() | 71 | this.embed.player.p2pMediaLoader().getHLSJS().nextLevel = resolutionId |
59 | this.embed.player.webtorrent().updateResolution(resolutionId) | ||
60 | } | 72 | } |
61 | 73 | ||
62 | /** | 74 | /** |
@@ -96,14 +108,24 @@ export class PeerTubeEmbedApi { | |||
96 | 108 | ||
97 | // PeerTube specific capabilities | 109 | // PeerTube specific capabilities |
98 | 110 | ||
99 | if (this.embed.player.webtorrent) { | 111 | if (this.isWebtorrent()) { |
100 | this.embed.player.webtorrent().on('autoResolutionUpdate', () => this.loadWebTorrentResolutions()) | 112 | this.embed.player.webtorrent().on('autoResolutionUpdate', () => this.loadWebTorrentResolutions()) |
101 | this.embed.player.webtorrent().on('videoFileUpdate', () => this.loadWebTorrentResolutions()) | 113 | this.embed.player.webtorrent().on('videoFileUpdate', () => this.loadWebTorrentResolutions()) |
114 | } else { | ||
115 | this.embed.player.p2pMediaLoader().on('resolutionChange', () => this.loadP2PMediaLoaderResolutions()) | ||
102 | } | 116 | } |
117 | |||
118 | this.embed.player.on('volumechange', () => { | ||
119 | this.channel.notify({ | ||
120 | method: 'volumeChange', | ||
121 | params: this.embed.player.volume() | ||
122 | }) | ||
123 | }) | ||
103 | } | 124 | } |
104 | 125 | ||
105 | private loadWebTorrentResolutions () { | 126 | private loadWebTorrentResolutions () { |
106 | const resolutions = [] | 127 | this.resolutions = [] |
128 | |||
107 | const currentResolutionId = this.embed.player.webtorrent().getCurrentResolutionId() | 129 | const currentResolutionId = this.embed.player.webtorrent().getCurrentResolutionId() |
108 | 130 | ||
109 | for (const videoFile of this.embed.player.webtorrent().videoFiles) { | 131 | for (const videoFile of this.embed.player.webtorrent().videoFiles) { |
@@ -112,18 +134,46 @@ export class PeerTubeEmbedApi { | |||
112 | label += videoFile.fps | 134 | label += videoFile.fps |
113 | } | 135 | } |
114 | 136 | ||
115 | resolutions.push({ | 137 | this.resolutions.push({ |
116 | id: videoFile.resolution.id, | 138 | id: videoFile.resolution.id, |
117 | label, | 139 | label, |
118 | src: videoFile.magnetUri, | 140 | src: videoFile.magnetUri, |
119 | active: videoFile.resolution.id === currentResolutionId | 141 | active: videoFile.resolution.id === currentResolutionId, |
142 | height: videoFile.resolution.id | ||
120 | }) | 143 | }) |
121 | } | 144 | } |
122 | 145 | ||
123 | this.resolutions = resolutions | ||
124 | this.channel.notify({ | 146 | this.channel.notify({ |
125 | method: 'resolutionUpdate', | 147 | method: 'resolutionUpdate', |
126 | params: this.resolutions | 148 | params: this.resolutions |
127 | }) | 149 | }) |
128 | } | 150 | } |
151 | |||
152 | private loadP2PMediaLoaderResolutions () { | ||
153 | this.resolutions = [] | ||
154 | |||
155 | const qualityLevels = this.embed.player.qualityLevels() | ||
156 | const currentResolutionId = this.embed.player.qualityLevels().selectedIndex | ||
157 | |||
158 | for (let i = 0; i < qualityLevels.length; i++) { | ||
159 | const level = qualityLevels[i] | ||
160 | |||
161 | this.resolutions.push({ | ||
162 | id: level.id, | ||
163 | label: level.height + 'p', | ||
164 | active: level.id === currentResolutionId, | ||
165 | width: level.width, | ||
166 | height: level.height | ||
167 | }) | ||
168 | } | ||
169 | |||
170 | this.channel.notify({ | ||
171 | method: 'resolutionUpdate', | ||
172 | params: this.resolutions | ||
173 | }) | ||
174 | } | ||
175 | |||
176 | private isWebtorrent () { | ||
177 | return this.embed.player.webtorrent | ||
178 | } | ||
129 | } | 179 | } |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index f33dd8869..c91ae08b9 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -23,7 +23,6 @@ import { TranslationsManager } from '../../assets/player/translations-manager' | |||
23 | export class PeerTubeEmbed { | 23 | export class PeerTubeEmbed { |
24 | videoElement: HTMLVideoElement | 24 | videoElement: HTMLVideoElement |
25 | player: any | 25 | player: any |
26 | playerOptions: any | ||
27 | api: PeerTubeEmbedApi = null | 26 | api: PeerTubeEmbedApi = null |
28 | autoplay: boolean | 27 | autoplay: boolean |
29 | controls: boolean | 28 | controls: boolean |
diff --git a/client/src/standalone/videos/test-embed.html b/client/src/standalone/videos/test-embed.html index a60ba2899..20cdbdc5f 100644 --- a/client/src/standalone/videos/test-embed.html +++ b/client/src/standalone/videos/test-embed.html | |||
@@ -25,6 +25,8 @@ | |||
25 | <button onclick="player.play()">Play</button> | 25 | <button onclick="player.play()">Play</button> |
26 | <button onclick="player.pause()">Pause</button> | 26 | <button onclick="player.pause()">Pause</button> |
27 | <button onclick="player.seek(parseInt(prompt('Enter position to seek to (in seconds)')))">Seek</button> | 27 | <button onclick="player.seek(parseInt(prompt('Enter position to seek to (in seconds)')))">Seek</button> |
28 | <button onclick="player.setVolume(0)">Mute</button> | ||
29 | <button onclick="player.setVolume(1)">Unmute</button> | ||
28 | </div> | 30 | </div> |
29 | <br/> | 31 | <br/> |
30 | 32 | ||
@@ -39,6 +41,11 @@ | |||
39 | <legend>Rates:</legend> | 41 | <legend>Rates:</legend> |
40 | <div id="rate-list"></div> | 42 | <div id="rate-list"></div> |
41 | </fieldset> | 43 | </fieldset> |
44 | |||
45 | <fieldset> | ||
46 | <legend>Volume</legend> | ||
47 | <div id="volume"></div> | ||
48 | </fieldset> | ||
42 | </div> | 49 | </div> |
43 | 50 | ||
44 | </div> | 51 | </div> |
diff --git a/client/src/standalone/videos/test-embed.ts b/client/src/standalone/videos/test-embed.ts index 8e83d92a9..e5e6365dc 100644 --- a/client/src/standalone/videos/test-embed.ts +++ b/client/src/standalone/videos/test-embed.ts | |||
@@ -9,6 +9,7 @@ window.addEventListener('load', async () => { | |||
9 | 9 | ||
10 | const iframe = document.createElement('iframe') | 10 | const iframe = document.createElement('iframe') |
11 | iframe.src = `/videos/embed/${videoId}?autoplay=1&controls=0&api=1` | 11 | iframe.src = `/videos/embed/${videoId}?autoplay=1&controls=0&api=1` |
12 | |||
12 | const mainElement = document.querySelector('#host') | 13 | const mainElement = document.querySelector('#host') |
13 | mainElement.appendChild(iframe) | 14 | mainElement.appendChild(iframe) |
14 | 15 | ||
@@ -93,4 +94,12 @@ window.addEventListener('load', async () => { | |||
93 | resolutions => updateResolutions(resolutions)) | 94 | resolutions => updateResolutions(resolutions)) |
94 | player.addEventListener('resolutionUpdate', | 95 | player.addEventListener('resolutionUpdate', |
95 | resolutions => updateResolutions(resolutions)) | 96 | resolutions => updateResolutions(resolutions)) |
97 | |||
98 | const updateVolume = (volume: number) => { | ||
99 | const volumeEl = document.getElementById('volume') | ||
100 | volumeEl.innerText = (volume * 100) + '%' | ||
101 | } | ||
102 | |||
103 | player.getVolume().then(volume => updateVolume(volume)) | ||
104 | player.addEventListener('volumeChange', volume => updateVolume(volume)) | ||
96 | }) | 105 | }) |