import { VideoCaptionService } from '@app/shared/video-caption'
import { MarkdownService } from '@app/shared/renderer'
import {
+ videojs,
CustomizationOptions,
P2PMediaLoaderOptions,
PeertubePlayerManager,
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',
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
remoteServerDown = false
hotkeys: Hotkey[]
+ private nextVideoUuid = ''
private currentTime: number
private paramsSub: Subscription
private queryParamsSub: Subscription
private i18n: I18n,
private hotkeysService: HotkeysService,
private hooks: HooksService,
+ private location: PlatformLocation,
@Inject(LOCALE_ID) private localeId: string
) {}
}
async ngOnInit () {
- this.pluginService.loadPluginsByScope('video-watch')
-
this.configSub = this.serverService.configLoaded
.subscribe(() => {
if (
this.theaterEnabled = getStoredTheater()
- this.hooks.runAction('action:video-watch.init')
+ this.hooks.runAction('action:video-watch.init', 'video-watch')
}
ngOnDestroy () {
}
showSupportModal () {
+ this.pausePlayer()
+
this.videoSupportModal.show()
}
showShareModal () {
+ this.pausePlayer()
+
this.videoShareModal.show(this.currentTime)
}
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()
}
)
// Video did change
- forkJoin(
+ 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 ]))
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'
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))
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())
}
})
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()
this.setOpenGraphTags()
this.checkUserRating()
- this.hooks.runAction('action:video-watch.video.loaded')
+ 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) {
]
if (this.isUserLoggedIn()) this.hotkeysService.add(this.hotkeys)
}
+
+ private pausePlayer () {
+ if (!this.player) return
+
+ this.player.pause()
+ }
}