mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Creating controller for video transcoding and reworking the stream (subtitle/audio) section.
This commit is contained in:
parent
e5d3ea1257
commit
8d1e8433fb
@ -1,7 +1,8 @@
|
||||
<div id="root">
|
||||
<div class="player">
|
||||
<video id="player" poster="backdrop/{{this.item.showSlug}}" autoplay muted (click)="tooglePlayback()">
|
||||
<source src="/api/video/{{this.item.link}}" type="video/mp4" />
|
||||
<source src="/api/video/{{this.item.link}}" type="video/webm" />
|
||||
<source src="/api/video/{{this.item.link}}/stream" type="video/mp4" />
|
||||
</video>
|
||||
</div>
|
||||
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Kyoo.InternalAPI;
|
||||
using Kyoo.Models.Watch;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace Kyoo.Controllers
|
||||
@ -14,10 +15,16 @@ namespace Kyoo.Controllers
|
||||
this.libraryManager = libraryManager;
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}-{languageTag}.ass")]
|
||||
public IActionResult GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag)
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}-{languageTag}.{format?}")]
|
||||
public IActionResult GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, string format)
|
||||
{
|
||||
return PhysicalFile(@"D:\Videos\Devilman\Subtitles\fre\Devilman Crybaby S01E01.fre.ass", "text/x-ssa");
|
||||
Stream subtitle = libraryManager.GetSubtitle(showSlug, seasonNumber, episodeNumber, languageTag);
|
||||
|
||||
if (subtitle == null)
|
||||
return NotFound();
|
||||
|
||||
//Should use appropriate mime type here
|
||||
return PhysicalFile(subtitle.Path, "text/x-ssa");
|
||||
}
|
||||
}
|
||||
}
|
@ -22,11 +22,35 @@ namespace Kyoo.Controllers
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
return PhysicalFile(episode.Path, "video/x-matroska", true);
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}/stream")]
|
||||
public IActionResult Stream(string showSlug, long seasonNumber, long episodeNumber)
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
{
|
||||
//Should check if video is playable on the client and transcode if needed.
|
||||
//Should use the right mime type
|
||||
return PhysicalFile(episode.Path, "video/mp4", true);
|
||||
string path = transcoder.Stream(episode.Path);
|
||||
return PhysicalFile(path, "video/mp4", true);
|
||||
}
|
||||
else
|
||||
return NotFound();
|
||||
}
|
||||
|
||||
[HttpGet("{showSlug}-s{seasonNumber}e{episodeNumber}/transcode")]
|
||||
public IActionResult Transcode(string showSlug, long seasonNumber, long episodeNumber)
|
||||
{
|
||||
WatchItem episode = libraryManager.GetWatchItem(showSlug, seasonNumber, episodeNumber);
|
||||
|
||||
if (System.IO.File.Exists(episode.Path))
|
||||
{
|
||||
string path = transcoder.Transcode(episode.Path);
|
||||
return PhysicalFile(path, "video/mp4", true);
|
||||
}
|
||||
else
|
||||
return NotFound();
|
||||
|
@ -15,7 +15,10 @@ namespace Kyoo.InternalAPI
|
||||
List<Genre> GetGenreForShow(long showID);
|
||||
List<Season> GetSeasons(long showID);
|
||||
int GetSeasonCount(string showSlug, long seasonNumber);
|
||||
(VideoStream video, List<Stream> audios, List<Stream> subtitles) GetStreams(long episodeID);
|
||||
|
||||
//Internal HTML read
|
||||
(List<Stream> audios, List<Stream> subtitles) GetStreams(long episodeID);
|
||||
Stream GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag);
|
||||
|
||||
//Public read
|
||||
IEnumerable<Library> GetLibraries();
|
||||
|
@ -73,24 +73,14 @@ namespace Kyoo.InternalAPI
|
||||
CREATE TABLE streams(
|
||||
id INTEGER PRIMARY KEY UNIQUE,
|
||||
episodeID INTEGER,
|
||||
streamIndex INTEGER,
|
||||
streamType TEXT,
|
||||
codec TEXT,
|
||||
tile TEXT,
|
||||
language TEXT,
|
||||
channelLayout TEXT,
|
||||
profile TEXT,
|
||||
aspectRatio TEXT,
|
||||
bitRate INTEGER,
|
||||
sampleRate INTEGER,
|
||||
codec TEXT,
|
||||
isDefault BOOLEAN,
|
||||
isForced BOOLEAN,
|
||||
isExternal BOOLEAN,
|
||||
height INTEGER,
|
||||
width INTEGER,
|
||||
frameRate NUMBER,
|
||||
level NUMBER,
|
||||
pixelFormat TEXT,
|
||||
bitDepth INTEGER,
|
||||
isExternal BOOLEAN,
|
||||
path TEXT,
|
||||
FOREIGN KEY(episodeID) REFERENCES episodes(id)
|
||||
);
|
||||
|
||||
@ -199,6 +189,52 @@ namespace Kyoo.InternalAPI
|
||||
}
|
||||
|
||||
|
||||
public (List<Stream> audios, List<Stream> subtitles) GetStreams(long episodeID)
|
||||
{
|
||||
string query = "SELECT * FROM streams WHERE episodeID = $episodeID;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$episodeID", episodeID);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
List<Stream> audios = new List<Stream>();
|
||||
List<Stream> subtitles = new List<Stream>();
|
||||
|
||||
while (reader.Read())
|
||||
{
|
||||
Stream stream = Stream.FromReader(reader);
|
||||
|
||||
if (stream.type == StreamType.Audio)
|
||||
audios.Add(stream);
|
||||
else if (stream.type == StreamType.Subtitle)
|
||||
subtitles.Add(stream);
|
||||
}
|
||||
|
||||
return (audios, subtitles);
|
||||
}
|
||||
}
|
||||
|
||||
public Stream GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag)
|
||||
{
|
||||
string query = "SELECT streams.* FROM streams JOIN episodes ON streams.episodeID = episodes.id JOIN shows ON episodes.showID = shows.id WHERE shows.showSlug = $showSlug, episodes.seasonNumber = $seasonNumber, episodes.episodeNumber = $episodeNumber, streams.language = $languageTag;";
|
||||
|
||||
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
{
|
||||
cmd.Parameters.AddWithValue("$showSlug", showSlug);
|
||||
cmd.Parameters.AddWithValue("$seasonNumber", seasonNumber);
|
||||
cmd.Parameters.AddWithValue("$episodeNumber", episodeNumber);
|
||||
cmd.Parameters.AddWithValue("$languageTag", languageTag);
|
||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
if (reader.Read())
|
||||
return Stream.FromReader(reader);
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public IEnumerable<Show> QueryShows(string selection)
|
||||
{
|
||||
string query = "SELECT * FROM shows ORDER BY title;";
|
||||
@ -341,25 +377,6 @@ namespace Kyoo.InternalAPI
|
||||
}
|
||||
}
|
||||
|
||||
public (VideoStream video, List<Stream> audios, List<Stream> subtitles) GetStreams(long episodeID)
|
||||
{
|
||||
return (new VideoStream(), null, null);
|
||||
//string query = "SELECT genres.id, genres.slug, genres.name FROM genres JOIN genresLinks l ON l.genreID = genres.id WHERE l.showID = $showID;";
|
||||
|
||||
//using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
|
||||
//{
|
||||
// cmd.Parameters.AddWithValue("$episodeID", episodeID);
|
||||
// SQLiteDataReader reader = cmd.ExecuteReader();
|
||||
|
||||
// List<Genre> genres = new List<Genre>();
|
||||
|
||||
// while (reader.Read())
|
||||
// genres.Add(Stream.FromReader(reader));
|
||||
|
||||
// return genres;
|
||||
//}
|
||||
}
|
||||
|
||||
public List<People> GetPeople(long showID)
|
||||
{
|
||||
string query = "SELECT people.id, people.slug, people.name, people.imgPrimary, people.externalIDs, l.role, l.type FROM people JOIN peopleLinks l ON l.peopleID = people.id WHERE l.showID = $showID;";
|
||||
|
@ -2,6 +2,12 @@ namespace Kyoo.InternalAPI
|
||||
{
|
||||
public interface ITranscoder
|
||||
{
|
||||
//Should transcode to a mp4 container (same video/audio format if possible, no subtitles).
|
||||
string Stream(string path);
|
||||
|
||||
//Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles.
|
||||
string Transcode(string path);
|
||||
|
||||
void GetVideo(string Path);
|
||||
|
||||
dynamic ScanVideo(string Path);
|
||||
|
@ -22,5 +22,15 @@ namespace Kyoo.InternalAPI
|
||||
{
|
||||
return TranscoderAPI.ScanVideo(path);
|
||||
}
|
||||
|
||||
public string Stream(string path)
|
||||
{
|
||||
return @"D:\Videos\Anohana\AnoHana S01E01.mp4";
|
||||
}
|
||||
|
||||
public string Transcode(string path)
|
||||
{
|
||||
return @"D:\Videos\Anohana\AnoHana S01E01.mp4";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,17 +1,46 @@
|
||||
namespace Kyoo.Models.Watch
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Kyoo.Models.Watch
|
||||
{
|
||||
public struct Stream
|
||||
public enum StreamType
|
||||
{
|
||||
Audio, Subtitle, Unknow
|
||||
}
|
||||
|
||||
public class Stream
|
||||
{
|
||||
[JsonIgnore] public StreamType type;
|
||||
public string Title;
|
||||
public string Language;
|
||||
public bool IsDefault;
|
||||
public bool IsForced;
|
||||
public string Format;
|
||||
}
|
||||
|
||||
public struct VideoStream
|
||||
{
|
||||
public string Title;
|
||||
public string Language;
|
||||
[JsonIgnore] public bool IsExternal;
|
||||
[JsonIgnore] public string Path;
|
||||
|
||||
public Stream(StreamType type, string title, string language, bool isDefault, bool isForced, string format, bool isExternal, string path)
|
||||
{
|
||||
this.type = type;
|
||||
Title = title;
|
||||
Language = language;
|
||||
IsDefault = isDefault;
|
||||
IsForced = isForced;
|
||||
Format = format;
|
||||
IsExternal = isExternal;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
public static Stream FromReader(System.Data.SQLite.SQLiteDataReader reader)
|
||||
{
|
||||
return new Stream(reader["streamType"] as StreamType? ?? StreamType.Unknow,
|
||||
reader["title"] as string,
|
||||
reader["language"] as string,
|
||||
reader["isDefault"] as bool? ?? false,
|
||||
reader["isForced"] as bool? ?? false,
|
||||
reader["codec"] as string,
|
||||
reader["isExternal"] as bool? ?? false,
|
||||
reader["path"] as string);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ namespace Kyoo.Models
|
||||
public string previousEpisode;
|
||||
public Episode nextEpisode;
|
||||
|
||||
[JsonIgnore] public VideoStream video;
|
||||
public IEnumerable<Stream> audios;
|
||||
public IEnumerable<Stream> subtitles;
|
||||
|
||||
@ -61,8 +60,7 @@ namespace Kyoo.Models
|
||||
|
||||
public WatchItem SetStreams(ILibraryManager libraryManager)
|
||||
{
|
||||
(VideoStream video, IEnumerable<Stream> audios, IEnumerable<Stream> subtitles) streams = libraryManager.GetStreams(episodeID);
|
||||
video = streams.video;
|
||||
(IEnumerable<Stream> audios, IEnumerable<Stream> subtitles) streams = libraryManager.GetStreams(episodeID);
|
||||
audios = streams.audios;
|
||||
subtitles = streams.subtitles;
|
||||
return this;
|
||||
|
Loading…
x
Reference in New Issue
Block a user