diff --git a/Kyoo/ClientApp/angular.json b/Kyoo/ClientApp/angular.json index 298f7ce5..3169896d 100644 --- a/Kyoo/ClientApp/angular.json +++ b/Kyoo/ClientApp/angular.json @@ -31,7 +31,8 @@ ], "scripts": [ "./node_modules/jquery/dist/jquery.min.js", - "./node_modules/bootstrap/dist/js/bootstrap.bundle.min.js" + "./node_modules/bootstrap/dist/js/bootstrap.bundle.min.js", + "./src/libraries/subtitles.js" ] }, "configurations": { diff --git a/Kyoo/ClientApp/src/app/player/player.component.scss b/Kyoo/ClientApp/src/app/player/player.component.scss index 24ce721a..881ad788 100644 --- a/Kyoo/ClientApp/src/app/player/player.component.scss +++ b/Kyoo/ClientApp/src/app/player/player.component.scss @@ -1,3 +1,5 @@ +@import "../../libraries/subtitles"; + .player { position: fixed; @@ -15,6 +17,20 @@ } } +#hover +{ + transition: opacity .2s linear; + opacity: 1; + visibility: visible; + + &.idle + { + transition: opacity .6s linear, visibility 0s .6s; + opacity: 0; + visibility: hidden; + } +} + .back { position: fixed; @@ -267,7 +283,7 @@ overflow: hidden; transition: width .2s cubic-bezier(0.4,0, 1, 1); - &::ng-deep > div + > div { top: 19px; left: 10px; diff --git a/Kyoo/ClientApp/src/app/player/player.component.ts b/Kyoo/ClientApp/src/app/player/player.component.ts index b66437df..9cd771b5 100644 --- a/Kyoo/ClientApp/src/app/player/player.component.ts +++ b/Kyoo/ClientApp/src/app/player/player.component.ts @@ -1,15 +1,17 @@ -import { Component, OnInit, ViewChild } from '@angular/core'; +import { Component, OnInit, ViewChild, ViewEncapsulation } from '@angular/core'; import { WatchItem } from "../../models/watch-item"; import { ActivatedRoute } from "@angular/router"; import { DomSanitizer, Title } from "@angular/platform-browser"; import { Location } from "@angular/common"; import { MatSliderChange } from "@angular/material/slider"; -import { HtmlAstPath } from "@angular/compiler"; + +declare var SubtitleManager: any; @Component({ selector: 'app-player', templateUrl: './player.component.html', - styleUrls: ['./player.component.scss'] + styleUrls: ['./player.component.scss'], + encapsulation: ViewEncapsulation.None }) export class PlayerComponent implements OnInit { @@ -17,10 +19,11 @@ export class PlayerComponent implements OnInit volume: number = 100; seeking: boolean = false; + videoHider; hours: number; - minutes: number; - seconds: number; + minutes: number = 0; + seconds: number = 0; maxHours: number; maxMinutes: number; @@ -51,9 +54,7 @@ export class PlayerComponent implements OnInit this.initPlayBtn(); } - this.maxSeconds = Math.round(this.item.duration % 60); - this.maxMinutes = Math.round(this.item.duration / 60 % 60); - this.maxHours = Math.round(this.item.duration / 3600); + this.setDuration(this.item.duration); this.title.setTitle(this.item.showTitle + " S" + this.item.seasonNumber + ":E" + this.item.episodeNumber + " - Kyoo"); }); @@ -91,11 +92,15 @@ export class PlayerComponent implements OnInit { if (this.player.buffered.length > 0) this.buffered.style.width = (this.player.buffered.end(this.player.buffered.length - 1) / this.item.duration * 100) + "%"; + + if (this.player.duration != undefined && this.player.duration != Infinity) + this.setDuration(this.player.duration); }; let progressBar: HTMLElement = document.getElementById("progress-bar") as HTMLElement; $(progressBar).click((event) => { + console.log("Duration: " + this.player.duration); event.preventDefault(); let time: number = this.getTimeFromSeekbar(progressBar, event.pageX); this.player.currentTime = time; @@ -134,8 +139,34 @@ export class PlayerComponent implements OnInit let time: number = this.getTimeFromSeekbar(progressBar, event.pageX); this.updateTime(time); } + else + { + document.getElementById("hover").classList.remove("idle"); + document.documentElement.style.cursor = ""; + + clearTimeout(this.videoHider); + + this.videoHider = setTimeout(() => + { + if (!this.player.paused) + { + document.getElementById("hover").classList.add("idle"); + document.documentElement.style.cursor = "none"; + } + }, 2000); + } }); + //Initialize the timout at the document initialization. + this.videoHider = setTimeout(() => + { + if (!this.player.paused) + { + document.getElementById("hover").classList.add("idle"); + document.documentElement.style.cursor = "none"; + } + }, 2000); + document.addEventListener("fullscreenchange", () => { if (document.fullscreenElement != null) @@ -151,6 +182,8 @@ export class PlayerComponent implements OnInit }); $('[data-toggle="tooltip"]').tooltip({ trigger: "hover" }); + + SubtitleManager.add(this.player, "/api/subtitle/" + this.item.link + "-fre.ass", true); } getTimeFromSeekbar(progressBar: HTMLElement, pageX: number) @@ -158,6 +191,15 @@ export class PlayerComponent implements OnInit return Math.max(0, Math.min((pageX - progressBar.offsetLeft) / progressBar.clientWidth, 1)) * this.item.duration; } + setDuration(duration: number) + { + this.maxSeconds = Math.round(duration % 60); + this.maxMinutes = Math.round(duration / 60 % 60); + this.maxHours = Math.round(duration / 3600); + + this.item.duration = duration; + } + updateTime(time: number) { this.hours = Math.round(time / 60 % 60); diff --git a/Kyoo/ClientApp/src/libraries/subtitles.css b/Kyoo/ClientApp/src/libraries/subtitles.css new file mode 100644 index 00000000..f030ce59 --- /dev/null +++ b/Kyoo/ClientApp/src/libraries/subtitles.css @@ -0,0 +1,23 @@ +.subtitle_container { + line-height: normal; + position: absolute; + pointer-events: none; + transform-origin: 0 0 0; + top: 0; + left: 0; +} +.subtitle_container text, .subtitle_container path { + dominant-baseline: text-before-edge; + text-anchor: start; + transform-box: view-box; + paint-order: stroke; + position: absolute; + top: 0; + left: 0; +} +.subtitle_container tspan { + white-space: pre; +} +.subtitle_container mask path { + fill: white; +} diff --git a/Kyoo/ClientApp/src/libraries/subtitles.js b/Kyoo/ClientApp/src/libraries/subtitles.js new file mode 100644 index 00000000..06aeb3fa --- /dev/null +++ b/Kyoo/ClientApp/src/libraries/subtitles.js @@ -0,0 +1,3372 @@ +// A full list of supported features can be found here: https://github.com/AniDevTwitter/animeopenings/wiki/Subtitle-Features + +/* List of Methods +Name Arguments Description +add video[,filepath[,show]] Adds subtitles to the given