diff options
Diffstat (limited to 'client/src/app/videos')
-rw-r--r-- | client/src/app/videos/+video-watch/video-watch.component.ts | 183 |
1 files changed, 103 insertions, 80 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' | |||
5 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' | 5 | import { peertubeLocalStorage } from '@app/shared/misc/peertube-local-storage' |
6 | import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' | 6 | import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-support.component' |
7 | import { MetaService } from '@ngx-meta/core' | 7 | import { MetaService } from '@ngx-meta/core' |
8 | import { Notifier, ServerService } from '@app/core' | 8 | import { AuthUser, Notifier, ServerService } from '@app/core' |
9 | import { forkJoin, Observable, Subscription } from 'rxjs' | 9 | import { forkJoin, Observable, Subscription } from 'rxjs' |
10 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' | 10 | import { Hotkey, HotkeysService } from 'angular2-hotkeys' |
11 | import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared' | 11 | import { 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 | ||