mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-08 08:04:16 -04:00
Subrip to WebVTT on the fly transcoder finished.
This commit is contained in:
parent
8fc703ff15
commit
f67293d065
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<div class="controller container-fluid" id="controller">
|
<div class="controller container-fluid" id="controller">
|
||||||
<div class="img d-none d-sm-block">
|
<div class="img d-none d-sm-block">
|
||||||
<img src="thumb/{{this.item.showSlug}}" />
|
<img src="poster/{{this.item.showSlug}}" />
|
||||||
</div>
|
</div>
|
||||||
<div class="content">
|
<div class="content">
|
||||||
<h3>S{{this.item.seasonNumber}}:E{{this.item.episodeNumber}} - {{this.item.title}}</h3>
|
<h3>S{{this.item.seasonNumber}}:E{{this.item.episodeNumber}} - {{this.item.title}}</h3>
|
||||||
|
@ -207,7 +207,6 @@ export class PlayerComponent implements OnInit
|
|||||||
|
|
||||||
$(window).keydown((e) =>
|
$(window).keydown((e) =>
|
||||||
{
|
{
|
||||||
console.log(e.keyCode);
|
|
||||||
switch (e.keyCode)
|
switch (e.keyCode)
|
||||||
{
|
{
|
||||||
case 32: //space
|
case 32: //space
|
||||||
@ -313,6 +312,7 @@ export class PlayerComponent implements OnInit
|
|||||||
this.title.setTitle("Kyoo");
|
this.title.setTitle("Kyoo");
|
||||||
|
|
||||||
$(document).unbind();
|
$(document).unbind();
|
||||||
|
$(window).unbind();
|
||||||
$('[data-toggle="tooltip"]').hide();
|
$('[data-toggle="tooltip"]').hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,12 @@
|
|||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
using Kyoo.Models.Watch;
|
using Kyoo.Models.Watch;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Kyoo.Controllers
|
namespace Kyoo.Controllers
|
||||||
{
|
{
|
||||||
@ -19,8 +24,8 @@ namespace Kyoo.Controllers
|
|||||||
this.transcoder = transcoder;
|
this.transcoder = transcoder;
|
||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{codec?}")]
|
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")]
|
||||||
public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string codec)
|
public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string extension)
|
||||||
{
|
{
|
||||||
string languageTag = identifier.Substring(0, 3);
|
string languageTag = identifier.Substring(0, 3);
|
||||||
bool forced = identifier.Length > 3 && identifier.Substring(4) == "forced";
|
bool forced = identifier.Length > 3 && identifier.Substring(4) == "forced";
|
||||||
@ -30,10 +35,16 @@ namespace Kyoo.Controllers
|
|||||||
if (subtitle == null)
|
if (subtitle == null)
|
||||||
return NotFound();
|
return NotFound();
|
||||||
|
|
||||||
string mime = "text/vtt";
|
|
||||||
|
if (subtitle.Codec == "subrip" && extension == "vtt") //The request wants a WebVTT from a Subrip subtitle, convert it on the fly and send it.
|
||||||
|
{
|
||||||
|
return new ConvertSubripToVtt(subtitle.Path);
|
||||||
|
}
|
||||||
|
|
||||||
|
string mime;
|
||||||
if (subtitle.Codec == "ass")
|
if (subtitle.Codec == "ass")
|
||||||
mime = "text/x-ssa";
|
mime = "text/x-ssa";
|
||||||
else if (subtitle.Codec == "subrip")
|
else
|
||||||
mime = "application/x-subrip";
|
mime = "application/x-subrip";
|
||||||
|
|
||||||
//Should use appropriate mime type here
|
//Should use appropriate mime type here
|
||||||
@ -44,9 +55,87 @@ namespace Kyoo.Controllers
|
|||||||
public string ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
public string ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
transcoder.ExtractSubtitles(episode.Path);
|
libraryManager.ClearSubtitles(episode.id);
|
||||||
|
|
||||||
return "Processing...";
|
Track[] tracks = transcoder.ExtractSubtitles(episode.Path);
|
||||||
|
foreach (Track track in tracks)
|
||||||
|
{
|
||||||
|
track.episodeID = episode.id;
|
||||||
|
libraryManager.RegisterTrack(track);
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Done. " + tracks.Length + " track(s) extracted.";
|
||||||
|
}
|
||||||
|
|
||||||
|
[HttpGet("extract/{showSlug}")]
|
||||||
|
public string ExtractSubtitle(string showSlug)
|
||||||
|
{
|
||||||
|
List<Episode> episodes = libraryManager.GetEpisodes(showSlug);
|
||||||
|
foreach (Episode episode in episodes)
|
||||||
|
{
|
||||||
|
libraryManager.ClearSubtitles(episode.id);
|
||||||
|
|
||||||
|
Track[] tracks = transcoder.ExtractSubtitles(episode.Path);
|
||||||
|
foreach (Track track in tracks)
|
||||||
|
{
|
||||||
|
track.episodeID = episode.id;
|
||||||
|
libraryManager.RegisterTrack(track);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return "Done.";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public class ConvertSubripToVtt : IActionResult
|
||||||
|
{
|
||||||
|
private string path;
|
||||||
|
private string lastLine = "";
|
||||||
|
|
||||||
|
public ConvertSubripToVtt(string subtitlePath)
|
||||||
|
{
|
||||||
|
path = subtitlePath;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ExecuteResultAsync(ActionContext context)
|
||||||
|
{
|
||||||
|
context.HttpContext.Response.StatusCode = 200;
|
||||||
|
//HttpContext.Response.Headers.Add("Content-Disposition", "attachement");
|
||||||
|
context.HttpContext.Response.Headers.Add("Content-Type", "text/vtt");
|
||||||
|
|
||||||
|
using (StreamWriter writer = new StreamWriter(context.HttpContext.Response.Body))
|
||||||
|
{
|
||||||
|
await writer.WriteLineAsync("WEBVTT");
|
||||||
|
await writer.WriteLineAsync("");
|
||||||
|
await writer.WriteLineAsync("");
|
||||||
|
|
||||||
|
string line;
|
||||||
|
using (StreamReader reader = new StreamReader(path))
|
||||||
|
{
|
||||||
|
while ((line = await reader.ReadLineAsync()) != null)
|
||||||
|
{
|
||||||
|
string processedLine = ConvertLine(line);
|
||||||
|
if(processedLine != null)
|
||||||
|
await writer.WriteLineAsync(processedLine);
|
||||||
|
|
||||||
|
lastLine = processedLine;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
await context.HttpContext.Response.Body.FlushAsync();
|
||||||
|
}
|
||||||
|
|
||||||
|
public string ConvertLine(string line)
|
||||||
|
{
|
||||||
|
if (lastLine == "")
|
||||||
|
line = null;
|
||||||
|
|
||||||
|
if (lastLine == null) //The line is a timecode only if the last line is an index line and we already set it to null.
|
||||||
|
line = line.Replace(',', '.'); //This is never called.
|
||||||
|
|
||||||
|
return line;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -24,6 +24,7 @@ namespace Kyoo.InternalAPI
|
|||||||
IEnumerable<Library> GetLibraries();
|
IEnumerable<Library> GetLibraries();
|
||||||
Show GetShowBySlug(string slug);
|
Show GetShowBySlug(string slug);
|
||||||
Season GetSeason(string showSlug, long seasonNumber);
|
Season GetSeason(string showSlug, long seasonNumber);
|
||||||
|
List<Episode> GetEpisodes(string showSlug);
|
||||||
List<Episode> GetEpisodes(string showSlug, long seasonNumber);
|
List<Episode> GetEpisodes(string showSlug, long seasonNumber);
|
||||||
Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber);
|
Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber);
|
||||||
WatchItem GetWatchItem(string showSlug, long seasonNumber, long episodeNumber, bool complete = true);
|
WatchItem GetWatchItem(string showSlug, long seasonNumber, long episodeNumber, bool complete = true);
|
||||||
@ -48,5 +49,7 @@ namespace Kyoo.InternalAPI
|
|||||||
long GetOrCreateStudio(Studio studio);
|
long GetOrCreateStudio(Studio studio);
|
||||||
|
|
||||||
void RegisterShowPeople(long showID, List<People> actors);
|
void RegisterShowPeople(long showID, List<People> actors);
|
||||||
|
|
||||||
|
void ClearSubtitles(long episodeID);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -318,6 +318,24 @@ namespace Kyoo.InternalAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<Episode> GetEpisodes(string showSlug)
|
||||||
|
{
|
||||||
|
string query = "SELECT * FROM episodes JOIN shows ON shows.id = episodes.showID WHERE shows.slug = $showSlug ORDER BY episodeNumber;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$showSlug", showSlug);
|
||||||
|
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||||
|
|
||||||
|
List<Episode> episodes = new List<Episode>();
|
||||||
|
|
||||||
|
while (reader.Read())
|
||||||
|
episodes.Add(Episode.FromReader(reader).SetThumb(showSlug));
|
||||||
|
|
||||||
|
return episodes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public List<Episode> GetEpisodes(string showSlug, long seasonNumber)
|
public List<Episode> GetEpisodes(string showSlug, long seasonNumber)
|
||||||
{
|
{
|
||||||
string query = "SELECT * FROM episodes JOIN shows ON shows.id = episodes.showID WHERE shows.slug = $showSlug AND episodes.seasonNumber = $seasonNumber ORDER BY episodeNumber;";
|
string query = "SELECT * FROM episodes JOIN shows ON shows.id = episodes.showID WHERE shows.slug = $showSlug AND episodes.seasonNumber = $seasonNumber ORDER BY episodeNumber;";
|
||||||
@ -735,6 +753,17 @@ namespace Kyoo.InternalAPI
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void ClearSubtitles(long episodeID)
|
||||||
|
{
|
||||||
|
string query = "DELETE FROM tracks WHERE episodeID = $episodeID;";
|
||||||
|
|
||||||
|
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||||
|
{
|
||||||
|
cmd.Parameters.AddWithValue("$episodeID", episodeID);
|
||||||
|
cmd.ExecuteNonQuery();
|
||||||
|
}
|
||||||
|
}
|
||||||
#endregion
|
#endregion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,10 @@
|
|||||||
using Kyoo.InternalAPI.TranscoderLink;
|
using Kyoo.InternalAPI.TranscoderLink;
|
||||||
using Kyoo.Models;
|
using Kyoo.Models;
|
||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace Kyoo.InternalAPI
|
namespace Kyoo.InternalAPI
|
||||||
{
|
{
|
||||||
|
Loading…
x
Reference in New Issue
Block a user