extratorSRT.cpp 5.74 KB
#include "extratorSRT.h"
#include <iostream>

ExtratorSRT::ExtratorSRT(){
    listeners = new list<ListenerSub*>();
    finish = false;
    seek_pos = 0;
    hasNextSub = true;
    PRINTL(util::_DEBUG, "ExtratorSTR Done!\n");
}

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

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

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

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

void ExtratorSRT::encodingfiletoUTF8() {
    string iconvcmd = "iconv -f"; //Recodifica o arquivo para utf-8

    iconvcmd.append(" $(file --mime-encoding -b ")
    .append(this->filePath).append(") -t utf-8 ")
    .append(this->filePath).append(" > ").append(TEMP_SRT);
    system(iconvcmd.c_str());

    string perlcmd = "perl -p -e 's/\r$//' < "; //Formata a quebra de linha

    perlcmd.append(TEMP_SRT).append(" > ").append(this->filePath)
    .append(" && rm -f ").append(TEMP_SRT);
    system(perlcmd.c_str());
}

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

void ExtratorSRT::initialize(){

  file = new lavidlib::File(this->filePath);

	try{
		file_io = new lavidlib::FileIO(file->getPath(), FileIO::MODE_READ);
	}catch(Exception &ex){
		finish = true;
    Logging::instance()->writeLog("extratorSRT.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();

}

bool ExtratorSRT::isFinished(){
    return finish;
}

bool ExtratorSRT::hasNextSubtitle() {
    return hasNextSub;
}

void ExtratorSRT::Run(){
    PRINTL(util::_INFO, "Extraindo Legendas...\n");
    int sub_index = 0;
    string sub_text = "";
    while(hasNextSubtitle()){
        try{
            subtitle = next();
        }catch(ExtratorException ex){
          break;
        }
        sub_text = subtitle->getSubtitleText();
        notifyListeners((unsigned char*)sub_text.c_str(), calcula_pts((double) subtitle->getTimeIn()));
        sub_index++;
        free(subtitle);
    }
    if(sub_index == 0)
        notifyListeners((unsigned char*)"ARQUIVO_INVALIDO", 0);

    finish = true;
    notifyEndExtraction(sub_index);
}

Subtitle* ExtratorSRT::next() {

        file_io->seek(seek_pos);
        try{
            bff_reader = new BufferedReader(file_io);
        }catch(Exception &ex){
            Logging::instance()->writeLog("extratorSRT.cpp <Error>: BufferedReader não inicializado.");
            throw ExtratorException("O BufferedReader não foi inicializado.");
        }

        Subtitle* sub = new Subtitle();
        string line = "";
        string text_sub = "";

        try {
            /* ID */
            int id = 0;
            line = bff_reader->readLine();
            seek_pos += (int64_t) line.size() + SIZE_CSCAPE;
            id = atoi(line.c_str());
            sub->setID(id);

            /* TimeIn and TimeOut */
            int64_t t_in = 0, t_out = 0;
            line = bff_reader->readLine();
            seek_pos += (int64_t) line.size() + SIZE_CSCAPE;

            int target_pos = line.find(TARGET_TIME);
            t_in = str_to_time(line.substr(0, target_pos));
            sub->setTimeIn(t_in);
            t_out = str_to_time(line.substr(target_pos + strlen(TARGET_TIME)+1, line.size()));
            sub->setTimeOut(t_out);

            /* Text: read until line be empty */
            while ((line = bff_reader->readLine()).size() > 0) {
                text_sub += line;
                text_sub.append(" ");
            }
            seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE;

        } catch (lavidlib::EOFException &ex) {
            sub->setSubtitleText(formatText(text_sub));
            seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE;
            hasNextSub = false;
            delete(bff_reader);
            return sub;
        }
        sub->setSubtitleText(formatText(text_sub));
        delete(bff_reader);
        return sub;
    }

string ExtratorSRT::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 ExtratorSRT::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;

    }

uint64_t ExtratorSRT::calcula_pts(double msec) {
    return (uint64_t)msec;
}