X-Git-Url: https://git.immae.eu/?a=blobdiff_plain;f=client%2Fsrc%2Fapp%2Fvideos%2F%2Bvideo-watch%2Fvideo-watch.component.ts;h=0007331f8651d53a792b862ae7dc1cd68717439f;hb=f56ebb3616606e678b25d8064696c75655dcd2ed;hp=6d8bb4b3f1403c12f0eacda0ba571888e20e831f;hpb=18a6f04c071f7a0735eb39b8c67fd51a082d1a31;p=github%2FChocobozzz%2FPeerTube.git 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 6d8bb4b3f..0007331f8 100644 --- a/client/src/app/videos/+video-watch/video-watch.component.ts +++ b/client/src/app/videos/+video-watch/video-watch.component.ts @@ -20,6 +20,7 @@ import { environment } from '../../../environments/environment' import { VideoCaptionService } from '@app/shared/video-caption' import { MarkdownService } from '@app/shared/renderer' import { + videojs, CustomizationOptions, P2PMediaLoaderOptions, PeertubePlayerManager, @@ -33,6 +34,9 @@ import { isWebRTCDisabled, timeToInt } from '../../../assets/player/utils' import { VideoWatchPlaylistComponent } from '@app/videos/+video-watch/video-watch-playlist.component' import { getStoredTheater } from '../../../assets/player/peertube-player-local-storage' import { PluginService } from '@app/core/plugins/plugin.service' +import { HooksService } from '@app/core/plugins/hooks.service' +import { PlatformLocation } from '@angular/common' +import { randomInt } from '@shared/core-utils/miscs/miscs' @Component({ selector: 'my-video-watch', @@ -42,10 +46,10 @@ import { PluginService } from '@app/core/plugins/plugin.service' export class VideoWatchComponent implements OnInit, OnDestroy { private static LOCAL_STORAGE_PRIVACY_CONCERN_KEY = 'video-watch-privacy-concern' - @ViewChild('videoWatchPlaylist') videoWatchPlaylist: VideoWatchPlaylistComponent - @ViewChild('videoShareModal') videoShareModal: VideoShareComponent - @ViewChild('videoSupportModal') videoSupportModal: VideoSupportComponent - @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent + @ViewChild('videoWatchPlaylist', { static: true }) videoWatchPlaylist: VideoWatchPlaylistComponent + @ViewChild('videoShareModal', { static: false }) videoShareModal: VideoShareComponent + @ViewChild('videoSupportModal', { static: false }) videoSupportModal: VideoSupportComponent + @ViewChild('subscribeButton', { static: false }) subscribeButton: SubscribeButtonComponent player: any playerElement: HTMLVideoElement @@ -67,6 +71,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { remoteServerDown = false hotkeys: Hotkey[] + private nextVideoUuid = '' private currentTime: number private paramsSub: Subscription private queryParamsSub: Subscription @@ -93,6 +98,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { private videoCaptionService: VideoCaptionService, private i18n: I18n, private hotkeysService: HotkeysService, + private hooks: HooksService, + private location: PlatformLocation, @Inject(LOCALE_ID) private localeId: string ) {} @@ -101,8 +108,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy { } async ngOnInit () { - await this.pluginService.loadPluginsByScope('video-watch') - this.configSub = this.serverService.configLoaded .subscribe(() => { if ( @@ -131,7 +136,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.theaterEnabled = getStoredTheater() - this.pluginService.runHook('action:video-watch.loaded') + this.hooks.runAction('action:video-watch.init', 'video-watch') } ngOnDestroy () { @@ -198,10 +203,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy { } showSupportModal () { + this.pausePlayer() + this.videoSupportModal.show() } showShareModal () { + this.pausePlayer() + this.videoShareModal.show(this.currentTime) } @@ -215,6 +224,17 @@ export class VideoWatchComponent implements OnInit, OnDestroy { return this.video.tags } + onRecommendations (videos: Video[]) { + if (videos.length > 0) { + // Pick a random video until the recommendations are improved + this.nextVideoUuid = videos[randomInt(0,videos.length - 1)].uuid + } + } + + onModalOpened () { + this.pausePlayer() + } + onVideoRemoved () { this.redirectService.redirectToHomepage() } @@ -246,11 +266,19 @@ export class VideoWatchComponent implements OnInit, OnDestroy { if (this.player) this.player.pause() + const videoObs = this.hooks.wrapObsFun( + this.videoService.getVideo.bind(this.videoService), + { videoId }, + 'video-watch', + 'filter:api.video-watch.video.get.params', + 'filter:api.video-watch.video.get.result' + ) + // Video did change - forkJoin( - this.videoService.getVideo(videoId), + forkJoin([ + videoObs, this.videoCaptionService.listCaptions(videoId) - ) + ]) .pipe( // If 401, the video is private or blacklisted so redirect to 404 catchError(err => this.restExtractor.redirectTo404IfNotFound(err, [ 400, 401, 403, 404 ])) @@ -366,13 +394,13 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'), this.i18n('Mature or explicit content') ) - if (res === false) return this.redirectService.redirectToHomepage() + if (res === false) return this.location.back() } // Flush old player if needed this.flushPlayer() - // Build video element, because videojs remove it on dispose + // Build video element, because videojs removes it on dispose const playerElementWrapper = this.elementRef.nativeElement.querySelector('#videojs-wrapper') this.playerElement = document.createElement('video') this.playerElement.className = 'video-js vjs-peertube-skin' @@ -449,14 +477,15 @@ export class VideoWatchComponent implements OnInit, OnDestroy { segmentsSha256Url: hlsPlaylist.segmentsSha256Url, redundancyBaseUrls: hlsPlaylist.redundancies.map(r => r.baseUrl), trackerAnnounce: this.video.trackerUrls, - videoFiles: this.video.files + videoFiles: hlsPlaylist.files } as P2PMediaLoaderOptions Object.assign(options, { p2pMediaLoader }) } this.zone.runOutsideAngular(async () => { - this.player = await PeertubePlayerManager.initialize(mode, options) + this.player = await PeertubePlayerManager.initialize(mode, options, player => this.player = player) + this.player.focus() this.player.on('customError', ({ err }: { err: any }) => this.handleError(err)) @@ -467,6 +496,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.player.one('ended', () => { if (this.playlist) { this.zone.run(() => this.videoWatchPlaylist.navigateToNextPlaylistVideo()) + } else if (this.user && this.user.autoPlayNextVideo) { + this.zone.run(() => this.autoplayNext()) } }) @@ -479,6 +510,8 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.player.on('theaterChange', (_: any, enabled: boolean) => { this.zone.run(() => this.theaterEnabled = enabled) }) + + this.hooks.runAction('action:video-watch.player.loaded', 'video-watch', { player: this.player }) }) this.setVideoDescriptionHTML() @@ -486,6 +519,14 @@ export class VideoWatchComponent implements OnInit, OnDestroy { this.setOpenGraphTags() this.checkUserRating() + + this.hooks.runAction('action:video-watch.video.loaded', 'video-watch', { videojs }) + } + + private autoplayNext () { + if (this.nextVideoUuid) { + this.router.navigate([ '/videos/watch', this.nextVideoUuid ]) + } } private setRating (nextRating: UserVideoRateType) { @@ -589,4 +630,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy { ] if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) } + + private pausePlayer () { + if (!this.player) return + + this.player.pause() + } }