aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorChocobozzz <me@florianbigard.com>2019-12-05 17:06:18 +0100
committerChocobozzz <me@florianbigard.com>2019-12-05 17:06:18 +0100
commit3d9a63d3d824e753e95292b5e1343e1ebf9eaf71 (patch)
treef52c6da3c014c83e8687fb09ec8645ea845bbcdf
parent0d3a9be9f13c2642cb6cf26fdebc5edf5217bbbc (diff)
downloadPeerTube-3d9a63d3d824e753e95292b5e1343e1ebf9eaf71.tar.gz
PeerTube-3d9a63d3d824e753e95292b5e1343e1ebf9eaf71.tar.zst
PeerTube-3d9a63d3d824e753e95292b5e1343e1ebf9eaf71.zip
Add hook to alter player build options
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts183
-rw-r--r--client/src/assets/player/peertube-player-manager.ts8
-rw-r--r--client/src/standalone/videos/embed.ts2
-rw-r--r--shared/models/plugins/client-hook.model.ts6
4 files changed, 113 insertions, 86 deletions
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 aacd697cf..523865fef 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -5,7 +5,7 @@ import { RedirectService } from '@app/core/routing/redirect.service'
5import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' 5import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage'
6import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' 6import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component'
7import { MetaService } from '@ngx-meta/core' 7import { MetaService } from '@ngx-meta/core'
8import { Notifier, ServerService } from '@app/core' 8import { AuthUser, Notifier, ServerService } from '@app/core'
9import { forkJoin, Observable, Subscription } from 'rxjs' 9import { forkJoin, Observable, Subscription } from 'rxjs'
10import { Hotkey, HotkeysService } from 'angular2-hotkeys' 10import { Hotkey, HotkeysService } from 'angular2-hotkeys'
11import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared' 11import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared'
@@ -391,10 +391,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
391 391
392 this.videoWatchPlaylist.updatePlaylistIndex(video) 392 this.videoWatchPlaylist.updatePlaylistIndex(video)
393 393
394 let startTime = timeToInt(urlOptions.startTime) || (this.video.userHistory ? this.video.userHistory.currentTime : 0)
395 // If we are at the end of the video, reset the timer
396 if (this.video.duration - startTime <= 1) startTime = 0
397
398 if (this.isVideoBlur(this.video)) { 394 if (this.isVideoBlur(this.video)) {
399 const res = await this.confirmService.confirm( 395 const res = await this.confirmService.confirm(
400 this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'), 396 this.i18n('This video contains mature or explicit content. Are you sure you want to watch it?'),
@@ -413,84 +409,20 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
413 this.playerElement.setAttribute('playsinline', 'true') 409 this.playerElement.setAttribute('playsinline', 'true')
414 playerElementWrapper.appendChild(this.playerElement) 410 playerElementWrapper.appendChild(this.playerElement)
415 411
416 const playerCaptions = videoCaptions.map(c => ({ 412 const params = {
417 label: c.language.label, 413 video: this.video,
418 language: c.language.id, 414 videoCaptions,
419 src: environment.apiUrl + c.captionPath 415 urlOptions,
420 })) 416 user: this.user
421
422 const options: PeertubePlayerManagerOptions = {
423 common: {
424 autoplay: this.isAutoplay(),
425
426 playerElement: this.playerElement,
427 onPlayerElementChange: (element: HTMLVideoElement) => this.playerElement = element,
428
429 videoDuration: this.video.duration,
430 enableHotkeys: true,
431 inactivityTimeout: 2500,
432 poster: this.video.previewUrl,
433
434 startTime,
435 stopTime: urlOptions.stopTime,
436 controls: urlOptions.controls,
437 muted: urlOptions.muted,
438 loop: urlOptions.loop,
439 subtitle: urlOptions.subtitle,
440
441 peertubeLink: urlOptions.peertubeLink,
442
443 theaterMode: true,
444 captions: videoCaptions.length !== 0,
445
446 videoViewUrl: this.video.privacy.id !== VideoPrivacy.PRIVATE
447 ? this.videoService.getVideoViewUrl(this.video.uuid)
448 : null,
449 embedUrl: this.video.embedUrl,
450
451 language: this.localeId,
452
453 userWatching: this.user && this.user.videosHistoryEnabled === true ? {
454 url: this.videoService.getUserWatchingVideoUrl(this.video.uuid),
455 authorizationHeader: this.authService.getRequestHeaderValue()
456 } : undefined,
457
458 serverUrl: environment.apiUrl,
459
460 videoCaptions: playerCaptions
461 },
462
463 webtorrent: {
464 videoFiles: this.video.files
465 }
466 }
467
468 let mode: PlayerMode
469
470 if (urlOptions.playerMode) {
471 if (urlOptions.playerMode === 'p2p-media-loader') mode = 'p2p-media-loader'
472 else mode = 'webtorrent'
473 } else {
474 if (this.video.hasHlsPlaylist()) mode = 'p2p-media-loader'
475 else mode = 'webtorrent'
476 }
477
478 if (mode === 'p2p-media-loader') {
479 const hlsPlaylist = this.video.getHlsPlaylist()
480
481 const p2pMediaLoader = {
482 playlistUrl: hlsPlaylist.playlistUrl,
483 segmentsSha256Url: hlsPlaylist.segmentsSha256Url,
484 redundancyBaseUrls: hlsPlaylist.redundancies.map(r => r.baseUrl),
485 trackerAnnounce: this.video.trackerUrls,
486 videoFiles: hlsPlaylist.files
487 } as P2PMediaLoaderOptions
488
489 Object.assign(options, { p2pMediaLoader })
490 } 417 }
418 const { playerMode, playerOptions } = await this.hooks.wrapFun(
419 this.buildPlayerManagerOptions.bind(this),
420 params,
421 'filter:internal.video-watch.player.build-options.result'
422 )
491 423
492 this.zone.runOutsideAngular(async () => { 424 this.zone.runOutsideAngular(async () => {
493 this.player = await PeertubePlayerManager.initialize(mode, options, player => this.player = player) 425 this.player = await PeertubePlayerManager.initialize(playerMode, playerOptions, player => this.player = player)
494 this.player.focus() 426 this.player.focus()
495 427
496 this.player.on('customError', ({ err }: { err: any }) => this.handleError(err)) 428 this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))
@@ -637,6 +569,97 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
637 if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys) 569 if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys)
638 } 570 }
639 571
572 private buildPlayerManagerOptions (params: {
573 video: VideoDetails,
574 videoCaptions: VideoCaption[],
575 urlOptions: CustomizationOptions & { playerMode: PlayerMode },
576 user?: AuthUser
577 }) {
578 const { video, videoCaptions, urlOptions, user } = params
579
580 let startTime = timeToInt(urlOptions.startTime) || (video.userHistory ? video.userHistory.currentTime : 0)
581 // If we are at the end of the video, reset the timer
582 if (video.duration - startTime <= 1) startTime = 0
583
584 const playerCaptions = videoCaptions.map(c => ({
585 label: c.language.label,
586 language: c.language.id,
587 src: environment.apiUrl + c.captionPath
588 }))
589
590 const options: PeertubePlayerManagerOptions = {
591 common: {
592 autoplay: this.isAutoplay(),
593
594 playerElement: this.playerElement,
595 onPlayerElementChange: (element: HTMLVideoElement) => this.playerElement = element,
596
597 videoDuration: video.duration,
598 enableHotkeys: true,
599 inactivityTimeout: 2500,
600 poster: video.previewUrl,
601
602 startTime,
603 stopTime: urlOptions.stopTime,
604 controls: urlOptions.controls,
605 muted: urlOptions.muted,
606 loop: urlOptions.loop,
607 subtitle: urlOptions.subtitle,
608
609 peertubeLink: urlOptions.peertubeLink,
610
611 theaterButton: true,
612 captions: videoCaptions.length !== 0,
613
614 videoViewUrl: video.privacy.id !== VideoPrivacy.PRIVATE
615 ? this.videoService.getVideoViewUrl(video.uuid)
616 : null,
617 embedUrl: video.embedUrl,
618
619 language: this.localeId,
620
621 userWatching: user && user.videosHistoryEnabled === true ? {
622 url: this.videoService.getUserWatchingVideoUrl(video.uuid),
623 authorizationHeader: this.authService.getRequestHeaderValue()
624 } : undefined,
625
626 serverUrl: environment.apiUrl,
627
628 videoCaptions: playerCaptions
629 },
630
631 webtorrent: {
632 videoFiles: video.files
633 }
634 }
635
636 let mode: PlayerMode
637
638 if (urlOptions.playerMode) {
639 if (urlOptions.playerMode === 'p2p-media-loader') mode = 'p2p-media-loader'
640 else mode = 'webtorrent'
641 } else {
642 if (video.hasHlsPlaylist()) mode = 'p2p-media-loader'
643 else mode = 'webtorrent'
644 }
645
646 if (mode === 'p2p-media-loader') {
647 const hlsPlaylist = video.getHlsPlaylist()
648
649 const p2pMediaLoader = {
650 playlistUrl: hlsPlaylist.playlistUrl,
651 segmentsSha256Url: hlsPlaylist.segmentsSha256Url,
652 redundancyBaseUrls: hlsPlaylist.redundancies.map(r => r.baseUrl),
653 trackerAnnounce: video.trackerUrls,
654 videoFiles: hlsPlaylist.files
655 } as P2PMediaLoaderOptions
656
657 Object.assign(options, { p2pMediaLoader })
658 }
659
660 return { playerMode: mode, playerOptions: options }
661 }
662
640 private pausePlayer () { 663 private pausePlayer () {
641 if (!this.player) return 664 if (!this.player) return
642 665
diff --git a/client/src/assets/player/peertube-player-manager.ts b/client/src/assets/player/peertube-player-manager.ts
index 7c7c9ad2a..4ddbaed82 100644
--- a/client/src/assets/player/peertube-player-manager.ts
+++ b/client/src/assets/player/peertube-player-manager.ts
@@ -63,7 +63,7 @@ export interface CommonOptions extends CustomizationOptions {
63 inactivityTimeout: number 63 inactivityTimeout: number
64 poster: string 64 poster: string
65 65
66 theaterMode: boolean 66 theaterButton: boolean
67 captions: boolean 67 captions: boolean
68 68
69 videoViewUrl: string 69 videoViewUrl: string
@@ -311,7 +311,7 @@ export class PeertubePlayerManager {
311 children: this.getControlBarChildren(mode, { 311 children: this.getControlBarChildren(mode, {
312 captions: commonOptions.captions, 312 captions: commonOptions.captions,
313 peertubeLink: commonOptions.peertubeLink, 313 peertubeLink: commonOptions.peertubeLink,
314 theaterMode: commonOptions.theaterMode 314 theaterButton: commonOptions.theaterButton
315 }) 315 })
316 } 316 }
317 } 317 }
@@ -382,7 +382,7 @@ export class PeertubePlayerManager {
382 382
383 private static getControlBarChildren (mode: PlayerMode, options: { 383 private static getControlBarChildren (mode: PlayerMode, options: {
384 peertubeLink: boolean 384 peertubeLink: boolean
385 theaterMode: boolean, 385 theaterButton: boolean,
386 captions: boolean 386 captions: boolean
387 }) { 387 }) {
388 const settingEntries = [] 388 const settingEntries = []
@@ -432,7 +432,7 @@ export class PeertubePlayerManager {
432 }) 432 })
433 } 433 }
434 434
435 if (options.theaterMode === true) { 435 if (options.theaterButton === true) {
436 Object.assign(children, { 436 Object.assign(children, {
437 'theaterButton': {} 437 'theaterButton': {}
438 }) 438 })
diff --git a/client/src/standalone/videos/embed.ts b/client/src/standalone/videos/embed.ts
index 40d945824..bd012f506 100644
--- a/client/src/standalone/videos/embed.ts
+++ b/client/src/standalone/videos/embed.ts
@@ -194,7 +194,7 @@ export class PeerTubeEmbed {
194 enableHotkeys: true, 194 enableHotkeys: true,
195 peertubeLink: true, 195 peertubeLink: true,
196 poster: window.location.origin + videoInfo.previewPath, 196 poster: window.location.origin + videoInfo.previewPath,
197 theaterMode: false, 197 theaterButton: false,
198 198
199 serverUrl: window.location.origin, 199 serverUrl: window.location.origin,
200 language: navigator.language, 200 language: navigator.language,
diff --git a/shared/models/plugins/client-hook.model.ts b/shared/models/plugins/client-hook.model.ts
index 91167ff8c..f0cdb8b19 100644
--- a/shared/models/plugins/client-hook.model.ts
+++ b/shared/models/plugins/client-hook.model.ts
@@ -1,4 +1,5 @@
1// Data from API hooks: {hookType}:api.{location}.{elementType}.{actionType}.{target} 1// Data from API hooks: {hookType}:api.{location}.{elementType}.{actionType}.{target}
2// Data in internal functions: {hookType}:{location}.{elementType}.{actionType}.{target}
2 3
3export const clientFilterHookObject = { 4export const clientFilterHookObject = {
4 // Filter params/result of the function that fetch videos of the trending page 5 // Filter params/result of the function that fetch videos of the trending page
@@ -41,7 +42,10 @@ export const clientFilterHookObject = {
41 'filter:api.search.video-channels.list.result': true, 42 'filter:api.search.video-channels.list.result': true,
42 43
43 // Filter form 44 // Filter form
44 'filter:api.signup.registration.create.params': true 45 'filter:api.signup.registration.create.params': true,
46
47 // Filter the options to create our player
48 'filter:internal.video-watch.player.build-options.result': true
45} 49}
46 50
47export type ClientFilterHookName = keyof typeof clientFilterHookObject 51export type ClientFilterHookName = keyof typeof clientFilterHookObject