mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Creating subtitle support on the web-app.
This commit is contained in:
parent
9527894fad
commit
e5d3ea1257
@ -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": {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
23
Kyoo/ClientApp/src/libraries/subtitles.css
Normal file
23
Kyoo/ClientApp/src/libraries/subtitles.css
Normal file
@ -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;
|
||||
}
|
3372
Kyoo/ClientApp/src/libraries/subtitles.js
Normal file
3372
Kyoo/ClientApp/src/libraries/subtitles.js
Normal file
File diff suppressed because it is too large
Load Diff
23
Kyoo/Controllers/SubtitleController.cs
Normal file
23
Kyoo/Controllers/SubtitleController.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using Kyoo.InternalAPI;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
[Route("api/[controller]")]
|
||||
[ApiController]
|
||||
public class SubtitleController : ControllerBase
|
||||
{
|
||||
private readonly ILibraryManager libraryManager;
|
||||
|
||||
public SubtitleController(ILibraryManager libraryManager)
|
||||
{
|
||||
this.libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}-{languageTag}.ass")]
|
||||
public IActionResult GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag)
|
||||
{
|
||||
return PhysicalFile(@"D:\Videos\Devilman\Subtitles\fre\Devilman Crybaby S01E01.fre.ass", "text/x-ssa");
|
||||
}
|
||||
}
|
||||
}
|
@ -26,7 +26,7 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
//Should check if video is playable on the client and transcode if needed.
|
||||
//Should use the right mime type
|
||||
return new PhysicalFileResult(episode.Path, "video/mp4");
|
||||
return PhysicalFile(episode.Path, "video/mp4", true);
|
||||
}
|
||||
else
|
||||
return NotFound();
|
||||
|
@ -4,6 +4,7 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.SpaServices.AngularCli;
|
||||
using Microsoft.AspNetCore.StaticFiles;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using System.Web.Http;
|
||||
|
Loading…
x
Reference in New Issue
Block a user