mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-09 03:04:20 -04:00
Adding video and audio codec detection in the crawler.
Adding multiple audio support for the playback method detector.
This commit is contained in:
parent
f776a00853
commit
690048e720
@ -1,10 +1,4 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#ifdef TRANSCODER_EXPORTS
|
|
||||||
#define API __declspec(dllexport)
|
|
||||||
#else
|
|
||||||
#define API __declspec(dllimport)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
@ -18,20 +12,38 @@ extern "C" struct Stream
|
|||||||
char *path;
|
char *path;
|
||||||
|
|
||||||
Stream()
|
Stream()
|
||||||
: title(NULL), language(NULL), codec(NULL), is_default(NULL), is_forced(NULL), path(NULL) {}
|
: title(nullptr), language(nullptr), codec(nullptr), is_default(nullptr), is_forced(nullptr), path(nullptr) {}
|
||||||
|
|
||||||
Stream(const char* title, const char* languageCode, const char* codec, bool isDefault, bool isForced)
|
Stream(const char* title, const char* languageCode, const char* codec, bool isDefault, bool isForced)
|
||||||
: title(NULL), language(NULL), codec(NULL), is_default(isDefault), is_forced(isForced), path(NULL)
|
: title(nullptr), language(nullptr), codec(nullptr), is_default(isDefault), is_forced(isForced), path(nullptr)
|
||||||
{
|
{
|
||||||
if(title != NULL)
|
if(title != nullptr)
|
||||||
this->title= strdup(title);
|
this->title= strdup(title);
|
||||||
|
|
||||||
if (languageCode != NULL)
|
if (languageCode != nullptr)
|
||||||
language = strdup(languageCode);
|
language = strdup(languageCode);
|
||||||
else
|
else
|
||||||
language = strdup("und");
|
language = strdup("und");
|
||||||
|
|
||||||
if (codec != NULL)
|
if (codec != nullptr)
|
||||||
this->codec = strdup(codec);
|
this->codec = strdup(codec);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream(const char *title, const char *languageCode, const char *codec, bool isDefault, bool isForced, const char *path)
|
||||||
|
: title(nullptr), language(nullptr), codec(nullptr), is_default(isDefault), is_forced(isForced), path(nullptr)
|
||||||
|
{
|
||||||
|
if (title != nullptr)
|
||||||
|
this->title = strdup(title);
|
||||||
|
|
||||||
|
if (languageCode != nullptr)
|
||||||
|
language = strdup(languageCode);
|
||||||
|
else
|
||||||
|
language = strdup("und");
|
||||||
|
|
||||||
|
if (codec != nullptr)
|
||||||
|
this->codec = strdup(codec);
|
||||||
|
|
||||||
|
if (path != nullptr)
|
||||||
|
this->path = strdup(path);
|
||||||
|
}
|
||||||
};
|
};
|
@ -13,6 +13,8 @@ extern "C" API int Init();
|
|||||||
|
|
||||||
extern "C" API int transmux(const char *path, const char *out_path, float *playable_duration);
|
extern "C" API int transmux(const char *path, const char *out_path, float *playable_duration);
|
||||||
|
|
||||||
|
extern "C" API Stream *get_track_info(const char *path, int *stream_count, int *track_count);
|
||||||
|
|
||||||
//Take the path of the file and the path of the output directory. It will return the list of subtitle streams in the streams variable. The int returned is the number of subtitles extracted.
|
//Take the path of the file and the path of the output directory. It will return the list of subtitle streams in the streams variable. The int returned is the number of subtitles extracted.
|
||||||
extern "C" API Stream* extract_subtitles(const char *path, const char *outPath, int *streamCount, int *subtitleCount);
|
extern "C" API Stream* extract_subtitles(const char *path, const char *outPath, int *streamCount, int *subtitleCount);
|
||||||
|
|
||||||
|
@ -98,6 +98,43 @@ int transmux(const char *path, const char *out_path, float *playable_duration)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Stream *get_track_info(const char *path, int *stream_count, int *track_count)
|
||||||
|
{
|
||||||
|
AVFormatContext *ctx = NULL;
|
||||||
|
Stream *streams;
|
||||||
|
|
||||||
|
if (open_input_context(&ctx, path) != 0)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
*stream_count = ctx->nb_streams;
|
||||||
|
*track_count = 0;
|
||||||
|
streams = new Stream[*stream_count];
|
||||||
|
|
||||||
|
//Initialize output and set headers.
|
||||||
|
for (int i = 0; i < *stream_count; i++)
|
||||||
|
{
|
||||||
|
AVStream *stream = ctx->streams[i];
|
||||||
|
const AVCodecParameters *codecpar = stream->codecpar;
|
||||||
|
|
||||||
|
if (codecpar->codec_type == AVMEDIA_TYPE_VIDEO || codecpar->codec_type == AVMEDIA_TYPE_AUDIO)
|
||||||
|
{
|
||||||
|
AVDictionaryEntry *languageptr = av_dict_get(stream->metadata, "language", NULL, 0);
|
||||||
|
|
||||||
|
*track_count += 1;
|
||||||
|
|
||||||
|
streams[i] = Stream(codecpar->codec_type == AVMEDIA_TYPE_VIDEO ? "VIDEO" : NULL, // title
|
||||||
|
languageptr ? languageptr->value : NULL, // language
|
||||||
|
avcodec_get_name(codecpar->codec_id), // format
|
||||||
|
stream->disposition & AV_DISPOSITION_DEFAULT, // isDefault
|
||||||
|
stream->disposition & AV_DISPOSITION_FORCED, // isForced
|
||||||
|
path); // path
|
||||||
|
}
|
||||||
|
else
|
||||||
|
streams[i] = Stream();
|
||||||
|
}
|
||||||
|
avformat_close_input(&ctx);
|
||||||
|
return streams;
|
||||||
|
}
|
||||||
|
|
||||||
Stream *extract_subtitles(const char *path, const char *out_path, int *stream_count, int *subtitle_count)
|
Stream *extract_subtitles(const char *path, const char *out_path, int *stream_count, int *subtitle_count)
|
||||||
{
|
{
|
||||||
@ -124,7 +161,10 @@ Stream *extract_subtitles(const char *path, const char *out_path, int *stream_co
|
|||||||
const AVCodecParameters *in_codecpar = in_stream->codecpar;
|
const AVCodecParameters *in_codecpar = in_stream->codecpar;
|
||||||
|
|
||||||
if (in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
|
if (in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
|
||||||
|
{
|
||||||
output_list[i] = NULL;
|
output_list[i] = NULL;
|
||||||
|
streams[i] = Stream();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*subtitle_count += 1;
|
*subtitle_count += 1;
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
<ng-template #elseBlock><p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p></ng-template>
|
<ng-template #elseBlock><p>{{this.minutes | number: '2.0-0'}}:{{this.seconds | number: '2.0-0'}} / {{this.maxMinutes | number: '2.0-0'}}:{{this.maxSeconds | number: '2.0-0'}}</p></ng-template>
|
||||||
</div>
|
</div>
|
||||||
<div class="right">
|
<div class="right">
|
||||||
<button id="volume" *ngIf="this.item.audios.length > 0" mat-icon-button matTooltipPosition="above" matTooltip="Select audio track">
|
<button id="volume" *ngIf="this.item.audios.length > 1" mat-icon-button matTooltipPosition="above" matTooltip="Select audio track">
|
||||||
<mat-icon>music_note</mat-icon>
|
<mat-icon>music_note</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button *ngIf="this.item.subtitles.length > 0" mat-icon-button [matMenuTriggerFor]="subtitles" matTooltipPosition="above" matTooltip="Select subtitle track">
|
<button *ngIf="this.item.subtitles.length > 0" mat-icon-button [matMenuTriggerFor]="subtitles" matTooltipPosition="above" matTooltip="Select subtitle track">
|
||||||
|
@ -13,7 +13,7 @@ function getPlaybackMethod(player, item) {
|
|||||||
// If we can't find the browser, transcode (It may or may not support containers/codecs)
|
// If we can't find the browser, transcode (It may or may not support containers/codecs)
|
||||||
if (!browser)
|
if (!browser)
|
||||||
return method.transcode;
|
return method.transcode;
|
||||||
if (containerIsSupported(player, item.container, browser.name)) {
|
if (containerIsSupported(player, item.container, browser.name) && item.audios.length <= 1) {
|
||||||
if (videoCodecIsSupported(player, item.video.codec, browser.name) &&
|
if (videoCodecIsSupported(player, item.video.codec, browser.name) &&
|
||||||
audioCodecIsSupported(player, item.audios.map(function (value) { return value.codec; }), browser.name))
|
audioCodecIsSupported(player, item.audios.map(function (value) { return value.codec; }), browser.name))
|
||||||
return method.direct;
|
return method.direct;
|
||||||
|
@ -1 +1 @@
|
|||||||
{"version":3,"file":"playbackMethodDetector.js","sourceRoot":"","sources":["playbackMethodDetector.ts"],"names":[],"mappings":"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"}
|
{"version":3,"file":"playbackMethodDetector.js","sourceRoot":"","sources":["playbackMethodDetector.ts"],"names":[],"mappings":"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"}
|
@ -16,7 +16,7 @@ export function getPlaybackMethod(player: HTMLVideoElement, item: WatchItem): me
|
|||||||
if (!browser)
|
if (!browser)
|
||||||
return method.transcode;
|
return method.transcode;
|
||||||
|
|
||||||
if (containerIsSupported(player, item.container, browser.name))
|
if (containerIsSupported(player, item.container, browser.name) && item.audios.length <= 1)
|
||||||
{
|
{
|
||||||
if (videoCodecIsSupported(player, item.video.codec, browser.name) &&
|
if (videoCodecIsSupported(player, item.video.codec, browser.name) &&
|
||||||
audioCodecIsSupported(player, item.audios.map((value: Track) => value.codec), browser.name))
|
audioCodecIsSupported(player, item.audios.map((value: Track) => value.codec), browser.name))
|
||||||
|
@ -252,14 +252,21 @@ namespace Kyoo.InternalAPI
|
|||||||
episode.SeasonID = seasonID;
|
episode.SeasonID = seasonID;
|
||||||
episode.id = libraryManager.RegisterEpisode(episode);
|
episode.id = libraryManager.RegisterEpisode(episode);
|
||||||
|
|
||||||
|
Track[] tracks = await transcoder.GetTrackInfo(episode.Path);
|
||||||
|
foreach (Track track in tracks)
|
||||||
|
{
|
||||||
|
track.episodeID = episode.id;
|
||||||
|
libraryManager.RegisterTrack(track);
|
||||||
|
}
|
||||||
|
|
||||||
if (episode.Path.EndsWith(".mkv"))
|
if (episode.Path.EndsWith(".mkv"))
|
||||||
{
|
{
|
||||||
if (!FindExtractedSubtitles(episode))
|
if (!FindExtractedSubtitles(episode))
|
||||||
{
|
{
|
||||||
Track[] tracks = await transcoder.ExtractSubtitles(episode.Path);
|
Track[] subtitles = await transcoder.ExtractSubtitles(episode.Path);
|
||||||
if (tracks != null)
|
if (subtitles != null)
|
||||||
{
|
{
|
||||||
foreach (Track track in tracks)
|
foreach (Track track in subtitles)
|
||||||
{
|
{
|
||||||
track.episodeID = episode.id;
|
track.episodeID = episode.id;
|
||||||
libraryManager.RegisterTrack(track);
|
libraryManager.RegisterTrack(track);
|
||||||
|
@ -19,8 +19,8 @@ namespace Kyoo.InternalAPI
|
|||||||
IEnumerable<Show> GetShowsByPeople(long peopleID);
|
IEnumerable<Show> GetShowsByPeople(long peopleID);
|
||||||
IEnumerable<string> GetLibrariesPath();
|
IEnumerable<string> GetLibrariesPath();
|
||||||
|
|
||||||
//Internal HTML read
|
//Internal read
|
||||||
(List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string showSlug);
|
(Track video, List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string showSlug);
|
||||||
Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced);
|
Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag, bool forced);
|
||||||
|
|
||||||
//Public read
|
//Public read
|
||||||
|
@ -224,7 +224,7 @@ namespace Kyoo.InternalAPI
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public (List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string episodeSlug)
|
public (Track video, List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string episodeSlug)
|
||||||
{
|
{
|
||||||
string query = "SELECT * FROM tracks WHERE episodeID = $episodeID;";
|
string query = "SELECT * FROM tracks WHERE episodeID = $episodeID;";
|
||||||
|
|
||||||
@ -233,6 +233,7 @@ namespace Kyoo.InternalAPI
|
|||||||
cmd.Parameters.AddWithValue("$episodeID", episodeID);
|
cmd.Parameters.AddWithValue("$episodeID", episodeID);
|
||||||
SQLiteDataReader reader = cmd.ExecuteReader();
|
SQLiteDataReader reader = cmd.ExecuteReader();
|
||||||
|
|
||||||
|
Track video = null;
|
||||||
List<Track> audios = new List<Track>();
|
List<Track> audios = new List<Track>();
|
||||||
List<Track> subtitles = new List<Track>();
|
List<Track> subtitles = new List<Track>();
|
||||||
|
|
||||||
@ -240,13 +241,15 @@ namespace Kyoo.InternalAPI
|
|||||||
{
|
{
|
||||||
Track track = Track.FromReader(reader).SetLink(episodeSlug);
|
Track track = Track.FromReader(reader).SetLink(episodeSlug);
|
||||||
|
|
||||||
if (track.type == StreamType.Audio)
|
if (track.type == StreamType.Video)
|
||||||
|
video = track;
|
||||||
|
else if (track.type == StreamType.Audio)
|
||||||
audios.Add(track);
|
audios.Add(track);
|
||||||
else if (track.type == StreamType.Subtitle)
|
else if (track.type == StreamType.Subtitle)
|
||||||
subtitles.Add(track);
|
subtitles.Add(track);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (audios, subtitles);
|
return (video, audios, subtitles);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,13 +6,16 @@ namespace Kyoo.InternalAPI
|
|||||||
{
|
{
|
||||||
public interface ITranscoder
|
public interface ITranscoder
|
||||||
{
|
{
|
||||||
//Should transcode to a mp4 container (same video/audio format if possible, no subtitles).
|
// Should transcode to a mp4 container (same video/audio format if possible, no subtitles).
|
||||||
Task<string> Transmux(WatchItem episode);
|
Task<string> Transmux(WatchItem episode);
|
||||||
|
|
||||||
//Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles.
|
// Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles.
|
||||||
Task<string> Transcode(WatchItem episode);
|
Task<string> Transcode(WatchItem episode);
|
||||||
|
|
||||||
//Extract all subtitles of a video and save them in the subtitles sub-folder.
|
// Get video and audio tracks infos (codec, name, language...)
|
||||||
|
Task<Track[]> GetTrackInfo(string path);
|
||||||
|
|
||||||
|
// Extract all subtitles of a video and save them in the subtitles sub-folder.
|
||||||
Task<Track[]> ExtractSubtitles(string path);
|
Task<Track[]> ExtractSubtitles(string path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,15 @@ namespace Kyoo.InternalAPI
|
|||||||
Debug.WriteLine("&Api INIT (unmanaged stream size): " + TranscoderAPI.Init() + ", Stream size: " + Marshal.SizeOf<Models.Watch.Stream>());
|
Debug.WriteLine("&Api INIT (unmanaged stream size): " + TranscoderAPI.Init() + ", Stream size: " + Marshal.SizeOf<Models.Watch.Stream>());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Track[]> GetTrackInfo(string path)
|
||||||
|
{
|
||||||
|
return await Task.Run(() =>
|
||||||
|
{
|
||||||
|
TranscoderAPI.GetTrackInfo(path, out Track[] tracks);
|
||||||
|
return tracks;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
public async Task<Track[]> ExtractSubtitles(string path)
|
public async Task<Track[]> ExtractSubtitles(string path)
|
||||||
{
|
{
|
||||||
string output = Path.Combine(Path.GetDirectoryName(path), "Subtitles");
|
string output = Path.Combine(Path.GetDirectoryName(path), "Subtitles");
|
||||||
|
@ -17,18 +17,51 @@ namespace Kyoo.InternalAPI.TranscoderLink
|
|||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public extern static int transmux(string path, string out_path, out float playableDuration);
|
public extern static int transmux(string path, string out_path, out float playableDuration);
|
||||||
|
|
||||||
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
|
private extern static IntPtr get_track_info(string path, out int array_length, out int track_count);
|
||||||
|
|
||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private extern static IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);
|
private extern static IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);
|
||||||
|
|
||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
private extern static void free_memory(IntPtr stream_ptr);
|
private extern static void free_memory(IntPtr stream_ptr);
|
||||||
|
|
||||||
|
|
||||||
|
public static void GetTrackInfo(string path, out Track[] tracks)
|
||||||
|
{
|
||||||
|
int size = Marshal.SizeOf<Stream>();
|
||||||
|
IntPtr ptr = get_track_info(path, out int arrayLength, out int trackCount);
|
||||||
|
IntPtr streamsPtr = ptr;
|
||||||
|
|
||||||
|
if (trackCount > 0 && ptr != IntPtr.Zero)
|
||||||
|
{
|
||||||
|
tracks = new Track[trackCount];
|
||||||
|
|
||||||
|
int j = 0;
|
||||||
|
for (int i = 0; i < arrayLength; i++)
|
||||||
|
{
|
||||||
|
Stream stream = Marshal.PtrToStructure<Stream>(streamsPtr);
|
||||||
|
if (stream.Codec != null) //If the codec is null, the stream doesn't represent a usfull thing.
|
||||||
|
{
|
||||||
|
tracks[j] = Track.From(stream, stream.Title == "VIDEO" ? StreamType.Video : StreamType.Audio);
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
streamsPtr += size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
tracks = null;
|
||||||
|
|
||||||
|
free_memory(ptr);
|
||||||
|
Debug.WriteLine("&" + tracks?.Length + " tracks got at: " + path);
|
||||||
|
}
|
||||||
|
|
||||||
public static void ExtractSubtitles(string path, string outPath, out Track[] tracks)
|
public static void ExtractSubtitles(string path, string outPath, out Track[] tracks)
|
||||||
{
|
{
|
||||||
int size = Marshal.SizeOf<Stream>();
|
int size = Marshal.SizeOf<Stream>();
|
||||||
|
|
||||||
IntPtr ptr = extract_subtitles(path, outPath, out int arrayLength, out int trackCount);
|
IntPtr ptr = extract_subtitles(path, outPath, out int arrayLength, out int trackCount);
|
||||||
IntPtr streamsPtr = ptr;
|
IntPtr streamsPtr = ptr;
|
||||||
|
|
||||||
if (trackCount > 0 && ptr != IntPtr.Zero)
|
if (trackCount > 0 && ptr != IntPtr.Zero)
|
||||||
{
|
{
|
||||||
tracks = new Track[trackCount];
|
tracks = new Track[trackCount];
|
||||||
|
@ -11,7 +11,7 @@ namespace Kyoo.Models
|
|||||||
{
|
{
|
||||||
public enum StreamType
|
public enum StreamType
|
||||||
{
|
{
|
||||||
Audio, Subtitle, Unknow
|
Video, Audio, Subtitle, Unknow
|
||||||
}
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
|
||||||
@ -78,28 +78,32 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public Track SetLink(string episodeSlug)
|
public Track SetLink(string episodeSlug)
|
||||||
{
|
{
|
||||||
string language = Language;
|
if (type == StreamType.Subtitle)
|
||||||
//Converting mkv track language to c# system language tag.
|
|
||||||
if (language == "fre")
|
|
||||||
language = "fra";
|
|
||||||
|
|
||||||
DisplayName = CultureInfo.GetCultures(CultureTypes.NeutralCultures).Where(x => x.ThreeLetterISOLanguageName == language).FirstOrDefault()?.DisplayName ?? language;
|
|
||||||
Link = "/subtitle/" + episodeSlug + "." + Language;
|
|
||||||
|
|
||||||
if (IsForced)
|
|
||||||
{
|
{
|
||||||
DisplayName += " Forced";
|
string language = Language;
|
||||||
Link += "-forced";
|
//Converting mkv track language to c# system language tag.
|
||||||
|
if (language == "fre")
|
||||||
|
language = "fra";
|
||||||
|
|
||||||
|
DisplayName = CultureInfo.GetCultures(CultureTypes.NeutralCultures).Where(x => x.ThreeLetterISOLanguageName == language).FirstOrDefault()?.DisplayName ?? language;
|
||||||
|
Link = "/subtitle/" + episodeSlug + "." + Language;
|
||||||
|
|
||||||
|
if (IsForced)
|
||||||
|
{
|
||||||
|
DisplayName += " Forced";
|
||||||
|
Link += "-forced";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Title != null && Title.Length > 1)
|
||||||
|
DisplayName += " - " + Title;
|
||||||
|
|
||||||
|
if (Codec == "ass")
|
||||||
|
Link += ".ass";
|
||||||
|
else if (Codec == "subrip")
|
||||||
|
Link += ".srt";
|
||||||
}
|
}
|
||||||
|
else
|
||||||
if (Title != null && Title.Length > 1)
|
Link = null;
|
||||||
DisplayName += " - " + Title;
|
|
||||||
|
|
||||||
if (Codec == "ass")
|
|
||||||
Link += ".ass";
|
|
||||||
else if (Codec == "subrip")
|
|
||||||
Link += ".srt";
|
|
||||||
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
using Kyoo.InternalAPI;
|
using Kyoo.InternalAPI;
|
||||||
using Kyoo.Models.Watch;
|
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
@ -21,6 +20,8 @@ namespace Kyoo.Models
|
|||||||
public string previousEpisode;
|
public string previousEpisode;
|
||||||
public Episode nextEpisode;
|
public Episode nextEpisode;
|
||||||
|
|
||||||
|
public string container;
|
||||||
|
public Track video;
|
||||||
public IEnumerable<Track> audios;
|
public IEnumerable<Track> audios;
|
||||||
public IEnumerable<Track> subtitles;
|
public IEnumerable<Track> subtitles;
|
||||||
|
|
||||||
@ -60,7 +61,10 @@ namespace Kyoo.Models
|
|||||||
|
|
||||||
public WatchItem SetStreams(ILibraryManager libraryManager)
|
public WatchItem SetStreams(ILibraryManager libraryManager)
|
||||||
{
|
{
|
||||||
(IEnumerable<Track> audios, IEnumerable<Track> subtitles) streams = libraryManager.GetStreams(episodeID, Link);
|
(Track video, IEnumerable<Track> audios, IEnumerable<Track> subtitles) streams = libraryManager.GetStreams(episodeID, Link);
|
||||||
|
|
||||||
|
container = Path.Substring(Path.LastIndexOf('.') + 1);
|
||||||
|
video = streams.video;
|
||||||
audios = streams.audios;
|
audios = streams.audios;
|
||||||
subtitles = streams.subtitles;
|
subtitles = streams.subtitles;
|
||||||
return this;
|
return this;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user