aboutsummaryrefslogtreecommitdiffhomepage
path: root/client/src/app/videos/+video-watch/video-watch.component.ts
diff options
context:
space:
mode:
Diffstat (limited to 'client/src/app/videos/+video-watch/video-watch.component.ts')
-rw-r--r--client/src/app/videos/+video-watch/video-watch.component.ts119
1 files changed, 74 insertions, 45 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 67c5254b3..4dbfa41e5 100644
--- a/client/src/app/videos/+video-watch/video-watch.component.ts
+++ b/client/src/app/videos/+video-watch/video-watch.component.ts
@@ -7,29 +7,27 @@ import { VideoSupportComponent } from '@app/videos/+video-watch/modal/video-supp
7import { MetaService } from '@ngx-meta/core' 7import { MetaService } from '@ngx-meta/core'
8import { Notifier, ServerService } from '@app/core' 8import { Notifier, ServerService } from '@app/core'
9import { forkJoin, Subscription } from 'rxjs' 9import { forkJoin, Subscription } from 'rxjs'
10// FIXME: something weird with our path definition in tsconfig and typings
11// @ts-ignore
12import videojs from 'video.js'
13import 'videojs-hotkeys'
14import { Hotkey, HotkeysService } from 'angular2-hotkeys' 10import { Hotkey, HotkeysService } from 'angular2-hotkeys'
15import * as WebTorrent from 'webtorrent'
16import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared' 11import { UserVideoRateType, VideoCaption, VideoPrivacy, VideoState } from '../../../../../shared'
17import '../../../assets/player/peertube-videojs-plugin'
18import { AuthService, ConfirmService } from '../../core' 12import { AuthService, ConfirmService } from '../../core'
19import { RestExtractor, VideoBlacklistService } from '../../shared' 13import { RestExtractor, VideoBlacklistService } from '../../shared'
20import { VideoDetails } from '../../shared/video/video-details.model' 14import { VideoDetails } from '../../shared/video/video-details.model'
21import { VideoService } from '../../shared/video/video.service' 15import { VideoService } from '../../shared/video/video.service'
22import { MarkdownService } from '../shared'
23import { VideoDownloadComponent } from './modal/video-download.component' 16import { VideoDownloadComponent } from './modal/video-download.component'
24import { VideoReportComponent } from './modal/video-report.component' 17import { VideoReportComponent } from './modal/video-report.component'
25import { VideoShareComponent } from './modal/video-share.component' 18import { VideoShareComponent } from './modal/video-share.component'
26import { VideoBlacklistComponent } from './modal/video-blacklist.component' 19import { VideoBlacklistComponent } from './modal/video-blacklist.component'
27import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component' 20import { SubscribeButtonComponent } from '@app/shared/user-subscription/subscribe-button.component'
28import { addContextMenu, getVideojsOptions, loadLocaleInVideoJS } from '../../../assets/player/peertube-player'
29import { I18n } from '@ngx-translate/i18n-polyfill' 21import { I18n } from '@ngx-translate/i18n-polyfill'
30import { environment } from '../../../environments/environment' 22import { environment } from '../../../environments/environment'
31import { getDevLocale, isOnDevLocale } from '@app/shared/i18n/i18n-utils'
32import { VideoCaptionService } from '@app/shared/video-caption' 23import { VideoCaptionService } from '@app/shared/video-caption'
24import { MarkdownService } from '@app/shared/renderer'
25import {
26 P2PMediaLoaderOptions,
27 PeertubePlayerManager,
28 PeertubePlayerManagerOptions,
29 PlayerMode
30} from '../../../assets/player/peertube-player-manager'
33 31
34@Component({ 32@Component({
35 selector: 'my-video-watch', 33 selector: 'my-video-watch',
@@ -46,7 +44,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
46 @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent 44 @ViewChild('videoBlacklistModal') videoBlacklistModal: VideoBlacklistComponent
47 @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent 45 @ViewChild('subscribeButton') subscribeButton: SubscribeButtonComponent
48 46
49 player: videojs.Player 47 player: any
50 playerElement: HTMLVideoElement 48 playerElement: HTMLVideoElement
51 userRating: UserVideoRateType = null 49 userRating: UserVideoRateType = null
52 video: VideoDetails = null 50 video: VideoDetails = null
@@ -61,7 +59,6 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
61 remoteServerDown = false 59 remoteServerDown = false
62 hotkeys: Hotkey[] 60 hotkeys: Hotkey[]
63 61
64 private videojsLocaleLoaded = false
65 private paramsSub: Subscription 62 private paramsSub: Subscription
66 63
67 constructor ( 64 constructor (
@@ -92,7 +89,7 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
92 89
93 ngOnInit () { 90 ngOnInit () {
94 if ( 91 if (
95 WebTorrent.WEBRTC_SUPPORT === false || 92 !!((window as any).RTCPeerConnection || (window as any).mozRTCPeerConnection || (window as any).webkitRTCPeerConnection) === false ||
96 peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true' 93 peertubeLocalStorage.getItem(VideoWatchComponent.LOCAL_STORAGE_PRIVACY_CONCERN_KEY) === 'true'
97 ) { 94 ) {
98 this.hasAlreadyAcceptedPrivacyConcern = true 95 this.hasAlreadyAcceptedPrivacyConcern = true
@@ -118,8 +115,9 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
118 .subscribe(([ video, captionsResult ]) => { 115 .subscribe(([ video, captionsResult ]) => {
119 const startTime = this.route.snapshot.queryParams.start 116 const startTime = this.route.snapshot.queryParams.start
120 const subtitle = this.route.snapshot.queryParams.subtitle 117 const subtitle = this.route.snapshot.queryParams.subtitle
118 const playerMode = this.route.snapshot.queryParams.mode
121 119
122 this.onVideoFetched(video, captionsResult.data, { startTime, subtitle }) 120 this.onVideoFetched(video, captionsResult.data, { startTime, subtitle, playerMode })
123 .catch(err => this.handleError(err)) 121 .catch(err => this.handleError(err))
124 }) 122 })
125 }) 123 })
@@ -310,6 +308,10 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
310 return this.video && this.video.state.id === VideoState.TO_TRANSCODE 308 return this.video && this.video.state.id === VideoState.TO_TRANSCODE
311 } 309 }
312 310
311 isVideoDownloadable () {
312 return this.video && this.video.downloadEnabled
313 }
314
313 isVideoToImport () { 315 isVideoToImport () {
314 return this.video && this.video.state.id === VideoState.TO_IMPORT 316 return this.video && this.video.state.id === VideoState.TO_IMPORT
315 } 317 }
@@ -366,7 +368,11 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
366 ) 368 )
367 } 369 }
368 370
369 private async onVideoFetched (video: VideoDetails, videoCaptions: VideoCaption[], urlOptions: { startTime: number, subtitle: string }) { 371 private async onVideoFetched (
372 video: VideoDetails,
373 videoCaptions: VideoCaption[],
374 urlOptions: { startTime?: number, subtitle?: string, playerMode?: string }
375 ) {
370 this.video = video 376 this.video = video
371 377
372 // Re init attributes 378 // Re init attributes
@@ -402,41 +408,64 @@ export class VideoWatchComponent implements OnInit, OnDestroy {
402 src: environment.apiUrl + c.captionPath 408 src: environment.apiUrl + c.captionPath
403 })) 409 }))
404 410
405 const videojsOptions = getVideojsOptions({ 411 const options: PeertubePlayerManagerOptions = {
406 autoplay: this.isAutoplay(), 412 common: {
407 inactivityTimeout: 2500, 413 autoplay: this.isAutoplay(),
408 videoFiles: this.video.files, 414
409 videoCaptions: playerCaptions, 415 playerElement: this.playerElement,
410 playerElement: this.playerElement, 416 onPlayerElementChange: (element: HTMLVideoElement) => this.playerElement = element,
411 videoViewUrl: this.video.privacy.id !== VideoPrivacy.PRIVATE ? this.videoService.getVideoViewUrl(this.video.uuid) : null, 417
412 videoDuration: this.video.duration, 418 videoDuration: this.video.duration,
413 enableHotkeys: true, 419 enableHotkeys: true,
414 peertubeLink: false, 420 inactivityTimeout: 2500,
415 poster: this.video.previewUrl, 421 poster: this.video.previewUrl,
416 startTime, 422 startTime,
417 subtitle: urlOptions.subtitle, 423
418 theaterMode: true, 424 theaterMode: true,
419 language: this.localeId, 425 captions: videoCaptions.length !== 0,
420 426 peertubeLink: false,
421 userWatching: this.user && this.user.videosHistoryEnabled === true ? { 427
422 url: this.videoService.getUserWatchingVideoUrl(this.video.uuid), 428 videoViewUrl: this.video.privacy.id !== VideoPrivacy.PRIVATE ? this.videoService.getVideoViewUrl(this.video.uuid) : null,
423 authorizationHeader: this.authService.getRequestHeaderValue() 429 embedUrl: this.video.embedUrl,
424 } : undefined 430
425 }) 431 language: this.localeId,
432
433 subtitle: urlOptions.subtitle,
434
435 userWatching: this.user && this.user.videosHistoryEnabled === true ? {
436 url: this.videoService.getUserWatchingVideoUrl(this.video.uuid),
437 authorizationHeader: this.authService.getRequestHeaderValue()
438 } : undefined,
426 439
427 if (this.videojsLocaleLoaded === false) { 440 serverUrl: environment.apiUrl,
428 await loadLocaleInVideoJS(environment.apiUrl, videojs, isOnDevLocale() ? getDevLocale() : this.localeId) 441
429 this.videojsLocaleLoaded = true 442 videoCaptions: playerCaptions
443 },
444
445 webtorrent: {
446 videoFiles: this.video.files
447 }
430 } 448 }
431 449
432 const self = this 450 const mode: PlayerMode = urlOptions.playerMode === 'p2p-media-loader' ? 'p2p-media-loader' : 'webtorrent'
433 this.zone.runOutsideAngular(async () => { 451
434 videojs(this.playerElement, videojsOptions, function (this: videojs.Player) { 452 if (mode === 'p2p-media-loader') {
435 self.player = this 453 const hlsPlaylist = this.video.getHlsPlaylist()
436 this.on('customError', ({ err }: { err: any }) => self.handleError(err))
437 454
438 addContextMenu(self.player, self.video.embedUrl) 455 const p2pMediaLoader = {
439 }) 456 playlistUrl: hlsPlaylist.playlistUrl,
457 segmentsSha256Url: hlsPlaylist.segmentsSha256Url,
458 redundancyBaseUrls: hlsPlaylist.redundancies.map(r => r.baseUrl),
459 trackerAnnounce: this.video.trackerUrls,
460 videoFiles: this.video.files
461 } as P2PMediaLoaderOptions
462
463 Object.assign(options, { p2pMediaLoader })
464 }
465
466 this.zone.runOutsideAngular(async () => {
467 this.player = await PeertubePlayerManager.initialize(mode, options)
468 this.player.on('customError', ({ err }: { err: any }) => this.handleError(err))
440 }) 469 })
441 470
442 this.setVideoDescriptionHTML() 471 this.setVideoDescriptionHTML()