diff options
Diffstat (limited to 'client/src/app/+videos')
10 files changed, 94 insertions, 28 deletions
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.html b/client/src/app/+videos/+video-edit/shared/video-edit.component.html index c444dd8d3..0802e906d 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.html +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.html | |||
@@ -195,7 +195,7 @@ | |||
195 | </ng-template> | 195 | </ng-template> |
196 | </ng-container> | 196 | </ng-container> |
197 | 197 | ||
198 | <ng-container ngbNavItem *ngIf="videoLive"> | 198 | <ng-container ngbNavItem *ngIf="liveVideo"> |
199 | <a ngbNavLink i18n>Live settings</a> | 199 | <a ngbNavLink i18n>Live settings</a> |
200 | 200 | ||
201 | <ng-template ngbNavContent> | 201 | <ng-template ngbNavContent> |
@@ -203,13 +203,13 @@ | |||
203 | <div class="col-md-12"> | 203 | <div class="col-md-12"> |
204 | 204 | ||
205 | <div class="form-group"> | 205 | <div class="form-group"> |
206 | <label for="videoLiveRTMPUrl" i18n>Live RTMP Url</label> | 206 | <label for="liveVideoRTMPUrl" i18n>Live RTMP Url</label> |
207 | <my-input-readonly-copy id="videoLiveRTMPUrl" [value]="videoLive.rtmpUrl"></my-input-readonly-copy> | 207 | <my-input-readonly-copy id="liveVideoRTMPUrl" [value]="liveVideo.rtmpUrl"></my-input-readonly-copy> |
208 | </div> | 208 | </div> |
209 | 209 | ||
210 | <div class="form-group"> | 210 | <div class="form-group"> |
211 | <label for="videoLiveStreamKey" i18n>Live stream key</label> | 211 | <label for="liveVideoStreamKey" i18n>Live stream key</label> |
212 | <my-input-readonly-copy id="videoLiveStreamKey" [value]="videoLive.streamKey"></my-input-readonly-copy> | 212 | <my-input-readonly-copy id="liveVideoStreamKey" [value]="liveVideo.streamKey"></my-input-readonly-copy> |
213 | </div> | 213 | </div> |
214 | </div> | 214 | </div> |
215 | </div> | 215 | </div> |
diff --git a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts index bee65184b..304bf7ed0 100644 --- a/client/src/app/+videos/+video-edit/shared/video-edit.component.ts +++ b/client/src/app/+videos/+video-edit/shared/video-edit.component.ts | |||
@@ -20,7 +20,7 @@ import { | |||
20 | import { FormReactiveValidationMessages, FormValidatorService, SelectChannelItem } from '@app/shared/shared-forms' | 20 | import { FormReactiveValidationMessages, FormValidatorService, SelectChannelItem } from '@app/shared/shared-forms' |
21 | import { InstanceService } from '@app/shared/shared-instance' | 21 | import { InstanceService } from '@app/shared/shared-instance' |
22 | import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' | 22 | import { VideoCaptionEdit, VideoEdit, VideoService } from '@app/shared/shared-main' |
23 | import { ServerConfig, VideoConstant, VideoLive, VideoPrivacy } from '@shared/models' | 23 | import { ServerConfig, VideoConstant, LiveVideo, VideoPrivacy } from '@shared/models' |
24 | import { RegisterClientFormFieldOptions, RegisterClientVideoFieldOptions } from '@shared/models/plugins/register-client-form-field.model' | 24 | import { RegisterClientFormFieldOptions, RegisterClientVideoFieldOptions } from '@shared/models/plugins/register-client-form-field.model' |
25 | import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service' | 25 | import { I18nPrimengCalendarService } from './i18n-primeng-calendar.service' |
26 | import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' | 26 | import { VideoCaptionAddModalComponent } from './video-caption-add-modal.component' |
@@ -42,7 +42,7 @@ export class VideoEditComponent implements OnInit, OnDestroy { | |||
42 | @Input() videoCaptions: (VideoCaptionEdit & { captionPath?: string })[] = [] | 42 | @Input() videoCaptions: (VideoCaptionEdit & { captionPath?: string })[] = [] |
43 | @Input() waitTranscodingEnabled = true | 43 | @Input() waitTranscodingEnabled = true |
44 | @Input() type: VideoEditType | 44 | @Input() type: VideoEditType |
45 | @Input() videoLive: VideoLive | 45 | @Input() liveVideo: LiveVideo |
46 | 46 | ||
47 | @ViewChild('videoCaptionAddModal', { static: true }) videoCaptionAddModal: VideoCaptionAddModalComponent | 47 | @ViewChild('videoCaptionAddModal', { static: true }) videoCaptionAddModal: VideoCaptionAddModalComponent |
48 | 48 | ||
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html index 6997f5388..8fae4044a 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html +++ b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.html | |||
@@ -31,7 +31,7 @@ | |||
31 | <form [hidden]="!isInUpdateForm" novalidate [formGroup]="form"> | 31 | <form [hidden]="!isInUpdateForm" novalidate [formGroup]="form"> |
32 | <my-video-edit | 32 | <my-video-edit |
33 | [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions" [schedulePublicationPossible]="false" | 33 | [form]="form" [formErrors]="formErrors" [videoCaptions]="videoCaptions" [schedulePublicationPossible]="false" |
34 | [validationMessages]="validationMessages" [userVideoChannels]="userVideoChannels" [videoLive]="videoLive" | 34 | [validationMessages]="validationMessages" [userVideoChannels]="userVideoChannels" [liveVideo]="liveVideo" |
35 | type="go-live" | 35 | type="go-live" |
36 | ></my-video-edit> | 36 | ></my-video-edit> |
37 | 37 | ||
diff --git a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.ts b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.ts index 64fd4c4d4..0a9efc693 100644 --- a/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.ts +++ b/client/src/app/+videos/+video-edit/video-add-components/video-go-live.component.ts | |||
@@ -4,9 +4,9 @@ import { Router } from '@angular/router' | |||
4 | import { AuthService, CanComponentDeactivate, Notifier, ServerService } from '@app/core' | 4 | import { AuthService, CanComponentDeactivate, Notifier, ServerService } from '@app/core' |
5 | import { scrollToTop } from '@app/helpers' | 5 | import { scrollToTop } from '@app/helpers' |
6 | import { FormValidatorService } from '@app/shared/shared-forms' | 6 | import { FormValidatorService } from '@app/shared/shared-forms' |
7 | import { VideoCaptionService, VideoEdit, VideoService, VideoLiveService } from '@app/shared/shared-main' | 7 | import { LiveVideoService, VideoCaptionService, VideoEdit, VideoService } from '@app/shared/shared-main' |
8 | import { LoadingBarService } from '@ngx-loading-bar/core' | 8 | import { LoadingBarService } from '@ngx-loading-bar/core' |
9 | import { VideoCreate, VideoLive, VideoPrivacy } from '@shared/models' | 9 | import { LiveVideo, VideoCreate, VideoPrivacy } from '@shared/models' |
10 | import { VideoSend } from './video-send' | 10 | import { VideoSend } from './video-send' |
11 | 11 | ||
12 | @Component({ | 12 | @Component({ |
@@ -23,7 +23,7 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, CanCompon | |||
23 | 23 | ||
24 | isInUpdateForm = false | 24 | isInUpdateForm = false |
25 | 25 | ||
26 | videoLive: VideoLive | 26 | liveVideo: LiveVideo |
27 | videoId: number | 27 | videoId: number |
28 | videoUUID: string | 28 | videoUUID: string |
29 | error: string | 29 | error: string |
@@ -38,7 +38,7 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, CanCompon | |||
38 | protected serverService: ServerService, | 38 | protected serverService: ServerService, |
39 | protected videoService: VideoService, | 39 | protected videoService: VideoService, |
40 | protected videoCaptionService: VideoCaptionService, | 40 | protected videoCaptionService: VideoCaptionService, |
41 | private videoLiveService: VideoLiveService, | 41 | private liveVideoService: LiveVideoService, |
42 | private router: Router | 42 | private router: Router |
43 | ) { | 43 | ) { |
44 | super() | 44 | super() |
@@ -69,7 +69,7 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, CanCompon | |||
69 | const toPatch = Object.assign({}, video, { privacy: this.firstStepPrivacyId }) | 69 | const toPatch = Object.assign({}, video, { privacy: this.firstStepPrivacyId }) |
70 | this.form.patchValue(toPatch) | 70 | this.form.patchValue(toPatch) |
71 | 71 | ||
72 | this.videoLiveService.goLive(video).subscribe( | 72 | this.liveVideoService.goLive(video).subscribe( |
73 | res => { | 73 | res => { |
74 | this.videoId = res.video.id | 74 | this.videoId = res.video.id |
75 | this.videoUUID = res.video.uuid | 75 | this.videoUUID = res.video.uuid |
@@ -114,10 +114,10 @@ export class VideoGoLiveComponent extends VideoSend implements OnInit, CanCompon | |||
114 | } | 114 | } |
115 | 115 | ||
116 | private fetchVideoLive () { | 116 | private fetchVideoLive () { |
117 | this.videoLiveService.getVideoLive(this.videoId) | 117 | this.liveVideoService.getVideoLive(this.videoId) |
118 | .subscribe( | 118 | .subscribe( |
119 | videoLive => { | 119 | liveVideo => { |
120 | this.videoLive = videoLive | 120 | this.liveVideo = liveVideo |
121 | }, | 121 | }, |
122 | 122 | ||
123 | err => { | 123 | err => { |
diff --git a/client/src/app/+videos/+video-edit/video-update.component.html b/client/src/app/+videos/+video-edit/video-update.component.html index 5f50ddc74..f290fd136 100644 --- a/client/src/app/+videos/+video-edit/video-update.component.html +++ b/client/src/app/+videos/+video-edit/video-update.component.html | |||
@@ -11,7 +11,7 @@ | |||
11 | [validationMessages]="validationMessages" [userVideoChannels]="userVideoChannels" | 11 | [validationMessages]="validationMessages" [userVideoChannels]="userVideoChannels" |
12 | [videoCaptions]="videoCaptions" [waitTranscodingEnabled]="waitTranscodingEnabled" | 12 | [videoCaptions]="videoCaptions" [waitTranscodingEnabled]="waitTranscodingEnabled" |
13 | type="update" (pluginFieldsAdded)="hydratePluginFieldsFromVideo()" | 13 | type="update" (pluginFieldsAdded)="hydratePluginFieldsFromVideo()" |
14 | [videoLive]="videoLive" | 14 | [liveVideo]="liveVideo" |
15 | ></my-video-edit> | 15 | ></my-video-edit> |
16 | 16 | ||
17 | <div class="submit-container"> | 17 | <div class="submit-container"> |
diff --git a/client/src/app/+videos/+video-edit/video-update.component.ts b/client/src/app/+videos/+video-edit/video-update.component.ts index c0f46acd2..ec1305a33 100644 --- a/client/src/app/+videos/+video-edit/video-update.component.ts +++ b/client/src/app/+videos/+video-edit/video-update.component.ts | |||
@@ -5,7 +5,7 @@ import { Notifier } from '@app/core' | |||
5 | import { FormReactive, FormValidatorService, SelectChannelItem } from '@app/shared/shared-forms' | 5 | import { FormReactive, FormValidatorService, SelectChannelItem } from '@app/shared/shared-forms' |
6 | import { VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main' | 6 | import { VideoCaptionEdit, VideoCaptionService, VideoDetails, VideoEdit, VideoService } from '@app/shared/shared-main' |
7 | import { LoadingBarService } from '@ngx-loading-bar/core' | 7 | import { LoadingBarService } from '@ngx-loading-bar/core' |
8 | import { VideoPrivacy, VideoLive } from '@shared/models' | 8 | import { LiveVideo, VideoPrivacy } from '@shared/models' |
9 | import { hydrateFormFromVideo } from './shared/video-edit-utils' | 9 | import { hydrateFormFromVideo } from './shared/video-edit-utils' |
10 | 10 | ||
11 | @Component({ | 11 | @Component({ |
@@ -17,7 +17,7 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
17 | video: VideoEdit | 17 | video: VideoEdit |
18 | userVideoChannels: SelectChannelItem[] = [] | 18 | userVideoChannels: SelectChannelItem[] = [] |
19 | videoCaptions: VideoCaptionEdit[] = [] | 19 | videoCaptions: VideoCaptionEdit[] = [] |
20 | videoLive: VideoLive | 20 | liveVideo: LiveVideo |
21 | 21 | ||
22 | isUpdatingVideo = false | 22 | isUpdatingVideo = false |
23 | schedulePublicationPossible = false | 23 | schedulePublicationPossible = false |
@@ -42,11 +42,11 @@ export class VideoUpdateComponent extends FormReactive implements OnInit { | |||
42 | 42 | ||
43 | this.route.data | 43 | this.route.data |
44 | .pipe(map(data => data.videoData)) | 44 | .pipe(map(data => data.videoData)) |
45 | .subscribe(({ video, videoChannels, videoCaptions, videoLive }) => { | 45 | .subscribe(({ video, videoChannels, videoCaptions, liveVideo }) => { |
46 | this.video = new VideoEdit(video) | 46 | this.video = new VideoEdit(video) |
47 | this.userVideoChannels = videoChannels | 47 | this.userVideoChannels = videoChannels |
48 | this.videoCaptions = videoCaptions | 48 | this.videoCaptions = videoCaptions |
49 | this.videoLive = videoLive | 49 | this.liveVideo = liveVideo |
50 | 50 | ||
51 | this.schedulePublicationPossible = this.video.privacy === VideoPrivacy.PRIVATE | 51 | this.schedulePublicationPossible = this.video.privacy === VideoPrivacy.PRIVATE |
52 | 52 | ||
diff --git a/client/src/app/+videos/+video-edit/video-update.resolver.ts b/client/src/app/+videos/+video-edit/video-update.resolver.ts index 3a82324c3..b7ec22dd5 100644 --- a/client/src/app/+videos/+video-edit/video-update.resolver.ts +++ b/client/src/app/+videos/+video-edit/video-update.resolver.ts | |||
@@ -2,13 +2,13 @@ import { forkJoin, of } from 'rxjs' | |||
2 | import { map, switchMap } from 'rxjs/operators' | 2 | import { map, switchMap } from 'rxjs/operators' |
3 | import { Injectable } from '@angular/core' | 3 | import { Injectable } from '@angular/core' |
4 | import { ActivatedRouteSnapshot, Resolve } from '@angular/router' | 4 | import { ActivatedRouteSnapshot, Resolve } from '@angular/router' |
5 | import { VideoCaptionService, VideoChannelService, VideoDetails, VideoLiveService, VideoService } from '@app/shared/shared-main' | 5 | import { VideoCaptionService, VideoChannelService, VideoDetails, LiveVideoService, VideoService } from '@app/shared/shared-main' |
6 | 6 | ||
7 | @Injectable() | 7 | @Injectable() |
8 | export class VideoUpdateResolver implements Resolve<any> { | 8 | export class VideoUpdateResolver implements Resolve<any> { |
9 | constructor ( | 9 | constructor ( |
10 | private videoService: VideoService, | 10 | private videoService: VideoService, |
11 | private videoLiveService: VideoLiveService, | 11 | private liveVideoService: LiveVideoService, |
12 | private videoChannelService: VideoChannelService, | 12 | private videoChannelService: VideoChannelService, |
13 | private videoCaptionService: VideoCaptionService | 13 | private videoCaptionService: VideoCaptionService |
14 | ) { | 14 | ) { |
@@ -49,7 +49,7 @@ export class VideoUpdateResolver implements Resolve<any> { | |||
49 | ), | 49 | ), |
50 | 50 | ||
51 | video.isLive | 51 | video.isLive |
52 | ? this.videoLiveService.getVideoLive(video.id) | 52 | ? this.liveVideoService.getVideoLive(video.id) |
53 | : of(undefined) | 53 | : of(undefined) |
54 | ] | 54 | ] |
55 | } | 55 | } |
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 0d1768aa9..13242a2bc 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.html +++ b/client/src/app/+videos/+video-watch/video-watch.component.html | |||
@@ -29,6 +29,14 @@ | |||
29 | This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}. | 29 | This video will be published on {{ video.scheduledUpdate.updateAt | date: 'full' }}. |
30 | </div> | 30 | </div> |
31 | 31 | ||
32 | <div i18n class="col-md-12 alert alert-info" *ngIf="isWaitingForLive()"> | ||
33 | This live has not started yet. | ||
34 | </div> | ||
35 | |||
36 | <div i18n class="col-md-12 alert alert-info" *ngIf="isLiveEnded()"> | ||
37 | This live is finished. | ||
38 | </div> | ||
39 | |||
32 | <div class="col-md-12 alert alert-danger" *ngIf="video?.blacklisted"> | 40 | <div class="col-md-12 alert alert-danger" *ngIf="video?.blacklisted"> |
33 | <div class="blocked-label" i18n>This video is blocked.</div> | 41 | <div class="blocked-label" i18n>This video is blocked.</div> |
34 | {{ video.blockedReason }} | 42 | {{ video.blockedReason }} |
@@ -113,7 +121,7 @@ | |||
113 | </div> | 121 | </div> |
114 | </div> | 122 | </div> |
115 | 123 | ||
116 | <ng-container *ngIf="!isUserLoggedIn()"> | 124 | <ng-container *ngIf="!isUserLoggedIn() && !isLive()"> |
117 | <button | 125 | <button |
118 | *ngIf="isVideoDownloadable()" class="action-button action-button-save" | 126 | *ngIf="isVideoDownloadable()" class="action-button action-button-save" |
119 | (click)="showDownloadModal()" (keydown.enter)="showDownloadModal()" | 127 | (click)="showDownloadModal()" (keydown.enter)="showDownloadModal()" |
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 b2bd04cf3..4bf5ff808 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.scss +++ b/client/src/app/+videos/+video-watch/video-watch.component.scss | |||
@@ -50,6 +50,8 @@ $video-info-margin-left: 44px; | |||
50 | } | 50 | } |
51 | 51 | ||
52 | #video-wrapper { | 52 | #video-wrapper { |
53 | $video-height: 66vh; | ||
54 | |||
53 | background-color: #000; | 55 | background-color: #000; |
54 | display: flex; | 56 | display: flex; |
55 | justify-content: center; | 57 | justify-content: center; |
@@ -58,6 +60,7 @@ $video-info-margin-left: 44px; | |||
58 | display: flex; | 60 | display: flex; |
59 | justify-content: center; | 61 | justify-content: center; |
60 | flex-grow: 1; | 62 | flex-grow: 1; |
63 | height: $video-height; | ||
61 | } | 64 | } |
62 | 65 | ||
63 | .remote-server-down { | 66 | .remote-server-down { |
@@ -84,7 +87,7 @@ $video-info-margin-left: 44px; | |||
84 | ::ng-deep .video-js { | 87 | ::ng-deep .video-js { |
85 | width: 100%; | 88 | width: 100%; |
86 | max-width: getPlayerWidth(66vh); | 89 | max-width: getPlayerWidth(66vh); |
87 | height: 66vh; | 90 | height: $video-height; |
88 | 91 | ||
89 | // VideoJS create an inner video player | 92 | // VideoJS create an inner video player |
90 | video { | 93 | 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 fde32dc74..e4edb42fb 100644 --- a/client/src/app/+videos/+video-watch/video-watch.component.ts +++ b/client/src/app/+videos/+video-watch/video-watch.component.ts | |||
@@ -4,7 +4,17 @@ import { catchError } from 'rxjs/operators' | |||
4 | import { PlatformLocation } from '@angular/common' | 4 | import { PlatformLocation } from '@angular/common' |
5 | import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' | 5 | import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core' |
6 | import { ActivatedRoute, Router } from '@angular/router' | 6 | import { ActivatedRoute, Router } from '@angular/router' |
7 | import { AuthService, AuthUser, ConfirmService, MarkdownService, Notifier, RestExtractor, ServerService, UserService } from '@app/core' | 7 | import { |
8 | AuthService, | ||
9 | AuthUser, | ||
10 | ConfirmService, | ||
11 | MarkdownService, | ||
12 | Notifier, | ||
13 | PeerTubeSocket, | ||
14 | RestExtractor, | ||
15 | ServerService, | ||
16 | UserService | ||
17 | } from '@app/core' | ||
8 | import { HooksService } from '@app/core/plugins/hooks.service' | 18 | import { HooksService } from '@app/core/plugins/hooks.service' |
9 | import { RedirectService } from '@app/core/routing/redirect.service' | 19 | import { RedirectService } from '@app/core/routing/redirect.service' |
10 | import { isXPercentInViewport, scrollToTop } from '@app/helpers' | 20 | import { isXPercentInViewport, scrollToTop } from '@app/helpers' |
@@ -30,6 +40,8 @@ import { environment } from '../../../environments/environment' | |||
30 | import { VideoSupportComponent } from './modal/video-support.component' | 40 | import { VideoSupportComponent } from './modal/video-support.component' |
31 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' | 41 | import { VideoWatchPlaylistComponent } from './video-watch-playlist.component' |
32 | 42 | ||
43 | type URLOptions = CustomizationOptions & { playerMode: PlayerMode } | ||
44 | |||
33 | @Component({ | 45 | @Component({ |
34 | selector: 'my-video-watch', | 46 | selector: 'my-video-watch', |
35 | templateUrl: './video-watch.component.html', | 47 | templateUrl: './video-watch.component.html', |
@@ -76,6 +88,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
76 | private paramsSub: Subscription | 88 | private paramsSub: Subscription |
77 | private queryParamsSub: Subscription | 89 | private queryParamsSub: Subscription |
78 | private configSub: Subscription | 90 | private configSub: Subscription |
91 | private liveVideosSub: Subscription | ||
79 | 92 | ||
80 | private serverConfig: ServerConfig | 93 | private serverConfig: ServerConfig |
81 | 94 | ||
@@ -99,6 +112,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
99 | private videoCaptionService: VideoCaptionService, | 112 | private videoCaptionService: VideoCaptionService, |
100 | private hotkeysService: HotkeysService, | 113 | private hotkeysService: HotkeysService, |
101 | private hooks: HooksService, | 114 | private hooks: HooksService, |
115 | private peertubeSocket: PeerTubeSocket, | ||
102 | private location: PlatformLocation, | 116 | private location: PlatformLocation, |
103 | @Inject(LOCALE_ID) private localeId: string | 117 | @Inject(LOCALE_ID) private localeId: string |
104 | ) { | 118 | ) { |
@@ -165,6 +179,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
165 | if (this.paramsSub) this.paramsSub.unsubscribe() | 179 | if (this.paramsSub) this.paramsSub.unsubscribe() |
166 | if (this.queryParamsSub) this.queryParamsSub.unsubscribe() | 180 | if (this.queryParamsSub) this.queryParamsSub.unsubscribe() |
167 | if (this.configSub) this.configSub.unsubscribe() | 181 | if (this.configSub) this.configSub.unsubscribe() |
182 | if (this.liveVideosSub) this.liveVideosSub.unsubscribe() | ||
168 | 183 | ||
169 | // Unbind hotkeys | 184 | // Unbind hotkeys |
170 | this.hotkeysService.remove(this.hotkeys) | 185 | this.hotkeysService.remove(this.hotkeys) |
@@ -306,6 +321,18 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
306 | return this.video && this.video.scheduledUpdate !== undefined | 321 | return this.video && this.video.scheduledUpdate !== undefined |
307 | } | 322 | } |
308 | 323 | ||
324 | isLive () { | ||
325 | return !!(this.video?.isLive) | ||
326 | } | ||
327 | |||
328 | isWaitingForLive () { | ||
329 | return this.video?.state.id === VideoState.WAITING_FOR_LIVE | ||
330 | } | ||
331 | |||
332 | isLiveEnded () { | ||
333 | return this.video?.state.id === VideoState.LIVE_ENDED | ||
334 | } | ||
335 | |||
309 | isVideoBlur (video: Video) { | 336 | isVideoBlur (video: Video) { |
310 | return video.isVideoNSFWForUser(this.user, this.serverConfig) | 337 | return video.isVideoNSFWForUser(this.user, this.serverConfig) |
311 | } | 338 | } |
@@ -470,8 +497,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
470 | private async onVideoFetched ( | 497 | private async onVideoFetched ( |
471 | video: VideoDetails, | 498 | video: VideoDetails, |
472 | videoCaptions: VideoCaption[], | 499 | videoCaptions: VideoCaption[], |
473 | urlOptions: CustomizationOptions & { playerMode: PlayerMode } | 500 | urlOptions: URLOptions |
474 | ) { | 501 | ) { |
502 | this.subscribeToLiveEventsIfNeeded(this.video, video) | ||
503 | |||
475 | this.video = video | 504 | this.video = video |
476 | this.videoCaptions = videoCaptions | 505 | this.videoCaptions = videoCaptions |
477 | 506 | ||
@@ -489,6 +518,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
489 | if (res === false) return this.location.back() | 518 | if (res === false) return this.location.back() |
490 | } | 519 | } |
491 | 520 | ||
521 | const videoState = this.video.state.id | ||
522 | if (videoState === VideoState.LIVE_ENDED || videoState === VideoState.WAITING_FOR_LIVE) return | ||
523 | |||
492 | // Flush old player if needed | 524 | // Flush old player if needed |
493 | this.flushPlayer() | 525 | this.flushPlayer() |
494 | 526 | ||
@@ -794,6 +826,29 @@ export class VideoWatchComponent implements OnInit, OnDestroy { | |||
794 | return !this.player.paused() | 826 | return !this.player.paused() |
795 | } | 827 | } |
796 | 828 | ||
829 | private async subscribeToLiveEventsIfNeeded (oldVideo: VideoDetails, newVideo: VideoDetails) { | ||
830 | if (!this.liveVideosSub) { | ||
831 | this.liveVideosSub = this.peertubeSocket.getLiveVideosObservable() | ||
832 | .subscribe(({ payload }) => { | ||
833 | if (payload.state !== VideoState.PUBLISHED || this.video.state.id !== VideoState.WAITING_FOR_LIVE) return | ||
834 | |||
835 | const videoUUID = this.video.uuid | ||
836 | |||
837 | // Reset to refetch the video | ||
838 | this.video = undefined | ||
839 | this.loadVideo(videoUUID) | ||
840 | }) | ||
841 | } | ||
842 | |||
843 | if (oldVideo && oldVideo.id !== newVideo.id) { | ||
844 | await this.peertubeSocket.unsubscribeLiveVideos(oldVideo.id) | ||
845 | } | ||
846 | |||
847 | if (!newVideo.isLive) return | ||
848 | |||
849 | await this.peertubeSocket.subscribeToLiveVideosSocket(newVideo.id) | ||
850 | } | ||
851 | |||
797 | private initHotkeys () { | 852 | private initHotkeys () { |
798 | this.hotkeys = [ | 853 | this.hotkeys = [ |
799 | // These hotkeys are managed by the player | 854 | // These hotkeys are managed by the player |