diff options
6 files changed, 63 insertions, 21 deletions
diff --git a/client/src/app/videos/+video-watch/video-watch.component.html b/client/src/app/videos/+video-watch/video-watch.component.html index f28134ece..21f8f5534 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.html +++ b/client/src/app/videos/+video-watch/video-watch.component.html | |||
@@ -1,6 +1,11 @@ | |||
1 | <div class="row"> | 1 | <div class="row"> |
2 | <!-- We need the video container for videojs so we just hide it --> | 2 | <!-- We need the video container for videojs so we just hide it --> |
3 | <div id="video-element-wrapper"> | 3 | <div id="video-element-wrapper"> |
4 | <div *ngIf="remoteServerDown" class="remote-server-down"> | ||
5 | Sorry, but this video is not available because the remote instance is not responding. | ||
6 | <br /> | ||
7 | Please try again later. | ||
8 | </div> | ||
4 | </div> | 9 | </div> |
5 | 10 | ||
6 | <div i18n class="alert alert-warning" *ngIf="isVideoToTranscode()"> | 11 | <div i18n class="alert alert-warning" *ngIf="isVideoToTranscode()"> |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.scss b/client/src/app/videos/+video-watch/video-watch.component.scss index 7c694f2e2..4ce17209f 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.scss +++ b/client/src/app/videos/+video-watch/video-watch.component.scss | |||
@@ -5,15 +5,37 @@ | |||
5 | background-color: #000; | 5 | background-color: #000; |
6 | display: flex; | 6 | display: flex; |
7 | justify-content: center; | 7 | justify-content: center; |
8 | height: 500px; | ||
8 | 9 | ||
9 | /deep/ .video-js { | 10 | @media screen and (max-width: 600px) { |
10 | width: 888px; | 11 | width: 100vw; |
11 | height: 500px; | 12 | height: calc(100vw / 1.7); // 16/9 |
13 | } | ||
14 | |||
15 | .remote-server-down { | ||
16 | color: #fff; | ||
17 | display: flex; | ||
18 | flex-direction: column; | ||
19 | align-items: center; | ||
20 | text-align: center; | ||
21 | justify-content: center; | ||
22 | background-color: #141313; | ||
23 | width: 100%; | ||
24 | height: 100%; | ||
25 | font-size: 24px; | ||
26 | |||
27 | @media screen and (max-width: 1000px) { | ||
28 | font-size: 20px; | ||
29 | } | ||
12 | 30 | ||
13 | @media screen and (max-width: 600px) { | 31 | @media screen and (max-width: 600px) { |
14 | width: 100vw; | 32 | font-size: 16px; |
15 | height: calc(100vw / 1.7); // 16/9 | ||
16 | } | 33 | } |
34 | } | ||
35 | |||
36 | /deep/ .video-js { | ||
37 | width: 888px; | ||
38 | height: 100%; | ||
17 | 39 | ||
18 | // VideoJS create an inner video player | 40 | // VideoJS create an inner video player |
19 | video { | 41 | video { |
diff --git a/client/src/app/videos/+video-watch/video-watch.component.ts b/client/src/app/videos/+video-watch/video-watch.component.ts index 601c6a38d..43afbae1a 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts | |||
@@ -57,6 +57,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
57 | videoHTMLDescription = '' | 57 | videoHTMLDescription = '' |
58 | likesBarTooltipText = '' | 58 | likesBarTooltipText = '' |
59 | hasAlreadyAcceptedPrivacyConcern = false | 59 | hasAlreadyAcceptedPrivacyConcern = false |
60 | remoteServerDown = false | ||
60 | 61 | ||
61 | private videojsLocaleLoaded = false | 62 | private videojsLocaleLoaded = false |
62 | private otherVideos: Video[] = [] | 63 | private otherVideos: Video[] = [] |
@@ -312,15 +313,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
312 | const errorMessage: string = typeof err === 'string' ? err : err.message | 313 | const errorMessage: string = typeof err === 'string' ? err : err.message |
313 | if (!errorMessage) return | 314 | if (!errorMessage) return |
314 | 315 | ||
315 | let message = '' | 316 | // Display a message in the video player instead of a notification |
316 | |||
317 | if (errorMessage.indexOf('http error') !== -1) { | 317 | if (errorMessage.indexOf('http error') !== -1) { |
318 | message = this.i18n('Cannot fetch video from server, maybe down.') | 318 | this.flushPlayer() |
319 | } else { | 319 | this.remoteServerDown = true |
320 | message = errorMessage | 320 | return |
321 | } | 321 | } |
322 | 322 | ||
323 | this.notificationsService.error(this.i18n('Error'), message) | 323 | this.notificationsService.error(this.i18n('Error'), errorMessage) |
324 | } | 324 | } |
325 | 325 | ||
326 | private checkUserRating () { | 326 | private checkUserRating () { |
@@ -345,6 +345,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
345 | // Re init attributes | 345 | // Re init attributes |
346 | this.descriptionLoading = false | 346 | this.descriptionLoading = false |
347 | this.completeDescriptionShown = false | 347 | this.completeDescriptionShown = false |
348 | this.remoteServerDown = false | ||
348 | 349 | ||
349 | this.updateOtherVideosDisplayed() | 350 | this.updateOtherVideosDisplayed() |
350 | 351 | ||
diff --git a/client/src/assets/player/peertube-videojs-plugin.ts b/client/src/assets/player/peertube-videojs-plugin.ts index 0dcbe49b1..6d96e1c0b 100644 --- a/client/src/assets/player/peertube-videojs-plugin.ts +++ b/client/src/assets/player/peertube-videojs-plugin.ts | |||
@@ -268,7 +268,12 @@ class PeerTubePlugin extends Plugin { | |||
268 | return this.addTorrent(this.torrent['xs'], previousVideoFile, newOptions, done) | 268 | return this.addTorrent(this.torrent['xs'], previousVideoFile, newOptions, done) |
269 | } | 269 | } |
270 | 270 | ||
271 | return console.warn(err) | 271 | // Remote instance is down |
272 | if (err.message.indexOf('http error from xs param') !== -1) { | ||
273 | this.handleError(err) | ||
274 | } | ||
275 | |||
276 | console.warn(err) | ||
272 | }) | 277 | }) |
273 | } | 278 | } |
274 | 279 | ||
diff --git a/client/src/standalone/videos/embed.scss b/client/src/standalone/videos/embed.scss index f92a1f54a..30650538f 100644 --- a/client/src/standalone/videos/embed.scss +++ b/client/src/standalone/videos/embed.scss | |||
@@ -63,7 +63,6 @@ html, body { | |||
63 | align-content: center; | 63 | align-content: center; |
64 | justify-content: center; | 64 | justify-content: center; |
65 | text-align: center; | 65 | text-align: center; |
66 | background-color: #141313; | ||
67 | width: 100%; | 66 | width: 100%; |
68 | height: 100%; | 67 | height: 100%; |
69 | color: white; | 68 | color: white; |
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts index b2809467d..cb05ec2b5 100644 --- a/client/src/standalone/videos/embed.ts +++ b/client/src/standalone/videos/embed.ts | |||
@@ -188,9 +188,9 @@ class PeerTubeEmbed { | |||
188 | element.parentElement.removeChild(element) | 188 | element.parentElement.removeChild(element) |
189 | } | 189 | } |
190 | 190 | ||
191 | displayError (videoElement: HTMLVideoElement, text: string) { | 191 | displayError (text: string) { |
192 | // Remove video element | 192 | // Remove video element |
193 | this.removeElement(videoElement) | 193 | if (this.videoElement) this.removeElement(this.videoElement) |
194 | 194 | ||
195 | document.title = 'Sorry - ' + text | 195 | document.title = 'Sorry - ' + text |
196 | 196 | ||
@@ -201,14 +201,14 @@ class PeerTubeEmbed { | |||
201 | errorText.innerHTML = text | 201 | errorText.innerHTML = text |
202 | } | 202 | } |
203 | 203 | ||
204 | videoNotFound (videoElement: HTMLVideoElement) { | 204 | videoNotFound () { |
205 | const text = 'This video does not exist.' | 205 | const text = 'This video does not exist.' |
206 | this.displayError(videoElement, text) | 206 | this.displayError(text) |
207 | } | 207 | } |
208 | 208 | ||
209 | videoFetchError (videoElement: HTMLVideoElement) { | 209 | videoFetchError () { |
210 | const text = 'We cannot fetch the video. Please try again later.' | 210 | const text = 'We cannot fetch the video. Please try again later.' |
211 | this.displayError(videoElement, text) | 211 | this.displayError(text) |
212 | } | 212 | } |
213 | 213 | ||
214 | getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) { | 214 | getParamToggle (params: URLSearchParams, name: string, defaultValue: boolean) { |
@@ -264,9 +264,9 @@ class PeerTubeEmbed { | |||
264 | ]) | 264 | ]) |
265 | 265 | ||
266 | if (!videoResponse.ok) { | 266 | if (!videoResponse.ok) { |
267 | if (videoResponse.status === 404) return this.videoNotFound(this.videoElement) | 267 | if (videoResponse.status === 404) return this.videoNotFound() |
268 | 268 | ||
269 | return this.videoFetchError(this.videoElement) | 269 | return this.videoFetchError() |
270 | } | 270 | } |
271 | 271 | ||
272 | const videoInfo: VideoDetails = await videoResponse.json() | 272 | const videoInfo: VideoDetails = await videoResponse.json() |
@@ -303,6 +303,7 @@ class PeerTubeEmbed { | |||
303 | 303 | ||
304 | this.playerOptions = videojsOptions | 304 | this.playerOptions = videojsOptions |
305 | this.player = vjs(this.videoContainerId, videojsOptions, () => { | 305 | this.player = vjs(this.videoContainerId, videojsOptions, () => { |
306 | this.player.on('customError', (event, data) => this.handleError(data.err)) | ||
306 | 307 | ||
307 | window[ 'videojsPlayer' ] = this.player | 308 | window[ 'videojsPlayer' ] = this.player |
308 | 309 | ||
@@ -318,6 +319,15 @@ class PeerTubeEmbed { | |||
318 | this.initializeApi() | 319 | this.initializeApi() |
319 | }) | 320 | }) |
320 | } | 321 | } |
322 | |||
323 | private handleError (err: Error) { | ||
324 | if (err.message.indexOf('http error') !== -1) { | ||
325 | this.player.dispose() | ||
326 | this.videoElement = null | ||
327 | this.displayError('This video is not available because the remote instance is not responding.') | ||
328 | return | ||
329 | } | ||
330 | } | ||
321 | } | 331 | } |
322 | 332 | ||
323 | PeerTubeEmbed.main() | 333 | PeerTubeEmbed.main() |