Adding video and audio codec detection in the crawler.

Adding multiple audio support for the playback method detector.
This commit is contained in:
Zoe Roux 2019-11-24 23:22:25 +01:00
parent f776a00853
commit 690048e720
15 changed files with 167 additions and 50 deletions

View File

@ -1,10 +1,4 @@
#pragma once
#ifdef TRANSCODER_EXPORTS
#define API __declspec(dllexport)
#else
#define API __declspec(dllimport)
#endif
#include <iostream>
#include <sstream>
@ -18,20 +12,38 @@ extern "C" struct Stream
char *path;
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)
: 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);
if (languageCode != NULL)
if (languageCode != nullptr)
language = strdup(languageCode);
else
language = strdup("und");
if (codec != NULL)
if (codec != nullptr)
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);
}
};

View File

@ -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 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.
extern "C" API Stream* extract_subtitles(const char *path, const char *outPath, int *streamCount, int *subtitleCount);

View File

@ -98,6 +98,43 @@ int transmux(const char *path, const char *out_path, float *playable_duration)
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)
{
@ -124,7 +161,10 @@ Stream *extract_subtitles(const char *path, const char *out_path, int *stream_co
const AVCodecParameters *in_codecpar = in_stream->codecpar;
if (in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE)
{
output_list[i] = NULL;
streams[i] = Stream();
}
else
{
*subtitle_count += 1;

View File

@ -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>
</div>
<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>
</button>
<button *ngIf="this.item.subtitles.length > 0" mat-icon-button [matMenuTriggerFor]="subtitles" matTooltipPosition="above" matTooltip="Select subtitle track">

View File

@ -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 (!browser)
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) &&
audioCodecIsSupported(player, item.audios.map(function (value) { return value.codec; }), browser.name))
return method.direct;

View File

@ -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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"}

View File

@ -16,7 +16,7 @@ export function getPlaybackMethod(player: HTMLVideoElement, item: WatchItem): me
if (!browser)
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) &&
audioCodecIsSupported(player, item.audios.map((value: Track) => value.codec), browser.name))

View File

@ -252,14 +252,21 @@ namespace Kyoo.InternalAPI
episode.SeasonID = seasonID;
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 (!FindExtractedSubtitles(episode))
{
Track[] tracks = await transcoder.ExtractSubtitles(episode.Path);
if (tracks != null)
Track[] subtitles = await transcoder.ExtractSubtitles(episode.Path);
if (subtitles != null)
{
foreach (Track track in tracks)
foreach (Track track in subtitles)
{
track.episodeID = episode.id;
libraryManager.RegisterTrack(track);

View File

@ -19,8 +19,8 @@ namespace Kyoo.InternalAPI
IEnumerable<Show> GetShowsByPeople(long peopleID);
IEnumerable<string> GetLibrariesPath();
//Internal HTML read
(List<Track> audios, List<Track> subtitles) GetStreams(long episodeID, string showSlug);
//Internal read
(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);
//Public read

View File

@ -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;";
@ -233,6 +233,7 @@ namespace Kyoo.InternalAPI
cmd.Parameters.AddWithValue("$episodeID", episodeID);
SQLiteDataReader reader = cmd.ExecuteReader();
Track video = null;
List<Track> audios = new List<Track>();
List<Track> subtitles = new List<Track>();
@ -240,13 +241,15 @@ namespace Kyoo.InternalAPI
{
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);
else if (track.type == StreamType.Subtitle)
subtitles.Add(track);
}
return (audios, subtitles);
return (video, audios, subtitles);
}
}

View File

@ -12,6 +12,9 @@ namespace Kyoo.InternalAPI
// Should transcode to a mp4 container with a h264 video format and a AAC audio format, no subtitles.
Task<string> Transcode(WatchItem episode);
// 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);
}

View File

@ -20,6 +20,15 @@ namespace Kyoo.InternalAPI
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)
{
string output = Path.Combine(Path.GetDirectoryName(path), "Subtitles");

View File

@ -17,18 +17,51 @@ namespace Kyoo.InternalAPI.TranscoderLink
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
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)]
private extern static IntPtr extract_subtitles(string path, string out_path, out int array_length, out int track_count);
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
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)
{
int size = Marshal.SizeOf<Stream>();
IntPtr ptr = extract_subtitles(path, outPath, out int arrayLength, out int trackCount);
IntPtr streamsPtr = ptr;
if (trackCount > 0 && ptr != IntPtr.Zero)
{
tracks = new Track[trackCount];

View File

@ -11,7 +11,7 @@ namespace Kyoo.Models
{
public enum StreamType
{
Audio, Subtitle, Unknow
Video, Audio, Subtitle, Unknow
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
@ -77,6 +77,8 @@ namespace Kyoo.Models
}
public Track SetLink(string episodeSlug)
{
if (type == StreamType.Subtitle)
{
string language = Language;
//Converting mkv track language to c# system language tag.
@ -99,7 +101,9 @@ namespace Kyoo.Models
Link += ".ass";
else if (Codec == "subrip")
Link += ".srt";
}
else
Link = null;
return this;
}
}

View File

@ -1,5 +1,4 @@
using Kyoo.InternalAPI;
using Kyoo.Models.Watch;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
@ -21,6 +20,8 @@ namespace Kyoo.Models
public string previousEpisode;
public Episode nextEpisode;
public string container;
public Track video;
public IEnumerable<Track> audios;
public IEnumerable<Track> subtitles;
@ -60,7 +61,10 @@ namespace Kyoo.Models
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;
subtitles = streams.subtitles;
return this;