extratorSRT.cpp 5.17 KB
#include "extratorSRT.h"

ExtratorSRT::ExtratorSRT(){
    listeners = new list<ListenerSRT*>();
    finish = false;
    seek_pos = 0;
    hasNextSub = true;
    DPRINTF("Done!\n");
}

ExtratorSRT::~ExtratorSRT(){ 
    listeners->clear(); 
    delete listeners;
    //if (bff_reader) delete bff_reader;
    if (file_io) delete file_io;
    DDDPRINTF("ExtratorSTR finalized!\n");
}

void ExtratorSRT::initialize(){

    file = new lavidlib::File(filePath);

    try{
        file_io = new lavidlib::FileIO(file->getPath(), FileIO::MODE_READ);
    }catch(Exception ex){ 
        finish = true;
        Util::Logger::Instance()->writeLog((char*) "[ERRO: extratorSRT.cpp] Arquivo de legenda não encontrado.");
        throw ExtratorException("Falha ao abrir o arquivo de legenda! Verifique se o mesmo existe.\n");
    }
    
    this->Start();
}


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

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

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

void ExtratorSRT::setFilePath(char* path){
    filePath = (char*) path; 
    string command1 = "perl -p -e 's/\r$//' < ";
    command1.append(filePath).append(" > ").append(INPUT_SRT);
    system(command1.c_str());

    string command2 = "iconv -f";
    command2.append(" $(file --mime-encoding -b ")
    .append(INPUT_SRT).append(")")
    .append(" -t utf-8 ").append(INPUT_SRT).append(" > ").append(filePath)
    .append(" && rm -f ").append(INPUT_SRT);
    system(command2.c_str());
}

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

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

void ExtratorSRT::Run(){
    DPRINTF("[AGUARDE] 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_VAZIO", 0);
    finish = true;
    notifyEndExtraction(sub_index);
}

Subtitle* ExtratorSRT::next() {
        
        if (seek_pos >= file_io->getSize())
            throw ExtratorException("[ERRO: extratorSRT.cpp] Esse arquivo já foi lido.");
        
        file_io->seek(seek_pos);
        try{
            bff_reader = new BufferedReader(file_io);
        }catch(Exception &ex){
            throw ExtratorException("[ERRO: extratorSRT.cpp] 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(text_sub);
            seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE;
            hasNextSub = false;
            return sub;
        }
        sub->setSubtitleText(text_sub);
        delete(bff_reader);
        return sub;
    }
    
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)(1000 /*pcr_base*/ + ((msec/1000) * 90000.0));    
}