Finishing the c++ library for extracting subtitles.

This commit is contained in:
Zoe Roux 2019-09-17 01:09:07 +02:00
parent 2835f75c69
commit 1ce584d087
6 changed files with 31 additions and 23 deletions

View File

@ -6,6 +6,7 @@
#endif #endif
#include <iostream> #include <iostream>
#include <sstream>
extern "C" struct Stream extern "C" struct Stream
{ {
@ -14,8 +15,8 @@ extern "C" struct Stream
const char* codec; const char* codec;
bool isDefault; bool isDefault;
bool isForced; bool isForced;
const char* path; char* path;
Stream(const char* title, const char* languageCode, const char* codec, bool isDefault, bool isForced, const char* path) Stream(const char* title, const char* languageCode, const char* codec, bool isDefault, bool isForced, char* path)
: title(title), language(languageCode), codec(codec), isDefault(isDefault), isForced(isForced), path(path) { } : title(title), language(languageCode), codec(codec), isDefault(isDefault), isForced(isForced), path(path) { }
}; };

View File

@ -54,22 +54,18 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
else else
{ {
//Get metadata for file name //Get metadata for file name
Stream stream("title", //title Stream stream(NULL, //title
av_dict_get(inputStream->metadata, "language", NULL, 0)->value, //language av_dict_get(inputStream->metadata, "language", NULL, 0)->value, //language
avcodec_get_name(inputCodecpar->codec_id), //format avcodec_get_name(inputCodecpar->codec_id), //format
inputStream->disposition & AV_DISPOSITION_DEFAULT, //isDefault inputStream->disposition & AV_DISPOSITION_DEFAULT, //isDefault
inputStream->disposition & AV_DISPOSITION_FORCED, //isForced inputStream->disposition & AV_DISPOSITION_FORCED, //isForced
NULL); //The path is assigned afterward. NULL); //Path builder references
subtitleStreams->push_back(stream); //Create the language subfolder
std::stringstream outStream /*= new std::stringstream()*/;
std::cout << "Stream #" << i << "(" << stream.language << "), stream type: " << inputCodecpar->codec_type << " codec: " << stream.codec << std::endl;
//Create output folder
std::stringstream outStream;
outStream << outPath << (char)std::filesystem::path::preferred_separator << stream.language; outStream << outPath << (char)std::filesystem::path::preferred_separator << stream.language;
std::filesystem::create_directory(outStream.str()); std::filesystem::create_directory(outStream.str());
//Get file name //Get file name
std::string fileName(path); std::string fileName(path);
size_t lastSeparator = fileName.find_last_of((char)std::filesystem::path::preferred_separator); size_t lastSeparator = fileName.find_last_of((char)std::filesystem::path::preferred_separator);
@ -83,14 +79,16 @@ Stream* ExtractSubtitles(const char* path, const char* outPath, int* streamCount
if (stream.isForced) if (stream.isForced)
outStream << ".forced"; outStream << ".forced";
if (stream.codec == "subrip") if (strcmp(stream.codec, "subrip") == 0)
outStream << ".srt"; outStream << ".srt";
else if(stream.codec == "ass") else if (strcmp(stream.codec, "ass") == 0)
outStream << ".ass"; outStream << ".ass";
std::string outStr = outStream.str(); stream.path = _strdup(outStream.str().c_str());
stream.path = outStr.c_str();
subtitleStreams->push_back(stream);
std::cout << "Stream #" << i << "(" << stream.language << "), stream type: " << inputCodecpar->codec_type << " codec: " << stream.codec << std::endl;
AVFormatContext* outputContext = NULL; AVFormatContext* outputContext = NULL;
if (avformat_alloc_output_context2(&outputContext, NULL, NULL, stream.path) < 0) if (avformat_alloc_output_context2(&outputContext, NULL, NULL, stream.path) < 0)

View File

@ -61,10 +61,10 @@
<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 *ngIf="this.item.audios != null" mat-icon-button data-toggle="tooltip" data-placement="top" title="Select audio track"> <button *ngIf="this.item.audios.length > 0" mat-icon-button data-toggle="tooltip" data-placement="top" title="Select audio track">
<mat-icon>music_note</mat-icon> <mat-icon>music_note</mat-icon>
</button> </button>
<button *ngIf="this.item.subtitles != null" mat-icon-button data-toggle="tooltip" data-placement="top" title="Select subtitle track"> <button *ngIf="this.item.subtitles.length > 0" mat-icon-button data-toggle="tooltip" data-placement="top" title="Select subtitle track">
<mat-icon>closed_caption</mat-icon> <mat-icon>closed_caption</mat-icon>
</button> </button>
<button mat-icon-button data-toggle="tooltip" data-placement="top" title="Cast"> <button mat-icon-button data-toggle="tooltip" data-placement="top" title="Cast">

View File

@ -217,7 +217,7 @@ namespace Kyoo.InternalAPI
public Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag) public Track GetSubtitle(string showSlug, long seasonNumber, long episodeNumber, string languageTag)
{ {
string query = "SELECT tracks.* FROM tracks JOIN episodes ON tracks.episodeID = episodes.id JOIN shows ON episodes.showID = shows.id WHERE shows.showSlug = $showSlug AND episodes.seasonNumber = $seasonNumber AND episodes.episodeNumber = $episodeNumber AND tracks.language = $languageTag;"; string query = "SELECT tracks.* FROM tracks JOIN episodes ON tracks.episodeID = episodes.id JOIN shows ON episodes.showID = shows.id WHERE shows.slug = $showSlug AND episodes.seasonNumber = $seasonNumber AND episodes.episodeNumber = $episodeNumber AND tracks.language = $languageTag;";
using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection)) using (SQLiteCommand cmd = new SQLiteCommand(query, sqlConnection))
{ {

View File

@ -26,8 +26,7 @@ namespace Kyoo.InternalAPI.TranscoderLink
for (int i = 0; i < length; i++) for (int i = 0; i < length; i++)
{ {
tracks[i] = (Track)Marshal.PtrToStructure<Stream>(streamsPtr); tracks[i] = Track.From(Marshal.PtrToStructure<Stream>(streamsPtr), StreamType.Subtitle);
tracks[i].type = StreamType.Subtitle;
streamsPtr += size; streamsPtr += size;
} }
} }

View File

@ -30,14 +30,14 @@ namespace Kyoo.Models
[JsonIgnore] public StreamType type; [JsonIgnore] public StreamType type;
[JsonIgnore] public bool IsExternal; [JsonIgnore] public bool IsExternal;
public Track(StreamType type, string title, string language, bool isDefault, bool isForced, string format, bool isExternal, string path) public Track(StreamType type, string title, string language, bool isDefault, bool isForced, string codec, bool isExternal, string path)
{ {
this.type = type; this.type = type;
Title = title; Title = title;
Language = language; Language = language;
IsDefault = isDefault; IsDefault = isDefault;
IsForced = isForced; IsForced = isForced;
Codec = format; Codec = codec;
IsExternal = isExternal; IsExternal = isExternal;
Path = path; Path = path;
} }
@ -53,5 +53,15 @@ namespace Kyoo.Models
reader["isExternal"] as bool? ?? false, reader["isExternal"] as bool? ?? false,
reader["path"] as string); reader["path"] as string);
} }
public static Track From(Stream stream)
{
return new Track(StreamType.Unknow, stream.Title, stream.Language, stream.IsDefault, stream.IsForced, stream.Codec, false, stream.Path);
}
public static Track From(Stream stream, StreamType type)
{
return new Track(type, stream.Title, stream.Language, stream.IsDefault, stream.IsForced, stream.Codec, false, stream.Path);
}
} }
} }