Skip to content

Instantly share code, notes, and snippets.

@pierotofy
Created May 8, 2023 19:28
Show Gist options
  • Save pierotofy/12038d4b1674444b1707be880c8ce4c8 to your computer and use it in GitHub Desktop.
Save pierotofy/12038d4b1674444b1707be880c8ce4c8 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <fstream>
#include <sstream>
extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/timestamp.h>
}
using namespace std;
int main(int argc, char** argv) {
if (argc != 2) {
cerr << "Usage: " << argv[0] << " <input_file>" << endl;
return 1;
}
const char* input_file = argv[1];
avformat_network_init();
AVFormatContext* format_context = nullptr;
int error = avformat_open_input(&format_context, input_file, nullptr, nullptr);
if (error != 0) {
cerr << "Failed to open input file" << endl;
return 1;
}
error = avformat_find_stream_info(format_context, nullptr);
if (error < 0) {
cerr << "Failed to find stream information" << endl;
return 1;
}
const AVCodec* codec = nullptr;
AVCodecParameters* codec_parameters = nullptr;
int stream_index = av_find_best_stream(format_context, AVMEDIA_TYPE_SUBTITLE, -1, -1, &codec, 0);
if (stream_index < 0) {
cerr << "Failed to find subtitle stream in input file" << endl;
return 1;
}
codec_parameters = format_context->streams[stream_index]->codecpar;
AVCodecContext* codec_context = avcodec_alloc_context3(codec);
if (!codec_context) {
cerr << "Failed to allocate codec context" << endl;
return 1;
}
error = avcodec_parameters_to_context(codec_context, codec_parameters);
if (error < 0) {
cerr << "Failed to copy codec parameters to codec context" << endl;
return 1;
}
error = avcodec_open2(codec_context, codec, nullptr);
if (error < 0) {
cerr << "Failed to open codec" << endl;
return 1;
}
AVPacket packet;
av_init_packet(&packet);
while (av_read_frame(format_context, &packet) >= 0) {
if (packet.stream_index == stream_index) {
AVSubtitle subtitle;
int got_subtitle;
error = avcodec_decode_subtitle2(codec_context, &subtitle, &got_subtitle, &packet);
if (error < 0) {
cerr << "Failed to decode subtitle" << endl;
}
if (got_subtitle) {
for (unsigned int i = 0; i < subtitle.num_rects; ++i) {
AVSubtitleRect* rect = subtitle.rects[i];
if (rect->type == SUBTITLE_ASS) {
std::cout << rect->ass;
}else if (rect->type == SUBTITLE_TEXT){
std::cout << "!" << rect->text;
}
}
avsubtitle_free(&subtitle);
}
}
av_packet_unref(&packet);
}
avformat_network_deinit();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment