mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Adding more documentation
This commit is contained in:
parent
4ffd526875
commit
ab8d5c79e4
38
Kyoo.Common/Models/Chapter.cs
Normal file
38
Kyoo.Common/Models/Chapter.cs
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
namespace Kyoo.Models
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A chapter to split an episode in multiple parts.
|
||||||
|
/// </summary>
|
||||||
|
public class Chapter
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The start time of the chapter (in second from the start of the episode).
|
||||||
|
/// </summary>
|
||||||
|
public float StartTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The end time of the chapter (in second from the start of the episode)&.
|
||||||
|
/// </summary>
|
||||||
|
public float EndTime { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The name of this chapter. This should be a human-readable name that could be presented to the user.
|
||||||
|
/// There should be well-known chapters name for commonly used chapters.
|
||||||
|
/// For example, use "Opening" for the introduction-song and "Credits" for the end chapter with credits.
|
||||||
|
/// </summary>
|
||||||
|
public string Name { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Create a new <see cref="Chapter"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="startTime">The start time of the chapter (in second)</param>
|
||||||
|
/// <param name="endTime">The end time of the chapter (in second)</param>
|
||||||
|
/// <param name="name">The name of this chapter</param>
|
||||||
|
public Chapter(float startTime, float endTime, string name)
|
||||||
|
{
|
||||||
|
StartTime = startTime;
|
||||||
|
EndTime = endTime;
|
||||||
|
Name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,95 +9,137 @@ using PathIO = System.IO.Path;
|
|||||||
|
|
||||||
namespace Kyoo.Models
|
namespace Kyoo.Models
|
||||||
{
|
{
|
||||||
public class Chapter
|
/// <summary>
|
||||||
{
|
/// A watch item give information useful for playback.
|
||||||
public float StartTime;
|
/// Information about tracks and display information that could be used by the player.
|
||||||
public float EndTime;
|
/// This contains mostly data from an <see cref="Episode"/> with another form.
|
||||||
public string Name;
|
/// </summary>
|
||||||
|
|
||||||
public Chapter(float startTime, float endTime, string name)
|
|
||||||
{
|
|
||||||
StartTime = startTime;
|
|
||||||
EndTime = endTime;
|
|
||||||
Name = name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class WatchItem
|
public class WatchItem
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The ID of the episode associated with this item.
|
||||||
|
/// </summary>
|
||||||
public int EpisodeID { get; set; }
|
public int EpisodeID { get; set; }
|
||||||
|
|
||||||
public string ShowTitle { get; set; }
|
/// <summary>
|
||||||
public string ShowSlug { get; set; }
|
/// The slug of this episode.
|
||||||
public int SeasonNumber { get; set; }
|
/// </summary>
|
||||||
public int EpisodeNumber { get; set; }
|
|
||||||
public int AbsoluteNumber { get; set; }
|
|
||||||
public string Title { get; set; }
|
|
||||||
public string Slug { get; set; }
|
public string Slug { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The title of the show containing this episode.
|
||||||
|
/// </summary>
|
||||||
|
public string ShowTitle { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The slug of the show containing this episode
|
||||||
|
/// </summary>
|
||||||
|
public string ShowSlug { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The season in witch this episode is in. This defaults to -1 if not specified.
|
||||||
|
/// </summary>
|
||||||
|
public int SeasonNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The number of this episode is it's season. This defaults to -1 if not specified.
|
||||||
|
/// </summary>
|
||||||
|
public int EpisodeNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The absolute number of this episode. It's an episode number that is not reset to 1 after a new season.
|
||||||
|
/// This defaults to -1 if not specified.
|
||||||
|
/// </summary>
|
||||||
|
public int AbsoluteNumber { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The title of this episode.
|
||||||
|
/// </summary>
|
||||||
|
public string Title { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The release date of this episode. It can be null if unknown.
|
||||||
|
/// </summary>
|
||||||
public DateTime? ReleaseDate { get; set; }
|
public DateTime? ReleaseDate { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of the video file for this episode. Any format supported by a <see cref="IFileManager"/> is allowed.
|
||||||
|
/// </summary>
|
||||||
[SerializeIgnore] public string Path { get; set; }
|
[SerializeIgnore] public string Path { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The episode that come before this one if you follow usual watch orders.
|
||||||
|
/// If this is the first episode or this is a movie, it will be null.
|
||||||
|
/// </summary>
|
||||||
public Episode PreviousEpisode { get; set; }
|
public Episode PreviousEpisode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The episode that come after this one if you follow usual watch orders.
|
||||||
|
/// If this is the last aired episode or this is a movie, it will be null.
|
||||||
|
/// </summary>
|
||||||
public Episode NextEpisode { get; set; }
|
public Episode NextEpisode { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// <c>true</c> if this is a movie, <c>false</c> otherwise.
|
||||||
|
/// </summary>
|
||||||
public bool IsMovie { get; set; }
|
public bool IsMovie { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of this item's poster.
|
||||||
|
/// By default, the http path for the poster is returned from the public API.
|
||||||
|
/// This can be disabled using the internal query flag.
|
||||||
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/show/{ShowSlug}/poster")] public string Poster { get; set; }
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/poster")] public string Poster { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of this item's logo.
|
||||||
|
/// By default, the http path for the logo is returned from the public API.
|
||||||
|
/// This can be disabled using the internal query flag.
|
||||||
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/show/{ShowSlug}/logo")] public string Logo { get; set; }
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/logo")] public string Logo { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The path of this item's backdrop.
|
||||||
|
/// By default, the http path for the backdrop is returned from the public API.
|
||||||
|
/// This can be disabled using the internal query flag.
|
||||||
|
/// </summary>
|
||||||
[SerializeAs("{HOST}/api/show/{ShowSlug}/backdrop")] public string Backdrop { get; set; }
|
[SerializeAs("{HOST}/api/show/{ShowSlug}/backdrop")] public string Backdrop { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The container of the video file of this episode.
|
||||||
|
/// Common containers are mp4, mkv, avi and so on.
|
||||||
|
/// </summary>
|
||||||
public string Container { get; set; }
|
public string Container { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The video track. See <see cref="Track"/> for more information.
|
||||||
|
/// </summary>
|
||||||
public Track Video { get; set; }
|
public Track Video { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of audio tracks. See <see cref="Track"/> for more information.
|
||||||
|
/// </summary>
|
||||||
public ICollection<Track> Audios { get; set; }
|
public ICollection<Track> Audios { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of subtitles tracks. See <see cref="Track"/> for more information.
|
||||||
|
/// </summary>
|
||||||
public ICollection<Track> Subtitles { get; set; }
|
public ICollection<Track> Subtitles { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The list of chapters. See <see cref="Chapter"/> for more information.
|
||||||
|
/// </summary>
|
||||||
public ICollection<Chapter> Chapters { get; set; }
|
public ICollection<Chapter> Chapters { get; set; }
|
||||||
|
|
||||||
|
|
||||||
public WatchItem() { }
|
/// <summary>
|
||||||
|
/// Create a <see cref="WatchItem"/> from an <see cref="Episode"/>.
|
||||||
private WatchItem(int episodeID,
|
/// </summary>
|
||||||
Show show,
|
/// <param name="ep">The episode to transform.</param>
|
||||||
int seasonNumber,
|
/// <param name="library">
|
||||||
int episodeNumber,
|
/// A library manager to retrieve the next and previous episode and load the show & tracks of the episode.
|
||||||
int absoluteNumber,
|
/// </param>
|
||||||
string title,
|
/// <returns>A new WatchItem representing the given episode.</returns>
|
||||||
DateTime? releaseDate,
|
|
||||||
string path)
|
|
||||||
{
|
|
||||||
EpisodeID = episodeID;
|
|
||||||
ShowTitle = show.Title;
|
|
||||||
ShowSlug = show.Slug;
|
|
||||||
SeasonNumber = seasonNumber;
|
|
||||||
EpisodeNumber = episodeNumber;
|
|
||||||
AbsoluteNumber = absoluteNumber;
|
|
||||||
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, absoluteNumber);
|
|
||||||
}
|
|
||||||
|
|
||||||
private WatchItem(int episodeID,
|
|
||||||
Show show,
|
|
||||||
int seasonNumber,
|
|
||||||
int episodeNumber,
|
|
||||||
int absoluteNumber,
|
|
||||||
string title,
|
|
||||||
DateTime? releaseDate,
|
|
||||||
string path,
|
|
||||||
Track video,
|
|
||||||
ICollection<Track> audios,
|
|
||||||
ICollection<Track> subtitles)
|
|
||||||
: this(episodeID, show, seasonNumber, episodeNumber, absoluteNumber, title, releaseDate, path)
|
|
||||||
{
|
|
||||||
Video = video;
|
|
||||||
Audios = audios;
|
|
||||||
Subtitles = subtitles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static async Task<WatchItem> FromEpisode(Episode ep, ILibraryManager library)
|
public static async Task<WatchItem> FromEpisode(Episode ep, ILibraryManager library)
|
||||||
{
|
{
|
||||||
Episode previous = null;
|
Episode previous = null;
|
||||||
@ -123,24 +165,27 @@ namespace Kyoo.Models
|
|||||||
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1);
|
next = await library.GetOrDefault(ep.ShowID, ep.SeasonNumber, ep.EpisodeNumber + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new WatchItem(ep.ID,
|
return new WatchItem
|
||||||
ep.Show,
|
|
||||||
ep.SeasonNumber,
|
|
||||||
ep.EpisodeNumber,
|
|
||||||
ep.AbsoluteNumber,
|
|
||||||
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())
|
|
||||||
{
|
{
|
||||||
|
EpisodeID = ep.ID,
|
||||||
|
ShowSlug = ep.Show.Slug,
|
||||||
|
SeasonNumber = ep.SeasonNumber,
|
||||||
|
EpisodeNumber = ep.EpisodeNumber,
|
||||||
|
AbsoluteNumber = ep.AbsoluteNumber,
|
||||||
|
Title = ep.Title,
|
||||||
|
ReleaseDate = ep.ReleaseDate,
|
||||||
|
Path = ep.Path,
|
||||||
|
Video = ep.Tracks.FirstOrDefault(x => x.Type == StreamType.Video),
|
||||||
|
Audios = ep.Tracks.Where(x => x.Type == StreamType.Audio).ToArray(),
|
||||||
|
Subtitles = ep.Tracks.Where(x => x.Type == StreamType.Subtitle).ToArray(),
|
||||||
PreviousEpisode = previous,
|
PreviousEpisode = previous,
|
||||||
NextEpisode = next,
|
NextEpisode = next,
|
||||||
Chapters = await GetChapters(ep.Path)
|
Chapters = await GetChapters(ep.Path)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO move this method in a controller to support abstraction.
|
||||||
|
// TODO use a IFileManager to retrieve and read files.
|
||||||
private static async Task<ICollection<Chapter>> GetChapters(string episodePath)
|
private static async Task<ICollection<Chapter>> GetChapters(string episodePath)
|
||||||
{
|
{
|
||||||
string path = PathIO.Combine(
|
string path = PathIO.Combine(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user