mirror of
https://github.com/zoriya/Kyoo.git
synced 2025-07-07 18:24:14 -04:00
Making subtitle extraction algorithm.
This commit is contained in:
parent
5baf78fdde
commit
c4f1214092
@ -8,47 +8,125 @@ extern "C"
|
|||||||
#include <libavutil/dict.h>
|
#include <libavutil/dict.h>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int Init()
|
int Init()
|
||||||
{
|
{
|
||||||
return 42;
|
return 42;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractSubtitles(const char* path)
|
void ExtractSubtitles(const char* path, const char* outPath)
|
||||||
{
|
{
|
||||||
AVFormatContext* formatContext = NULL;
|
AVFormatContext* inputContext = NULL;
|
||||||
|
|
||||||
if (avformat_open_input(&formatContext, path, NULL, NULL))
|
if (avformat_open_input(&inputContext, path, NULL, NULL))
|
||||||
{
|
{
|
||||||
std::cout << "Error: Can't open the file at " << path << std::endl;
|
std::cout << "Error: Can't open the file at " << path << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avformat_find_stream_info(formatContext, NULL) < 0)
|
if (avformat_find_stream_info(inputContext, NULL) < 0)
|
||||||
{
|
{
|
||||||
std::cout << "Error: Could't find streams informations for the file at " << path << std::endl;
|
std::cout << "Error: Could't find streams informations for the file at " << path << std::endl;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < formatContext->nb_streams; i++)
|
for (unsigned int i = 0; i < inputContext->nb_streams; i++)
|
||||||
{
|
{
|
||||||
AVStream* stream = formatContext->streams[i];
|
AVStream* inputStream = inputContext->streams[i];
|
||||||
const AVCodecContext* streamContext = stream->codec;
|
const AVCodecParameters* inputCodecpar = inputStream->codecpar;
|
||||||
|
|
||||||
if (streamContext->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
if (inputCodecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||||
{
|
{
|
||||||
const AVCodec* dec = streamContext->codec;
|
const char* output = outPath;
|
||||||
std::cout << "Stream #" << i << ", stream type: " << streamContext->codec_type << " codec: " << dec->long_name << std::endl;
|
const AVCodec* codec = avcodec_find_decoder(inputCodecpar->codec_id);
|
||||||
|
std::cout << "Stream #" << i << ", stream type: " << inputCodecpar->codec_type << " codec: " << codec->name << " long name: " << codec->long_name << std::endl;
|
||||||
|
|
||||||
|
AVFormatContext* outputContext = NULL;
|
||||||
|
if (avformat_alloc_output_context2(&outputContext, NULL, NULL, output) < 0)
|
||||||
|
{
|
||||||
|
std::cout << "Error: Couldn't create an output file." << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVStream* outputStream = avformat_new_stream(outputContext, codec);
|
||||||
|
if (outputStream == NULL)
|
||||||
|
{
|
||||||
|
std::cout << "Error: Couldn't create stream." << std::endl;
|
||||||
|
avformat_free_context(outputContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVCodecParameters* outputCodecpar = outputStream->codecpar;
|
||||||
|
avcodec_parameters_copy(outputCodecpar, inputCodecpar);
|
||||||
|
|
||||||
|
//outputStream->disposition = inputStream->disposition;
|
||||||
|
|
||||||
|
//if (inputStream->nb_side_data)
|
||||||
|
//{
|
||||||
|
// for (int i = 0; i < inputStream->nb_side_data; i++)
|
||||||
|
// {
|
||||||
|
// std::cout << "Copying side packet #" << i << std::endl;
|
||||||
|
|
||||||
|
// AVPacketSideData* sidePkt = &inputStream->side_data[i];
|
||||||
|
// uint8_t* newPkt = av_stream_new_side_data(outputStream, sidePkt->type, sidePkt->size);
|
||||||
|
// if (newPkt == NULL)
|
||||||
|
// {
|
||||||
|
// std::cout << "Error copying side package." << std::endl;
|
||||||
|
// //Should handle return here
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// memcpy(newPkt, sidePkt->data, sidePkt->size);
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
if (avio_open(&outputContext->pb, output, AVIO_FLAG_WRITE) < 0)
|
||||||
|
{
|
||||||
|
std::cout << "Error: Couldn't open file at " << output << std::endl;
|
||||||
|
avformat_free_context(outputContext);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (avformat_write_header(outputContext, NULL) < 0)
|
||||||
|
{
|
||||||
|
std::cout << "Error: Couldn't write headers to file at " << output << std::endl;
|
||||||
|
avformat_free_context(outputContext);
|
||||||
|
avio_closep(&outputContext->pb);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
AVPacket pkt;
|
||||||
|
int i = 0;
|
||||||
|
while (av_read_frame(inputContext, &pkt) == 0)
|
||||||
|
{
|
||||||
|
if (pkt.stream_index != inputStream->index)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
std::cout << "Reading packet... " << i << std::endl;
|
||||||
|
i++;
|
||||||
|
|
||||||
|
pkt.pts = av_rescale_q_rnd(pkt.pts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF);
|
||||||
|
pkt.dts = av_rescale_q_rnd(pkt.dts, inputStream->time_base, outputStream->time_base, AV_ROUND_NEAR_INF);
|
||||||
|
pkt.duration = av_rescale_q(pkt.duration, inputStream->time_base, outputStream->time_base);
|
||||||
|
pkt.pos = -1;
|
||||||
|
pkt.stream_index = 0;
|
||||||
|
|
||||||
|
if (av_interleaved_write_frame(outputContext, &pkt) < 0)
|
||||||
|
{
|
||||||
|
//Should handle packet copy error;
|
||||||
|
}
|
||||||
|
|
||||||
|
av_packet_unref(&pkt);
|
||||||
|
}
|
||||||
|
av_write_trailer(outputContext);
|
||||||
|
|
||||||
|
avio_closep(&outputContext->pb);
|
||||||
|
avformat_free_context(outputContext);
|
||||||
|
|
||||||
|
goto end;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//const char* outputPath = "subtitle.ass";
|
end:
|
||||||
//if (avformat_alloc_output_context2(&formatContext, NULL, NULL, outputPath) < 0)
|
avformat_close_input(&inputContext);
|
||||||
//{
|
|
||||||
// std::cout << "Error: Can't create output file at " << outputPath << std::endl;
|
|
||||||
// return;
|
|
||||||
//}
|
|
||||||
|
|
||||||
avformat_close_input(&formatContext);
|
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
@ -11,4 +11,4 @@
|
|||||||
|
|
||||||
extern "C" API int Init();
|
extern "C" API int Init();
|
||||||
|
|
||||||
extern "C" API void ExtractSubtitles(const char* path);
|
extern "C" API void ExtractSubtitles(const char* path, const char* outPath);
|
||||||
|
@ -31,12 +31,12 @@ namespace Kyoo.Controllers
|
|||||||
}
|
}
|
||||||
|
|
||||||
[HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
[HttpGet("extract/{showSlug}-s{seasonNumber}e{episodeNumber}")]
|
||||||
public IActionResult ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
public string ExtractSubtitle(string showSlug, long seasonNumber, long episodeNumber)
|
||||||
{
|
{
|
||||||
Episode episode = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
Episode episode = libraryManager.GetEpisode(showSlug, seasonNumber, episodeNumber);
|
||||||
transcoder.ExtractSubtitles(episode.Path);
|
transcoder.ExtractSubtitles(episode.Path);
|
||||||
|
|
||||||
return null;
|
return "Processing...";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
using Kyoo.InternalAPI.TranscoderLink;
|
using Kyoo.InternalAPI.TranscoderLink;
|
||||||
using Microsoft.Extensions.Configuration;
|
using Microsoft.Extensions.Configuration;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
namespace Kyoo.InternalAPI
|
namespace Kyoo.InternalAPI
|
||||||
{
|
{
|
||||||
@ -13,7 +14,9 @@ namespace Kyoo.InternalAPI
|
|||||||
|
|
||||||
public void ExtractSubtitles(string path)
|
public void ExtractSubtitles(string path)
|
||||||
{
|
{
|
||||||
TranscoderAPI.ExtractSubtitles(path);
|
string output = Path.GetDirectoryName(path);
|
||||||
|
output = Path.Combine(output, "fre\\output.ass");
|
||||||
|
TranscoderAPI.ExtractSubtitles(path, output);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void GetVideo(string path)
|
public void GetVideo(string path)
|
||||||
|
@ -10,6 +10,6 @@ namespace Kyoo.InternalAPI.TranscoderLink
|
|||||||
public extern static int Init();
|
public extern static int Init();
|
||||||
|
|
||||||
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
[DllImport(TranscoderPath, CallingConvention = CallingConvention.Cdecl)]
|
||||||
public extern static void ExtractSubtitles(string path);
|
public extern static void ExtractSubtitles(string path, string outPath);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user