extratorVTT.cpp 4.01 KB
#include "extratorVTT.h"

ExtratorVTT::ExtratorVTT() {
	listeners = new list<ListenerSub*>();
	seekPos = 0;
	this->finish = false;
	hasNextCue = true;
	PRINTL(util::_DEBUG, "ExtratorVTT Done!\n");
}

ExtratorVTT::~ExtratorVTT() {
	listeners->clear(); 
    delete listeners;
    if (bff_reader) delete bff_reader;
    if (file_io) delete file_io;
    PRINTL(util::_DEBUG, "ExtratorVTT finalized!\n");
}

void ExtratorVTT::setFilePath(char* path) {
	this->filePath = path;
}

bool ExtratorVTT::isFinished() {
	return this->finish;
}

void ExtratorVTT::addListener(ListenerSub* listener){
    listeners->push_back(listener);
}

void ExtratorVTT::notifyListeners(unsigned char* subtitle, uint64_t pts) {
	for(list<ListenerSub*>::iterator it = listeners->begin(); it != listeners->end(); it++){
        (*it)->notifySubtitle(subtitle, pts);
    }  
}

void ExtratorVTT::notifyEndExtraction(int size) {
	PRINTL(util::_DEBUG, "Extrator webVTT concluiu a extração: %d legendas.\n", size);
    for(list<ListenerSub*>::iterator it = listeners->begin(); it != listeners->end(); it++){
        (*it)->notifyEnd(size);
    }
}

void ExtratorVTT::initialize() {
	file = new lavidlib::File(this->filePath);

	try{
		file_io = new lavidlib::FileIO(file->getPath(), FileIO::MODE_READ);
		bff_reader = new BufferedReader(file_io);
	}catch(Exception &ex){
		finish = true;
        Logging::instance()->writeLog("extratorVTT.cpp <Error>: Arquivo de legenda não encontrado.");
        throw lavidlib::RuntimeException("Falha ao abrir o arquivo de legenda! Verifique se o mesmo existe.\n");
	}
	this->Start();
}

Subtitle* ExtratorVTT::nextCue() {
	string line;
	string cueText = "";
	int target_pos;
	int64_t time_in;

	Subtitle* cue = new Subtitle();

	try{
		do{
			line = bff_reader->readLine();
			seekPos += line.size() + SIZE_SCAPE;
		}while(line.find(TARGET_TIME) == string::npos);

		target_pos = line.find(TARGET_TIME);
		time_in = str_to_time(line.substr(0, target_pos));
		cue->setTimeIn(time_in);

		while((line = bff_reader->readLine()) != ""){
			cueText += line;
			cueText += " ";
		}

	}catch(lavidlib::EOFException &ex){
		cue->setSubtitleText(formatText(cueText));
		seekPos += (int64_t) cueText.size() + SIZE_SCAPE;
		hasNextCue =false;
		return cue;
	}

	cue->setSubtitleText(formatText(cueText));
	seekPos += (int64_t) cueText.size() + SIZE_SCAPE;
	return cue;
}

string ExtratorVTT::formatText(string line){
	int lessThanPos;
	int moreThanPos;
	string f_line = line;

	lessThanPos = f_line.find_first_of(LESS_THAN); //pega a posição do simbolo '<'
	moreThanPos = f_line.find_first_of(MORE_THAN); //pega a posição do simbolo '>'

	while(lessThanPos != string::npos && moreThanPos != string::npos){
		f_line = f_line.erase(lessThanPos, moreThanPos - (lessThanPos-1)); //remove o trecho '<string>'
		lessThanPos = f_line.find_first_of(LESS_THAN);
		moreThanPos = f_line.find_first_of(MORE_THAN);
	}
	return f_line;
}

int64_t ExtratorVTT::str_to_time(string str_time) {
        int64_t ttime = 0;
        char* tokens = new char[4]; // hh, mm, ss, ms
        strcpy(tokens, (char*)str_time.c_str());

        int index = 0;
        int values [4]; // hh, mm, ss, ms
        char * str = strtok(tokens, ":,.");      
        while (str != NULL) {
            values[index] = atoi(str);
            str = strtok(NULL, ":,.");
            index++;
        }
        delete(tokens);

        /* calculate time */
        ttime = /*hour to sec*/((((values[0] * 60) * 60) + 
            /*min to sec*/(values[1] * 60) +/*sec*/values[2])*1000) + values[3];

        return ttime;
}

void ExtratorVTT::Run() {
	PRINTL(util::_INFO, "Extraindo Legendas...\n");
	
    int sub_index = 0;
    string cue_text = "";
    while(hasNextCue){
        subtitle = nextCue();
        cue_text = subtitle->getSubtitleText();
        notifyListeners((unsigned char*)cue_text.c_str(), (uint64_t) subtitle->getTimeIn());
        sub_index++;
        free(subtitle);
    }
    if(sub_index == 0)
        notifyListeners((unsigned char*)"ARQUIVO_INVALIDO", 0);
    this->finish = true;
    notifyEndExtraction(sub_index);
}