mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-03 21:54:49 -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="img d-none d-sm-block">
|
||||
<img src="thumb/{{this.item.showSlug}}" />
|
||||
<img src="poster/{{this.item.showSlug}}" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<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) =>
|
||||
{
|
||||
console.log(e.keyCode);
|
||||
switch (e.keyCode)
|
||||
{
|
||||
case 32: //space
|
||||
@ -313,6 +312,7 @@ export class PlayerComponent implements OnInit
|
||||
this.title.setTitle("Kyoo");
|
||||
|
||||
$(document).unbind();
|
||||
$(window).unbind();
|
||||
$('[data-toggle="tooltip"]').hide();
|
||||
}
|
||||
|
||||
|
@ -2,7 +2,12 @@
|
||||
using Kyoo.Models;
|
||||
using Kyoo.Models.Watch;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
{
|
||||
@ -19,8 +24,8 @@ namespace Kyoo.Controllers
|
||||
this.transcoder = transcoder;
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{codec?}")]
|
||||
public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string codec)
|
||||
[HttpGet("{showSlug}-s{seasonNumber:int}e{episodeNumber:int}.{identifier}.{extension?}")]
|
||||
public IActionResult GetSubtitle(string showSlug, int seasonNumber, int episodeNumber, string identifier, string extension)
|
||||
{
|
||||
string languageTag = identifier.Substring(0, 3);
|
||||
bool forced = identifier.Length > 3 && identifier.Substring(4) == "forced";
|
||||
@ -30,10 +35,16 @@ namespace Kyoo.Controllers
|
||||
if (subtitle == null)
|
||||
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")
|
||||
mime = "text/x-ssa";
|
||||
else if (subtitle.Codec == "subrip")
|
||||
else
|
||||
mime = "application/x-subrip";
|
||||
|
||||
//Should use appropriate mime type here
|
||||
@ -44,9 +55,87 @@ namespace Kyoo.Controllers
|
||||
public string ExtractSubtitle(string showSlug, long seasonNumber, long 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();
|
||||
Show GetShowBySlug(string slug);
|
||||
Season GetSeason(string showSlug, long seasonNumber);
|
||||
List<Episode> GetEpisodes(string showSlug);
|
||||
List<Episode> GetEpisodes(string showSlug, long seasonNumber);
|
||||
Episode GetEpisode(string showSlug, long seasonNumber, long episodeNumber);
|
||||
WatchItem GetWatchItem(string showSlug, long seasonNumber, long episodeNumber, bool complete = true);
|
||||
@ -48,5 +49,7 @@ namespace Kyoo.InternalAPI
|
||||
long GetOrCreateStudio(Studio studio);
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
}
|
||||
}
|
||||
|
@ -1,8 +1,10 @@
|
||||
using Kyoo.InternalAPI.TranscoderLink;
|
||||
using Kyoo.Models;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.Diagnostics;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Kyoo.InternalAPI
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user