ccextractor是一个字幕提取工具,可以从mpeg文件中提取字幕。它支持HDTV、DVD和电视,可以进行搜索,兼容几乎所有的字幕文件格式。
init_options (&ccx_options); //初始化选项配置结构体;
parse_configuration(&ccx_options);
//解析文件ccextractor.cnf里面的配置
ret = parse_parameters (&ccx_options, argc, argv);
//解析附加的额外参数;
//初始化用到的demux
ctx = init_libraries(&ccx_options);
.........
#ifdef WITH_LIBCURL
curl_global_init(CURL_GLOBAL_ALL);
/* get a curl handle */
curl = curl_easy_init();
if (!curl)
{
curl_global_cleanup(); // Must be done even on init fail
fatal (EXIT_NOT_CLASSIFIED, "Unable to init curl.");
}
#endif
int show_myth_banner = 0;
params_dump(ctx);
// default teletext page
if (tlt_config.page > 0) {
// dec to BCD, magazine pages numbers are in BCD (ETSI 300 706)
tlt_config.page = ((tlt_config.page / 100) << 8) | (((tlt_config.page / 10) % 10) << 4) | (tlt_config.page % 10);
}
if (ccx_options.transcript_settings.xds)
{
if (ccx_options.write_format != CCX_OF_TRANSCRIPT)
{
ccx_options.transcript_settings.xds = 0;
mprint ("Warning: -xds ignored, XDS can only be exported to transcripts at this time.\n");
}
}
time_t start, final;
time(&start);
if (ccx_options.binary_concat)
{
ctx->total_inputsize=get_total_file_size(ctx);
if (ctx->total_inputsize < 0)
{
switch (ctx->total_inputsize)
{
case -1*ENOENT:
fatal(EXIT_NO_INPUT_FILES, "Failed to open file: File does not exist.");
case -1*EACCES:
fatal(EXIT_READ_ERROR, "Failed to open file: Unable to access");
case -1*EINVAL:
fatal(EXIT_READ_ERROR, "Failed to open file: Invalid opening flag.");
case -1*EMFILE:
fatal(EXIT_TOO_MANY_INPUT_FILES, "Failed to open file: Too many files are open.");
default:
fatal(EXIT_READ_ERROR, "Failed to open file: Reason unknown");
}
}
}
.....................
terminate_asap = 0;
#ifdef ENABLE_SHARING
if (ccx_options.translate_enabled && ctx->num_input_files > 1)
{
mprint(“[share] WARNING: simultaneous translation of several input files is not supported yet\n”);
ccx_options.translate_enabled = 0;
ccx_options.sharing_enabled = 0;
}
if (ccx_options.translate_enabled)
{
mprint(“[share] launching translate service\n”);
ccx_share_launch_translator(ccx_options.translate_langs, ccx_options.translate_key);
}
#endif //ENABLE_SHARING
ret = 0;
while (switch_to_next_file(ctx, 0))
{
prepare_for_new_file(ctx);
#ifdef ENABLE_SHARING
if (ccx_options.sharing_enabled)
ccx_share_start(ctx->basefilename);
#endif //ENABLE_SHARING
stream_mode = ctx->demux_ctx->get_stream_mode(ctx->demux_ctx);
// Disable sync check for raw formats - they have the right timeline.
// Also true for bin formats, but -nosync might have created a
// broken timeline for debug purposes.
// Disable too in MP4, specs doesn't say that there can't be a jump
switch (stream_mode)
{
case CCX_SM_MCPOODLESRAW:
case CCX_SM_RCWT:
case CCX_SM_MP4:
#ifdef WTV_DEBUG
case CCX_SM_HEX_DUMP:
#endif
ccx_common_timing_settings.disable_sync_check = 1;
break;
default:
break;
}
/* -----------------------------------------------------------------
主循环
----------------------------------------------------------------- */
switch (stream_mode)
{
case CCX_SM_ELEMENTARY_OR_NOT_FOUND:
if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
ccx_options.use_gop_as_pts = 1; // Force GOP timing for ES
ccx_common_timing_settings.is_elementary_stream = 1;
case CCX_SM_TRANSPORT:
case CCX_SM_PROGRAM:
case CCX_SM_ASF:
case CCX_SM_WTV:
case CCX_SM_GXF:
#ifdef ENABLE_FFMPEG
case CCX_SM_FFMPEG:
#endif
if (!ccx_options.use_gop_as_pts) // If !0 then the user selected something
ccx_options.use_gop_as_pts = 0;
if (ccx_options.ignore_pts_jumps)
ccx_common_timing_settings.disable_sync_check = 1;
mprint (“\rAnalyzing data in general mode\n”);
tmp = general_loop(ctx);
if (!ret) ret = tmp;
break;
case CCX_SM_MCPOODLESRAW:
mprint (“\rAnalyzing data in McPoodle raw mode\n”);
tmp = raw_loop(ctx);
if (!ret) ret = tmp;
break;
case CCX_SM_RCWT:
mprint (“\rAnalyzing data in CCExtractor’s binary format\n”);
tmp = rcwt_loop(ctx);
if (!ret) ret = tmp;
break;
case CCX_SM_MYTH:
mprint (“\rAnalyzing data in MythTV mode\n”);
show_myth_banner = 1;
tmp = myth_loop(ctx);
if (!ret) ret = tmp;
break;
case CCX_SM_MP4:
mprint (“\rAnalyzing data with GPAC (MP4 library)\n”);
close_input_file(ctx); // No need to have it open. GPAC will do it for us
if (ctx->current_file == -1) // We don’t have a file to open, must be stdin, and GPAC is incompatible with stdin
{
fatal (EXIT_INCOMPATIBLE_PARAMETERS, “MP4 requires an actual file, it’s not possible to read from a stream, including stdin.\n”);
}
if(ccx_options.extract_chapters)
{
tmp = dumpchapters(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
}
else
{
tmp = processmp4(ctx, &ctx->mp4_cfg, ctx->inputfile[ctx->current_file]);
}
if (ccx_options.print_file_reports)
print_file_report(ctx);
if (!ret) ret = tmp;
break;
#ifdef WTV_DEBUG
case CCX_SM_HEX_DUMP:
close_input_file(ctx); // process_hex will open it in text mode
process_hex (ctx, ctx->inputfile[0]);
break;
#endif
case CCX_SM_AUTODETECT:
fatal(CCX_COMMON_EXIT_BUG_BUG, “Cannot be reached!”);
break;
}
return EXIT_OK;
}
<div align=center>
![这里写图片描述](https://img-blog.csdn.net/20171116144128471?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvemhpeWFuemhhaTU2Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)