import { Component, ElementRef, NgZone, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { ActivatedRoute } from '@angular/router'; import { MetaService } from 'ng2-meta'; import * as videojs from 'video.js'; import { AuthService } from '../../core'; import { VideoMagnetComponent } from './video-magnet.component'; import { VideoShareComponent } from './video-share.component'; import { VideoReportComponent } from './video-report.component'; import { Video, VideoService } from '../shared'; import { WebTorrentService } from './webtorrent.service'; @Component({ selector: 'my-video-watch', templateUrl: './video-watch.component.html', styleUrls: [ './video-watch.component.scss' ] }) export class VideoWatchComponent implements OnInit, OnDestroy { private static LOADTIME_TOO_LONG: number = 20000; @ViewChild('videoMagnetModal') videoMagnetModal: VideoMagnetComponent; @ViewChild('videoShareModal') videoShareModal: VideoShareComponent; @ViewChild('videoReportModal') videoReportModal: VideoReportComponent; downloadSpeed: number; error: boolean = false; loading: boolean = false; numPeers: number; player: VideoJSPlayer; playerElement: Element; uploadSpeed: number; video: Video = null; videoNotFound = false; private errorTimer: number; private sub: any; private torrentInfosInterval: number; constructor( private elementRef: ElementRef, private ngZone: NgZone, private route: ActivatedRoute, private videoService: VideoService, private metaService: MetaService, private webTorrentService: WebTorrentService, private authService: AuthService ) {} ngOnInit() { this.sub = this.route.params.subscribe(routeParams => { let id = routeParams['id']; this.videoService.getVideo(id).subscribe( video => { this.video = video; this.setOpenGraphTags(); this.loadVideo(); }, error => { this.videoNotFound = true; } ); }); this.playerElement = this.elementRef.nativeElement.querySelector('#video-container'); const videojsOptions = { controls: true, autoplay: false }; const self = this; videojs(this.playerElement, videojsOptions, function () { self.player = this; }); } ngOnDestroy() { // Remove WebTorrent stuff console.log('Removing video from webtorrent.'); window.clearInterval(this.torrentInfosInterval); window.clearTimeout(this.errorTimer); if (this.video !== null) { this.webTorrentService.remove(this.video.magnetUri); } // Remove player videojs(this.playerElement).dispose(); // Unsubscribe route subscription this.sub.unsubscribe(); } loadVideo() { // Reset the error this.error = false; // We are loading the video this.loading = true; console.log('Adding ' + this.video.magnetUri + '.'); // The callback might never return if there are network issues // So we create a timer to inform the user the load is abnormally long this.errorTimer = window.setTimeout(() => this.loadTooLong(), VideoWatchComponent.LOADTIME_TOO_LONG); this.webTorrentService.add(this.video.magnetUri, (torrent) => { // Clear the error timer window.clearTimeout(this.errorTimer); // Maybe the error was fired by the timer, so reset it this.error = false; // We are not loading the video anymore this.loading = false; console.log('Added ' + this.video.magnetUri + '.'); torrent.files[0].renderTo(this.playerElement, { autoplay: true }, (err) => { if (err) { alert('Cannot append the file.'); console.error(err); } }); this.runInProgress(torrent); }); } showReportModal(event: Event) { event.preventDefault(); this.videoReportModal.show(); } showShareModal() { this.videoShareModal.show(); } showMagnetUriModal() { this.videoMagnetModal.show(); } isUserLoggedIn() { return this.authService.isLoggedIn(); } private loadTooLong() { this.error = true; console.error('The video load seems to be abnormally long.'); } private setOpenGraphTags() { this.metaService.setTag('og:type', 'video'); this.metaService.setTag('og:title', this.video.name); this.metaService.setTag('name', this.video.name); this.metaService.setTag('og:description', this.video.description); this.metaService.setTag('description', this.video.description); this.metaService.setTag('og:image', this.video.thumbnailPath); this.metaService.setTag('og:duration', this.video.duration); this.metaService.setTag('og:site_name', 'PeerTube'); this.metaService.setTag('og:url', window.location.href); this.metaService.setTag('url', window.location.href); } private runInProgress(torrent: any) { // Refresh each second this.torrentInfosInterval = window.setInterval(() => { this.ngZone.run(() => { this.downloadSpeed = torrent.downloadSpeed; this.numPeers = torrent.numPeers; this.uploadSpeed = torrent.uploadSpeed; }); }, 1000); } }