mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-06-20 05:54:16 -04:00
166 lines
4.5 KiB
C#
166 lines
4.5 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.IO;
|
|
using System.Linq;
|
|
using System.Threading.Tasks;
|
|
using Kyoo.Controllers;
|
|
using Kyoo.Models.Attributes;
|
|
using PathIO = System.IO.Path;
|
|
|
|
namespace Kyoo.Models
|
|
{
|
|
public class Chapter
|
|
{
|
|
public float StartTime;
|
|
public float EndTime;
|
|
public string Name;
|
|
|
|
public Chapter(float startTime, float endTime, string name)
|
|
{
|
|
StartTime = startTime;
|
|
EndTime = endTime;
|
|
Name = name;
|
|
}
|
|
}
|
|
|
|
public class WatchItem
|
|
{
|
|
public int EpisodeID { get; set; }
|
|
|
|
public string ShowTitle { get; set; }
|
|
public string ShowSlug { get; set; }
|
|
public int SeasonNumber { get; set; }
|
|
public int EpisodeNumber { get; set; }
|
|
public string Title { get; set; }
|
|
public string Slug { get; set; }
|
|
public DateTime? ReleaseDate { get; set; }
|
|
[SerializeIgnore] public string Path { get; set; }
|
|
public Episode PreviousEpisode { get; set; }
|
|
public Episode NextEpisode { get; set; }
|
|
public bool IsMovie { get; set; }
|
|
|
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/poster")] public string Poster { get; set; }
|
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/logo")] public string Logo { get; set; }
|
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/backdrop")] public string Backdrop { get; set; }
|
|
|
|
public string Container { get; set; }
|
|
public Track Video { get; set; }
|
|
public ICollection<Track> Audios { get; set; }
|
|
public ICollection<Track> Subtitles { get; set; }
|
|
public ICollection<Chapter> Chapters { get; set; }
|
|
|
|
public WatchItem() { }
|
|
|
|
private WatchItem(int episodeID,
|
|
Show show,
|
|
int seasonNumber,
|
|
int episodeNumber,
|
|
string title,
|
|
DateTime? releaseDate,
|
|
string path)
|
|
{
|
|
EpisodeID = episodeID;
|
|
ShowTitle = show.Title;
|
|
ShowSlug = show.Slug;
|
|
SeasonNumber = seasonNumber;
|
|
EpisodeNumber = episodeNumber;
|
|
Title = title;
|
|
ReleaseDate = releaseDate;
|
|
Path = path;
|
|
IsMovie = show.IsMovie;
|
|
|
|
Poster = show.Poster;
|
|
Logo = show.Logo;
|
|
Backdrop = show.Backdrop;
|
|
|
|
Container = Path.Substring(Path.LastIndexOf('.') + 1);
|
|
Slug = Episode.GetSlug(ShowSlug, seasonNumber, episodeNumber);
|
|
}
|
|
|
|
private WatchItem(int episodeID,
|
|
Show show,
|
|
int seasonNumber,
|
|
int episodeNumber,
|
|
string title,
|
|
DateTime? releaseDate,
|
|
string path,
|
|
Track video,
|
|
ICollection<Track> audios,
|
|
ICollection<Track> subtitles)
|
|
: this(episodeID, show, seasonNumber, episodeNumber, title, releaseDate, path)
|
|
{
|
|
Video = video;
|
|
Audios = audios;
|
|
Subtitles = subtitles;
|
|
}
|
|
|
|
public static async Task<WatchItem> FromEpisode(Episode ep, ILibraryManager library)
|
|
{
|
|
Episode previous = null;
|
|
Episode next = null;
|
|
|
|
await library.Load(ep, x => x.Show);
|
|
await library.Load(ep, x => x.Tracks);
|
|
|
|
if (!ep.Show.IsMovie)
|
|
{
|
|
if (ep.EpisodeNumber > 1)
|
|
previous = await library.GetEpisode(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber - 1);
|
|
else if (ep.SeasonNumber > 1)
|
|
{
|
|
int count = await library.GetEpisodesCount(x => x.ShowID == ep.ShowID
|
|
&& x.SeasonNumber == ep.SeasonNumber - 1);
|
|
previous = await library.GetEpisode(ep.ShowID, ep.SeasonNumber - 1, count);
|
|
}
|
|
|
|
if (ep.EpisodeNumber >= await library.GetEpisodesCount(x => x.SeasonID == ep.SeasonID))
|
|
next = await library.GetEpisode(ep.ShowID, ep.SeasonNumber + 1, 1);
|
|
else
|
|
next = await library.GetEpisode(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1);
|
|
}
|
|
|
|
return new WatchItem(ep.ID,
|
|
ep.Show,
|
|
ep.SeasonNumber,
|
|
ep.EpisodeNumber,
|
|
ep.Title,
|
|
ep.ReleaseDate,
|
|
ep.Path,
|
|
ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video),
|
|
ep.Tracks.Where(x => x.Type == StreamType.Audio).ToArray(),
|
|
ep.Tracks.Where(x => x.Type == StreamType.Subtitle).ToArray())
|
|
{
|
|
PreviousEpisode = previous,
|
|
NextEpisode = next,
|
|
Chapters = await GetChapters(ep.Path)
|
|
};
|
|
}
|
|
|
|
private static async Task<ICollection<Chapter>> GetChapters(string episodePath)
|
|
{
|
|
string path = PathIO.Combine(
|
|
PathIO.GetDirectoryName(episodePath)!,
|
|
"Chapters",
|
|
PathIO.GetFileNameWithoutExtension(episodePath) + ".txt"
|
|
);
|
|
if (!File.Exists(path))
|
|
return Array.Empty<Chapter>();
|
|
try
|
|
{
|
|
return (await File.ReadAllLinesAsync(path))
|
|
.Select(x =>
|
|
{
|
|
string[] values = x.Split(' ');
|
|
return new Chapter(float.Parse(values[0]), float.Parse(values[1]), string.Join(' ', values.Skip(2)));
|
|
})
|
|
.ToArray();
|
|
}
|
|
catch
|
|
{
|
|
await Console.Error.WriteLineAsync($"Invalid chapter file at {path}");
|
|
return Array.Empty<Chapter>();
|
|
}
|
|
}
|
|
}
|
|
}
|