mirror of
				https://github.com/zoriya/Kyoo.git
				synced 2025-10-31 10:37:13 -04:00 
			
		
		
		
	Starting to clean up the player
This commit is contained in:
		
							parent
							
								
									de8fed8694
								
							
						
					
					
						commit
						2b8c527fdf
					
				| @ -18,6 +18,8 @@ export class AppComponent | |||||||
| 	libraries: Library[]; | 	libraries: Library[]; | ||||||
| 	isLoading: boolean = false; | 	isLoading: boolean = false; | ||||||
| 
 | 
 | ||||||
|  | 	static isMobile: boolean = false; | ||||||
|  | 
 | ||||||
| 	constructor(private libraryService: LibraryService, | 	constructor(private libraryService: LibraryService, | ||||||
| 	            private router: Router, | 	            private router: Router, | ||||||
| 	            private location: Location, | 	            private location: Location, | ||||||
| @ -47,7 +49,8 @@ export class AppComponent | |||||||
| 			} | 			} | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		if (!navigator.userAgent.match(/Mobi/)) | 		AppComponent.isMobile = !!navigator.userAgent.match(/Mobi/); | ||||||
|  | 		if (!AppComponent.isMobile) | ||||||
| 			document.body.classList.add("hoverEnabled"); | 			document.body.classList.add("hoverEnabled"); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -1,6 +1,14 @@ | |||||||
| <div id="root"> | <div id="root"> | ||||||
| 	<div class="player data-vjs-player"> | 	<div class="player data-vjs-player"> | ||||||
| 		<video id="player" poster="backdrop/{{this.item.showSlug}}" autoplay muted (click)="videoClicked()"> | 		<video id="player" | ||||||
|  | 		       poster="backdrop/{{this.item.showSlug}}" | ||||||
|  | 		       autoplay muted | ||||||
|  | 		       (click)="this.videoClicked()" | ||||||
|  | 		       (play)="this.playing = true" | ||||||
|  | 		       (pause)="this.playing = false" | ||||||
|  | 		       (ended)="this.next()" | ||||||
|  | 		       [volume]="this.volume / 100" | ||||||
|  | 		       [muted]="this.muted"> | ||||||
| 		</video> | 		</video> | ||||||
| 	</div> | 	</div> | ||||||
| 
 | 
 | ||||||
| @ -8,25 +16,41 @@ | |||||||
| 		<div class="spinner-border align-self-center" role="status"></div> | 		<div class="spinner-border align-self-center" role="status"></div> | ||||||
| 	</div> | 	</div> | ||||||
| 
 | 
 | ||||||
| 	<mat-card class="d-none w-25 m-5" [ngClass]="{'d-block': this.displayStats}"> | 	<mat-card class="d-none w-25 m-5 stats" [ngClass]="{'d-block': this.displayStats}"> | ||||||
| 		<mat-card-header style="margin-bottom: 0.5rem;"> | 		<mat-card-header> | ||||||
| 			<h4 style="align-self: center; margin-bottom: 0;">Stats</h4> | 			<h4>Stats</h4> | ||||||
| 			<div style="flex: 1 1 auto"></div> | 			<div style="flex: 1 1 auto"></div> | ||||||
| 			<button mat-icon-button aria-label="Close" (click)="this.displayStats = false" style="outline: none;"> | 			<button mat-icon-button aria-label="Close" (click)="this.displayStats = false"> | ||||||
| 				<mat-icon>close</mat-icon> | 				<mat-icon>close</mat-icon> | ||||||
| 			</button> | 			</button> | ||||||
| 		</mat-card-header> | 		</mat-card-header> | ||||||
| 		<mat-card-content> | 		<mat-card-content> | ||||||
| 			Play method: <span style="float: right">{{this.playMethod}}</span> | 			Play method: <span>{{this.playMethod}}</span> | ||||||
| 			<br /> | 			<br /> | ||||||
| 			<br /> | 			<br /> | ||||||
| 			Video Container: <span style="float: right">{{this.item.container}} <i class="material-icons" style="vertical-align: middle; font-size: 14px">{{getSupportedFeature("container")}}</i></span> | 			Video Container: | ||||||
|  | 			<span> | ||||||
|  | 				{{this.item.container}} | ||||||
|  | 				<i class="material-icons">{{getSupportedFeature("container")}}</i> | ||||||
|  | 			</span> | ||||||
| 			<br /> | 			<br /> | ||||||
| 			Video Codec: <span style="float: right">{{this.item.video.codec}} <i class="material-icons" style="vertical-align: middle; font-size: 14px">{{getSupportedFeature("video")}}</i></span> | 			Video Codec: | ||||||
|  | 			<span> | ||||||
|  | 				{{this.item.video.codec}} | ||||||
|  | 				<i class="material-icons">{{getSupportedFeature("video")}}</i> | ||||||
|  | 			</span> | ||||||
| 			<br /> | 			<br /> | ||||||
| 			Audio Codec: <span style="float: right">{{this.item.audios[0].codec}} <i class="material-icons" style="vertical-align: middle; font-size: 14px">{{getSupportedFeature("audio")}}</i></span> | 			Audio Codec: | ||||||
|  | 			<span> | ||||||
|  | 				{{this.item.audios[0].codec}} | ||||||
|  | 				<i class="material-icons">{{getSupportedFeature("audio")}}</i> | ||||||
|  | 			</span> | ||||||
| 			<br /> | 			<br /> | ||||||
| 			Subtitle Codec: <span style="float: right">{{this.selectedSubtitle ? this.selectedSubtitle.codec : "none"}} <i class="material-icons" style="vertical-align: middle; font-size: 14px">{{getSupportedFeature("subtitle")}}</i></span> | 			Subtitle Codec: | ||||||
|  | 			<span> | ||||||
|  | 				{{this.selectedSubtitle ? this.selectedSubtitle.codec : "none"}} | ||||||
|  | 				<i class="material-icons">{{getSupportedFeature("subtitle")}}</i> | ||||||
|  | 			</span> | ||||||
| 			<br /> | 			<br /> | ||||||
| 		</mat-card-content> | 		</mat-card-content> | ||||||
| 	</mat-card> | 	</mat-card> | ||||||
| @ -60,8 +84,10 @@ | |||||||
| 						<a *ngIf="this.item.previousEpisode" mat-icon-button matTooltipPosition="above" matTooltip="Previous" (click)="previous()"> | 						<a *ngIf="this.item.previousEpisode" mat-icon-button matTooltipPosition="above" matTooltip="Previous" (click)="previous()"> | ||||||
| 							<mat-icon>skip_previous</mat-icon> | 							<mat-icon>skip_previous</mat-icon> | ||||||
| 						</a> | 						</a> | ||||||
| 						<button mat-icon-button matTooltipPosition="above" [matTooltip]="playTooltip" id="play" (click)="tooglePlayback()"> | 						<button mat-icon-button matTooltipPosition="above" id="play" | ||||||
| 							<mat-icon>{{this.playIcon}}</mat-icon> | 						        [matTooltip]="this.playing ? 'Pause' : 'Play'" | ||||||
|  | 						        (click)="togglePlayback()"> | ||||||
|  | 							<mat-icon>{{this.playing ? 'pause' : 'play_arrow'}}</mat-icon> | ||||||
| 						</button> | 						</button> | ||||||
| 						<a mat-icon-button id="nextBtn" *ngIf="this.item.nextEpisode" (click)="next()"> | 						<a mat-icon-button id="nextBtn" *ngIf="this.item.nextEpisode" (click)="next()"> | ||||||
| 							<mat-icon>skip_next</mat-icon> | 							<mat-icon>skip_next</mat-icon> | ||||||
| @ -76,13 +102,15 @@ | |||||||
| 								</div> | 								</div> | ||||||
| 							</div> | 							</div> | ||||||
| 						</a> | 						</a> | ||||||
| 						<div id="volume"> | 						<div id="volume" [ngClass]="{'d-none': this.isMobile}"> | ||||||
| 							<button mat-icon-button matTooltipPosition="above" matTooltip="Volume" (click)="toogleMute()"> | 							<button mat-icon-button matTooltipPosition="above" matTooltip="Volume" | ||||||
| 								<mat-icon>{{this.volumeIcon}}</mat-icon> | 							        (click)="this.muted = !this.muted"> | ||||||
|  | 								<mat-icon>{{this.getVolumeBtn()}}</mat-icon> | ||||||
| 							</button> | 							</button> | ||||||
| 
 | 
 | ||||||
| 							<mat-slider [value]="volume" (input)="changeVolume($event.value)"></mat-slider> | 							<mat-slider [value]="this.volume" (input)="this.volume = $event.value"></mat-slider> | ||||||
| 						</div> | 						</div> | ||||||
|  | 						<!-- TODO REWORK THIS DUMPSTER FIRE OF A TIMER. --> | ||||||
| 						<p *ngIf="this.maxHours; else elseBlock">{{this.hours | number: '2.0-0'}}:{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxHours | number: '2.0-0'}}:{{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p> | 						<p *ngIf="this.maxHours; else elseBlock">{{this.hours | number: '2.0-0'}}:{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxHours | number: '2.0-0'}}:{{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p> | ||||||
| 						<ng-template #elseBlock><p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p></ng-template> | 						<ng-template #elseBlock><p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p></ng-template> | ||||||
| 					</div> | 					</div> | ||||||
| @ -90,7 +118,8 @@ | |||||||
| 						<button id="volume" *ngIf="this.item.audios.length > 1" mat-icon-button matTooltipPosition="above" matTooltip="Select audio track"> | 						<button id="volume" *ngIf="this.item.audios.length > 1" mat-icon-button matTooltipPosition="above" matTooltip="Select audio track"> | ||||||
| 							<mat-icon>music_note</mat-icon> | 							<mat-icon>music_note</mat-icon> | ||||||
| 						</button> | 						</button> | ||||||
| 						<button *ngIf="this.item.subtitles.length > 0" mat-icon-button [matMenuTriggerFor]="subtitles" matTooltipPosition="above" matTooltip="Select subtitle track"> | 						<button *ngIf="this.item.subtitles.length > 0" mat-icon-button [matMenuTriggerFor]="subtitles" | ||||||
|  | 						        matTooltipPosition="above" matTooltip="Select subtitle track"> | ||||||
| 							<mat-icon>closed_caption</mat-icon> | 							<mat-icon>closed_caption</mat-icon> | ||||||
| 						</button> | 						</button> | ||||||
| 						<button mat-icon-button matTooltipPosition="above" matTooltip="Cast"> | 						<button mat-icon-button matTooltipPosition="above" matTooltip="Cast"> | ||||||
| @ -99,8 +128,11 @@ | |||||||
| 						<button mat-icon-button matTooltipPosition="above" [matMenuTriggerFor]="settings" matTooltip="Settings"> | 						<button mat-icon-button matTooltipPosition="above" [matMenuTriggerFor]="settings" matTooltip="Settings"> | ||||||
| 							<mat-icon>settings</mat-icon> | 							<mat-icon>settings</mat-icon> | ||||||
| 						</button> | 						</button> | ||||||
| 						<button mat-icon-button matTooltipPosition="above" [matTooltip]="fullscreenTooltip" id="fullscreen" (click)="fullscreen()"> | 						<button mat-icon-button matTooltipPosition="above" | ||||||
| 							<mat-icon>{{fullscreenIcon}}</mat-icon> | 						        [ngClass]="{'d-none': this.isMobile}" | ||||||
|  | 						        [matTooltip]="this.isFullScreen ? 'Exit fullscreen' : 'Fullscreen'" | ||||||
|  | 						        (click)="fullscreen()"> | ||||||
|  | 							<mat-icon>{{this.isFullScreen ? "fullscreen_exit" : "fullscreen"}}</mat-icon> | ||||||
| 						</button> | 						</button> | ||||||
| 					</div> | 					</div> | ||||||
| 				</div> | 				</div> | ||||||
| @ -113,7 +145,10 @@ | |||||||
| 					</button> | 					</button> | ||||||
| 
 | 
 | ||||||
| 					<div *ngFor="let subtitle of this.item.subtitles"> | 					<div *ngFor="let subtitle of this.item.subtitles"> | ||||||
| 						<button [ngClass]="{'selected': this.selectedSubtitle == subtitle}" mat-menu-item *ngIf="subtitle.codec == 'ass' || subtitle.codec == 'subrip'; else elseBlock" (click)="selectSubtitle(subtitle)"> | 						<button [ngClass]="{'selected': this.selectedSubtitle == subtitle}" | ||||||
|  | 						        mat-menu-item *ngIf="subtitle.codec === 'ass' || subtitle.codec === 'subrip'; | ||||||
|  | 						                             else elseBlock" | ||||||
|  | 						        (click)="selectSubtitle(subtitle)"> | ||||||
| 							<span>{{subtitle.displayName}}</span> | 							<span>{{subtitle.displayName}}</span> | ||||||
| 						</button> | 						</button> | ||||||
| 
 | 
 | ||||||
|  | |||||||
| @ -51,8 +51,7 @@ | |||||||
| 
 | 
 | ||||||
| 	> h5 | 	> h5 | ||||||
| 	{ | 	{ | ||||||
| 		margin: 0; | 		margin: 0 0 0 .5rem; | ||||||
| 		margin-left: .5rem; |  | ||||||
| 		align-self: center; | 		align-self: center; | ||||||
| 	} | 	} | ||||||
| } | } | ||||||
| @ -104,8 +103,7 @@ | |||||||
| 
 | 
 | ||||||
| 					> p | 					> p | ||||||
| 					{ | 					{ | ||||||
| 						margin: 0; | 						margin: 0 0 0 1rem; | ||||||
| 						margin-left: 1rem; |  | ||||||
| 						align-self: center; | 						align-self: center; | ||||||
| 					} | 					} | ||||||
| 				} | 				} | ||||||
| @ -288,8 +286,8 @@ | |||||||
| 
 | 
 | ||||||
| 	> mat-slider | 	> mat-slider | ||||||
| 	{ | 	{ | ||||||
| 		width: 0px; | 		width: 0; | ||||||
| 		min-width: 0px; | 		min-width: 0; | ||||||
| 		padding: 0; | 		padding: 0; | ||||||
| 		height: 40px; | 		height: 40px; | ||||||
| 		overflow: hidden; | 		overflow: hidden; | ||||||
| @ -331,7 +329,7 @@ | |||||||
| 
 | 
 | ||||||
| .volume | .volume | ||||||
| { | { | ||||||
| 	min-width: 0px !important; | 	min-width: 0 !important; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| .info-panel | .info-panel | ||||||
| @ -339,3 +337,30 @@ | |||||||
| 	min-width: 250px !important; | 	min-width: 250px !important; | ||||||
| 	max-width: 300px !important; | 	max-width: 300px !important; | ||||||
| } | } | ||||||
|  | 
 | ||||||
|  | .stats | ||||||
|  | { | ||||||
|  | 	> mat-card-header | ||||||
|  | 	{ | ||||||
|  | 		margin-bottom: 0.5rem; | ||||||
|  | 
 | ||||||
|  | 		> h4 | ||||||
|  | 		{ | ||||||
|  | 			align-self: center; | ||||||
|  | 			margin-bottom: 0; | ||||||
|  | 		} | ||||||
|  | 		> button | ||||||
|  | 		{ | ||||||
|  | 			outline: none; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | 	> mat-card-content > span | ||||||
|  | 	{ | ||||||
|  | 		float: right; | ||||||
|  | 		> i | ||||||
|  | 		{ | ||||||
|  | 			vertical-align: middle; | ||||||
|  | 			font-size: 14px; | ||||||
|  | 		} | ||||||
|  | 	} | ||||||
|  | } | ||||||
|  | |||||||
| @ -1,26 +1,34 @@ | |||||||
| import {Component, Injector, OnInit, ViewEncapsulation} from '@angular/core'; | import { Component, Injector, OnInit, ViewEncapsulation } from "@angular/core"; | ||||||
| import {MatSnackBar} from "@angular/material/snack-bar"; | import { MatSnackBar } from "@angular/material/snack-bar"; | ||||||
| import {DomSanitizer, Title} from "@angular/platform-browser"; | import { DomSanitizer, Title } from "@angular/platform-browser"; | ||||||
| import {ActivatedRoute, Event, NavigationCancel, NavigationEnd, NavigationStart, Router} from "@angular/router"; | import { ActivatedRoute, Event, NavigationCancel, NavigationEnd, NavigationStart, Router } from "@angular/router"; | ||||||
| import {Track, WatchItem} from "../../models/watch-item"; | import { AppComponent } from "../../app.component"; | ||||||
| import {Location} from "@angular/common"; | import { Track, WatchItem } from "../../models/watch-item"; | ||||||
|  | import { Location } from "@angular/common"; | ||||||
|  | import { getPlaybackMethod, getWhatIsSupported, method, SupportList } from "../../../videoSupport/playbackMethodDetector"; | ||||||
|  | import { OidcSecurityService } from "angular-auth-oidc-client"; | ||||||
| import * as Hls from "hls.js" | import * as Hls from "hls.js" | ||||||
| import {getPlaybackMethod, getWhatIsSupported, method, SupportList} from "../../../videoSupport/playbackMethodDetector"; |  | ||||||
| import {OidcSecurityService} from "angular-auth-oidc-client"; |  | ||||||
| 
 | 
 | ||||||
| declare var SubtitleManager: any; | declare var SubtitleManager: any; | ||||||
| 
 | 
 | ||||||
| @Component({ | @Component({ | ||||||
| 	selector: 'app-player', | 	selector: "app-player", | ||||||
| 	templateUrl: './player.component.html', | 	templateUrl: "./player.component.html", | ||||||
| 	styleUrls: ['./player.component.scss'], | 	styleUrls: ["./player.component.scss"], | ||||||
| 	encapsulation: ViewEncapsulation.None | 	encapsulation: ViewEncapsulation.None | ||||||
| }) | }) | ||||||
| export class PlayerComponent implements OnInit | export class PlayerComponent implements OnInit | ||||||
| { | { | ||||||
| 	item: WatchItem; | 	item: WatchItem; | ||||||
|  | 	playing: boolean = true; | ||||||
|  | 	muted: boolean = false; | ||||||
|  | 
 | ||||||
|  | 	private _volume: number = 100; | ||||||
|  | 	get volume(): number { return this._volume; } | ||||||
|  | 	set volume(value: number) { this._volume = Math.max(0, Math.min(value, 100)); } | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| 
 | 
 | ||||||
| 	volume: number = 100; |  | ||||||
| 	seeking: boolean = false; | 	seeking: boolean = false; | ||||||
| 	videoHider; | 	videoHider; | ||||||
| 	controllerHovered: boolean = false; | 	controllerHovered: boolean = false; | ||||||
| @ -34,13 +42,6 @@ export class PlayerComponent implements OnInit | |||||||
| 	maxMinutes: number; | 	maxMinutes: number; | ||||||
| 	maxSeconds: number; | 	maxSeconds: number; | ||||||
| 
 | 
 | ||||||
| 	playIcon: string = "pause"; //Icon used by the play btn.
 |  | ||||||
| 	volumeIcon: string = "volume_up"; //Icon used by the volume btn.
 |  | ||||||
| 	fullscreenIcon: string = "fullscreen"; //Icon used by the fullscreen btn.
 |  | ||||||
| 
 |  | ||||||
| 	playTooltip: string = "Pause"; //Text used in the play tooltip
 |  | ||||||
| 	fullscreenTooltip: string = "Fullscreen"; //Text used in the fullscreen tooltip
 |  | ||||||
| 
 |  | ||||||
| 	playMethod: method = method.direct; | 	playMethod: method = method.direct; | ||||||
| 	methodType = method; | 	methodType = method; | ||||||
| 
 | 
 | ||||||
| @ -56,7 +57,14 @@ export class PlayerComponent implements OnInit | |||||||
| 
 | 
 | ||||||
| 	private oidcSecurity: OidcSecurityService; | 	private oidcSecurity: OidcSecurityService; | ||||||
| 
 | 
 | ||||||
| 	constructor(private route: ActivatedRoute, private sanitizer: DomSanitizer, private snackBar: MatSnackBar, private title: Title, private router: Router, private location: Location, private injector: Injector) { } | 	constructor(private route: ActivatedRoute, | ||||||
|  | 	            private sanitizer: DomSanitizer, | ||||||
|  | 	            private snackBar: MatSnackBar, | ||||||
|  | 	            private title: Title, | ||||||
|  | 	            private router: Router, | ||||||
|  | 	            private location: Location, | ||||||
|  | 	            private injector: Injector) | ||||||
|  | 	{ } | ||||||
| 
 | 
 | ||||||
| 	ngOnInit() | 	ngOnInit() | ||||||
| 	{ | 	{ | ||||||
| @ -64,27 +72,21 @@ export class PlayerComponent implements OnInit | |||||||
| 		this.route.data.subscribe((data) => | 		this.route.data.subscribe((data) => | ||||||
| 		{ | 		{ | ||||||
| 			this.item = data.item; | 			this.item = data.item; | ||||||
| 			this.item.duration = 20 * 60; |  | ||||||
| 
 | 
 | ||||||
| 			if (this.player) | 			if (this.player) | ||||||
| 			{ |  | ||||||
| 				this.player.load(); | 				this.player.load(); | ||||||
| 				this.initPlayBtn(); |  | ||||||
| 			} |  | ||||||
| 
 | 
 | ||||||
| 			this.setDuration(this.item.duration); | 			this.setDuration(this.item.duration); | ||||||
| 
 | 
 | ||||||
| 			if (this.item.isMovie) | 			if (this.item.isMovie) | ||||||
| 				this.title.setTitle(this.item.showTitle + " - Kyoo"); | 				this.title.setTitle(`${this.item.showTitle} - Kyoo`); | ||||||
| 			else | 			else | ||||||
| 				this.title.setTitle(this.item.showTitle + " S" + this.item.seasonNumber + ":E" + this.item.episodeNumber + " - Kyoo"); | 				this.title.setTitle(`${this.item.showTitle} S${this.item.seasonNumber}:E${this.item.episodeNumber} - Kyoo`); | ||||||
| 
 | 
 | ||||||
| 			if (navigator.userAgent.match(/Mobi/) && document.fullscreenElement == null) | 			if (AppComponent.isMobile && !this.isFullScreen) | ||||||
| 			{ | 			{ | ||||||
| 				this.fullscreen(); | 				this.fullscreen(); | ||||||
| 				screen.orientation.lock("landscape"); | 				screen.orientation.lock("landscape"); | ||||||
| 				$("#fullscreen").addClass("d-none"); |  | ||||||
| 				$("#volume").addClass("d-none"); |  | ||||||
| 			} | 			} | ||||||
| 			setTimeout(() => | 			setTimeout(() => | ||||||
| 			{ | 			{ | ||||||
| @ -94,24 +96,22 @@ export class PlayerComponent implements OnInit | |||||||
| 		}); | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | 	get isFullScreen(): boolean | ||||||
|  | 	{ | ||||||
|  | 		return document.fullscreenElement != null; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
|  | 	get isMobile(): boolean | ||||||
|  | 	{ | ||||||
|  | 		return AppComponent.isMobile; | ||||||
|  | 	} | ||||||
|  | 
 | ||||||
| 	ngAfterViewInit() | 	ngAfterViewInit() | ||||||
| 	{ | 	{ | ||||||
| 		this.player = document.getElementById("player") as HTMLVideoElement; | 		this.player = document.getElementById("player") as HTMLVideoElement; | ||||||
| 		this.thumb = document.getElementById("thumb") as HTMLElement; | 		this.thumb = document.getElementById("thumb") as HTMLElement; | ||||||
| 		this.progress = document.getElementById("progress") as HTMLElement; | 		this.progress = document.getElementById("progress") as HTMLElement; | ||||||
| 		this.buffered = document.getElementById("buffered") as HTMLElement; | 		this.buffered = document.getElementById("buffered") as HTMLElement; | ||||||
| 		this.player.controls = false; |  | ||||||
| 
 |  | ||||||
| 		this.player.onplay = () => |  | ||||||
| 		{ |  | ||||||
| 			this.initPlayBtn(); |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		this.player.onpause = () => |  | ||||||
| 		{ |  | ||||||
| 			this.playIcon = "play_arrow"; |  | ||||||
| 			this.playTooltip = "Play"; |  | ||||||
| 		}; |  | ||||||
| 
 | 
 | ||||||
| 		this.player.ontimeupdate = () => | 		this.player.ontimeupdate = () => | ||||||
| 		{ | 		{ | ||||||
| @ -139,16 +139,11 @@ export class PlayerComponent implements OnInit | |||||||
| 			loadIndicator.classList.add("d-none"); | 			loadIndicator.classList.add("d-none"); | ||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		this.player.onended = () => |  | ||||||
| 		{ |  | ||||||
| 			this.next(); |  | ||||||
| 		}; |  | ||||||
| 
 |  | ||||||
| 		this.player.onerror = () => | 		this.player.onerror = () => | ||||||
| 		{ | 		{ | ||||||
| 			if (this.playMethod == method.transcode) | 			if (this.playMethod == method.transcode) | ||||||
| 			{ | 			{ | ||||||
| 				this.snackBar.open("This episode can't be played.", null, { horizontalPosition: "left", panelClass: ['snackError'], duration: 10000 }); | 				this.snackBar.open("This episode can't be played.", null, { horizontalPosition: "left", panelClass: ["snackError"], duration: 10000 }); | ||||||
| 			} | 			} | ||||||
| 			else | 			else | ||||||
| 			{ | 			{ | ||||||
| @ -277,20 +272,6 @@ export class PlayerComponent implements OnInit | |||||||
| 				if (document.fullscreenElement == null && this.router.url.startsWith("/watch")) | 				if (document.fullscreenElement == null && this.router.url.startsWith("/watch")) | ||||||
| 					this.back(); | 					this.back(); | ||||||
| 			} | 			} | ||||||
| 			else |  | ||||||
| 			{ |  | ||||||
| 				if (document.fullscreenElement != null) |  | ||||||
| 				{ |  | ||||||
| 					this.fullscreenIcon = "fullscreen_exit"; |  | ||||||
| 					this.fullscreenTooltip = "Exit fullscreen"; |  | ||||||
| 				} |  | ||||||
| 				else |  | ||||||
| 				{ |  | ||||||
| 					this.fullscreenIcon = "fullscreen"; |  | ||||||
| 					this.fullscreenTooltip = "Fullscreen"; |  | ||||||
| 				} |  | ||||||
| 			} |  | ||||||
| 
 |  | ||||||
| 		}); | 		}); | ||||||
| 
 | 
 | ||||||
| 		$(window).keydown((e) => | 		$(window).keydown((e) => | ||||||
| @ -298,15 +279,15 @@ export class PlayerComponent implements OnInit | |||||||
| 			switch (e.keyCode) | 			switch (e.keyCode) | ||||||
| 			{ | 			{ | ||||||
| 				case 32: //space
 | 				case 32: //space
 | ||||||
| 					this.tooglePlayback(); | 					this.togglePlayback(); | ||||||
| 					break; | 					break; | ||||||
| 
 | 
 | ||||||
| 				case 38: //Key up
 | 				case 38: //Key up
 | ||||||
| 					this.changeVolume(this.volume + 5); | 					this.volume += 5; | ||||||
| 					this.snackBar.open(this.volume + "%", null, { verticalPosition: "top", horizontalPosition: "right", duration: 300, panelClass: "volume" }); | 					this.snackBar.open(this.volume + "%", null, { verticalPosition: "top", horizontalPosition: "right", duration: 300, panelClass: "volume" }); | ||||||
| 					break; | 					break; | ||||||
| 				case 40: //Key down
 | 				case 40: //Key down
 | ||||||
| 					this.changeVolume(this.volume - 5); | 					this.volume += 5; | ||||||
| 					this.snackBar.open(this.volume + "%", null, { verticalPosition: "top", horizontalPosition: "right", duration: 300, panelClass: "volume" }); | 					this.snackBar.open(this.volume + "%", null, { verticalPosition: "top", horizontalPosition: "right", duration: 300, panelClass: "volume" }); | ||||||
| 					break; | 					break; | ||||||
| 
 | 
 | ||||||
| @ -326,7 +307,7 @@ export class PlayerComponent implements OnInit | |||||||
| 					break; | 					break; | ||||||
| 
 | 
 | ||||||
| 				case 77: //M key
 | 				case 77: //M key
 | ||||||
| 					this.toogleMute(); | 					this.muted = !this.muted; | ||||||
| 					if (this.player.muted) | 					if (this.player.muted) | ||||||
| 						this.snackBar.open("Sound muted.", null, { verticalPosition: "top", horizontalPosition: "right", duration: 750, panelClass: "info-panel" }); | 						this.snackBar.open("Sound muted.", null, { verticalPosition: "top", horizontalPosition: "right", duration: 750, panelClass: "info-panel" }); | ||||||
| 					else | 					else | ||||||
| @ -351,16 +332,12 @@ export class PlayerComponent implements OnInit | |||||||
| 			switch (true) | 			switch (true) | ||||||
| 			{ | 			{ | ||||||
| 				case event instanceof NavigationStart: | 				case event instanceof NavigationStart: | ||||||
| 					{ | 					loadIndicator.classList.remove("d-none"); | ||||||
| 						loadIndicator.classList.remove("d-none"); | 					break; | ||||||
| 						break; |  | ||||||
| 					} |  | ||||||
| 				case event instanceof NavigationEnd: | 				case event instanceof NavigationEnd: | ||||||
| 				case event instanceof NavigationCancel: | 				case event instanceof NavigationCancel: | ||||||
| 					{ | 					loadIndicator.classList.add("d-none"); | ||||||
| 						loadIndicator.classList.add("d-none"); | 					break; | ||||||
| 						break; |  | ||||||
| 					} |  | ||||||
| 				default: | 				default: | ||||||
| 					break; | 					break; | ||||||
| 			} | 			} | ||||||
| @ -395,7 +372,12 @@ export class PlayerComponent implements OnInit | |||||||
| 
 | 
 | ||||||
| 		setTimeout(() => | 		setTimeout(() => | ||||||
| 		{ | 		{ | ||||||
| 			this.snackBar.open("Playing: " + this.item.showTitle + " S" + this.item.seasonNumber + ":E" + this.item.episodeNumber, null, { verticalPosition: "top", horizontalPosition: "right", duration: 2000, panelClass: "info-panel" }); | 			this.snackBar.open(`Playing: ${this.item.showTitle} S${this.item.seasonNumber}:E${this.item.episodeNumber}`, null, { | ||||||
|  | 				verticalPosition: "top", | ||||||
|  | 				horizontalPosition: "right", | ||||||
|  | 				duration: 2000, | ||||||
|  | 				panelClass: "info-panel" | ||||||
|  | 			}); | ||||||
| 		}, 750); | 		}, 750); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| @ -405,7 +387,7 @@ export class PlayerComponent implements OnInit | |||||||
| 
 | 
 | ||||||
| 		if (this.oidcSecurity === undefined) | 		if (this.oidcSecurity === undefined) | ||||||
| 			this.oidcSecurity = this.injector.get(OidcSecurityService); | 			this.oidcSecurity = this.injector.get(OidcSecurityService); | ||||||
| 		this.hlsPlayer.config.xhrSetup = (xhr, url) => | 		this.hlsPlayer.config.xhrSetup = xhr => | ||||||
| 		{ | 		{ | ||||||
| 			const token = this.oidcSecurity.getToken(); | 			const token = this.oidcSecurity.getToken(); | ||||||
| 			if (token) | 			if (token) | ||||||
| @ -413,9 +395,7 @@ export class PlayerComponent implements OnInit | |||||||
| 		}; | 		}; | ||||||
| 
 | 
 | ||||||
| 		if (this.playMethod == method.direct) | 		if (this.playMethod == method.direct) | ||||||
| 		{ | 			this.player.src = `/video/${this.item.slug}`; | ||||||
| 			this.player.src = "/video/" + this.item.slug; |  | ||||||
| 		} |  | ||||||
| 		else if (this.playMethod == method.transmux) | 		else if (this.playMethod == method.transmux) | ||||||
| 		{ | 		{ | ||||||
| 			this.hlsPlayer.loadSource("/video/transmux/" + this.item.slug + "/"); | 			this.hlsPlayer.loadSource("/video/transmux/" + this.item.slug + "/"); | ||||||
| @ -438,19 +418,25 @@ export class PlayerComponent implements OnInit | |||||||
| 
 | 
 | ||||||
| 	back() | 	back() | ||||||
| 	{ | 	{ | ||||||
| 		this.location.back(); | 		this.router.navigate(["/show", this.item.showSlug]); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	next() | 	next() | ||||||
| 	{ | 	{ | ||||||
| 		if (this.item.nextEpisode != null) | 		if (this.item.nextEpisode == null) | ||||||
| 			this.router.navigate(["/watch/" + this.item.nextEpisode.slug], { queryParamsHandling: "merge", replaceUrl: true }); | 			return; | ||||||
|  | 		this.router.navigate(["/watch", this.item.nextEpisode.slug], { | ||||||
|  | 			queryParamsHandling: "merge" | ||||||
|  | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	previous() | 	previous() | ||||||
| 	{ | 	{ | ||||||
| 		if (this.item.previousEpisode != null) | 		if (this.item.previousEpisode == null) | ||||||
| 			this.router.navigate(["/watch/" + this.item.previousEpisode], { queryParamsHandling: "merge", replaceUrl: true }); | 			return; | ||||||
|  | 		this.router.navigate(["/watch", this.item.previousEpisode], { | ||||||
|  | 			queryParamsHandling: "merge" | ||||||
|  | 		}); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	getTimeFromSeekbar(progressBar: HTMLElement, pageX: number) | 	getTimeFromSeekbar(progressBar: HTMLElement, pageX: number) | ||||||
| @ -492,7 +478,7 @@ export class PlayerComponent implements OnInit | |||||||
| 	videoClicked() | 	videoClicked() | ||||||
| 	{ | 	{ | ||||||
| 		if (!navigator.userAgent.match(/Mobi/)) | 		if (!navigator.userAgent.match(/Mobi/)) | ||||||
| 			this.tooglePlayback(); | 			this.togglePlayback(); | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			if ($("#hover").hasClass("idle")) | 			if ($("#hover").hasClass("idle")) | ||||||
| @ -515,7 +501,7 @@ export class PlayerComponent implements OnInit | |||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	tooglePlayback() | 	togglePlayback() | ||||||
| 	{ | 	{ | ||||||
| 		if (this.player.paused) | 		if (this.player.paused) | ||||||
| 			this.player.play(); | 			this.player.play(); | ||||||
| @ -523,22 +509,6 @@ export class PlayerComponent implements OnInit | |||||||
| 			this.player.pause(); | 			this.player.pause(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	toogleMute() |  | ||||||
| 	{ |  | ||||||
| 		if (this.player.muted) |  | ||||||
| 			this.player.muted = false; |  | ||||||
| 		else |  | ||||||
| 			this.player.muted = true; |  | ||||||
| 
 |  | ||||||
| 		this.updateVolumeBtn() |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	initPlayBtn() |  | ||||||
| 	{ |  | ||||||
| 		this.playIcon = "pause"; |  | ||||||
| 		this.playTooltip = "Pause"; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	fullscreen() | 	fullscreen() | ||||||
| 	{ | 	{ | ||||||
| 		if (document.fullscreenElement == null) | 		if (document.fullscreenElement == null) | ||||||
| @ -547,35 +517,16 @@ export class PlayerComponent implements OnInit | |||||||
| 			document.exitFullscreen(); | 			document.exitFullscreen(); | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	//Value from 0 to 100
 | 	getVolumeBtn(): string | ||||||
| 	changeVolume(value: number) |  | ||||||
| 	{ | 	{ | ||||||
| 		value = Math.max(0, Math.min(value, 100)); | 		if (this.volume == 0 || this.muted) | ||||||
| 
 | 			return "volume_off"; | ||||||
| 		this.player.muted = false; | 		else if (this.volume < 25) | ||||||
| 		this.player.volume = value / 100; | 			return "volume_mute"; | ||||||
| 		this.volume = value; | 		else if (this.volume < 65) | ||||||
| 
 | 			return "volume_down"; | ||||||
| 		this.updateVolumeBtn(); |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	updateVolumeBtn() |  | ||||||
| 	{ |  | ||||||
| 		if (this.player.muted) |  | ||||||
| 		{ |  | ||||||
| 			this.volumeIcon = "volume_off" |  | ||||||
| 		} |  | ||||||
| 		else | 		else | ||||||
| 		{ | 			return "volume_up"; | ||||||
| 			if (this.volume == 0) |  | ||||||
| 				this.volumeIcon = "volume_off"; |  | ||||||
| 			else if (this.volume < 25) |  | ||||||
| 				this.volumeIcon = "volume_mute"; |  | ||||||
| 			else if (this.volume < 65) |  | ||||||
| 				this.volumeIcon = "volume_down"; |  | ||||||
| 			else |  | ||||||
| 				this.volumeIcon = "volume_up"; |  | ||||||
| 		} |  | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	selectSubtitle(subtitle: Track, changeUrl: boolean = true) | 	selectSubtitle(subtitle: Track, changeUrl: boolean = true) | ||||||
| @ -590,25 +541,39 @@ export class PlayerComponent implements OnInit | |||||||
| 					subSlug += "-for"; | 					subSlug += "-for"; | ||||||
| 			} | 			} | ||||||
| 
 | 
 | ||||||
| 			this.router.navigate([], { relativeTo: this.route, queryParams: { sub: subSlug }, replaceUrl: true, queryParamsHandling: "merge" }); | 			this.router.navigate([], { | ||||||
|  | 				relativeTo: this.route, | ||||||
|  | 				queryParams: {sub: subSlug}, | ||||||
|  | 				replaceUrl: true, | ||||||
|  | 				queryParamsHandling: "merge" | ||||||
|  | 			}); | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		this.selectedSubtitle = subtitle; | 		this.selectedSubtitle = subtitle; | ||||||
| 
 | 
 | ||||||
| 		if (subtitle == null) | 		if (subtitle == null) | ||||||
| 		{ | 		{ | ||||||
| 			this.snackBar.open("Subtitle removed.", null, { verticalPosition: "top", horizontalPosition: "right", duration: 750, panelClass: "info-panel" }); | 			this.snackBar.open("Subtitle removed.", null, { | ||||||
|  | 				verticalPosition: "top", | ||||||
|  | 				horizontalPosition: "right", | ||||||
|  | 				duration: 750, | ||||||
|  | 				panelClass: "info-panel" | ||||||
|  | 			}); | ||||||
| 			SubtitleManager.remove(this.player); | 			SubtitleManager.remove(this.player); | ||||||
| 			this.removeHtmlTrack(); | 			this.removeHtmlTrack(); | ||||||
| 		} | 		} | ||||||
| 		else | 		else | ||||||
| 		{ | 		{ | ||||||
| 			this.snackBar.open(subtitle.displayName + " subtitle loaded.", null, { verticalPosition: "top", horizontalPosition: "right", duration: 750, panelClass: "info-panel" }); | 			this.snackBar.open(`${subtitle.displayName} subtitle loaded.`, null, { | ||||||
|  | 				verticalPosition: "top", | ||||||
|  | 				horizontalPosition: "right", | ||||||
|  | 				duration: 750, | ||||||
|  | 				panelClass: "info-panel" | ||||||
|  | 			}); | ||||||
| 			this.removeHtmlTrack(); | 			this.removeHtmlTrack(); | ||||||
| 
 | 
 | ||||||
| 			if (subtitle.codec == "ass") | 			if (subtitle.codec == "ass") | ||||||
| 				SubtitleManager.add(this.player, `subtitle/${subtitle.slug}`, true); | 				SubtitleManager.add(this.player, `subtitle/${subtitle.slug}`, true); | ||||||
| 
 |  | ||||||
| 			else if (subtitle.codec == "subrip") | 			else if (subtitle.codec == "subrip") | ||||||
| 			{ | 			{ | ||||||
| 				SubtitleManager.remove(this.player); | 				SubtitleManager.remove(this.player); | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user