Making subtitle extraction algorithm.

This commit is contained in:
Zoe Roux
2019-09-12 04:16:19 +02:00
parent 5baf78fdde
commit c4f1214092
5 changed files with 105 additions and 24 deletions
+97 -19
View File
@@ -8,47 +8,125 @@ extern "C"
#include <libavutil/dict.h>
}
int Init()
{
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;
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;
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];
const AVCodecContext* streamContext = stream->codec;
AVStream* inputStream = inputContext->streams[i];
const AVCodecParameters* inputCodecpar = inputStream->codecpar;
if (streamContext->codec_type == AVMEDIA_TYPE_SUBTITLE)
if (inputCodecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
{
const AVCodec* dec = streamContext->codec;
std::cout << "Stream #" << i << ", stream type: " << streamContext->codec_type << " codec: " << dec->long_name << std::endl;
const char* output = outPath;
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";
//if (avformat_alloc_output_context2(&formatContext, NULL, NULL, outputPath) < 0)
//{
// std::cout << "Error: Can't create output file at " << outputPath << std::endl;
// return;
//}
avformat_close_input(&formatContext);
end:
avformat_close_input(&inputContext);
return;
}
+1 -1
View File
@@ -11,4 +11,4 @@
extern "C" API int Init();
extern "C" API void ExtractSubtitles(const char* path);
extern "C" API void ExtractSubtitles(const char* path, const char* outPath);