extratorSRT.cpp 5.14 KB

#include "extratorSRT.h"


ExtratorSRT::ExtratorSRT(){
    listeners = new list<ListenerSRT*>();
    pcr_base = 0;
    finish = false;
    hasPCRBase = 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("Extractor STR 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 ExtratorSrtException("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 sub_size) {
    DDPRINTF("Extrator SRT concluiu a extração: %d legendas.\n", sub_size);
    for(list<ListenerSRT*>::iterator it = listeners->begin(); it != listeners->end(); it++){
        (*it)->notifyEnd(sub_size);
    }
}

void ExtratorSRT::setFilePath(char* path){
    filepath = (char*) path; 
    string command = "perl -p -e \'s/\n/ /\' ";
    command.append(filepath).append(" > /dev/null");
    system(command.c_str());
}

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

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

void ExtratorSRT::Run(){
    printf("\n");
    DDPRINTF("[AGUARDE] Extraindo SRT...\n");

    int sub_index = 0;
    string sub_text = "";
  
    while(hasNextSubtitle()){
        subtitle = next();
        sub_text = subtitle->getSubtitleText();
        notifyListeners((unsigned char*)sub_text.c_str(), calcula_pts((double) subtitle->getTimeIn()));
        cout << " . ";
        sub_index++;
        free(subtitle);
    }
    printf("\n");
    finish = true;
    notifyEndExtraction(sub_index);
}

Subtitle* ExtratorSRT::next() {
        
        if (seek_pos >= file_io->getSize())
            throw ExtratorSrtException("[ERRO: extratorSRT.cpp] Esse arquivo já foi lido.");
        
        file_io->seek(seek_pos);
        try{
            bff_reader = new BufferedReader(file_io);
        }catch(Exception &ex){
            throw ExtratorSrtException("[ERRO: extratorSRT.cpp] O BufferedReader não foi inicializado.");
        }

        Subtitle* sub = new Subtitle();
        std::string line = "";      
        std::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);
            sub->setStatusOfReady(true);
            //delete(bff_reader);
            seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE;
            hasNextSub = false;
            return sub;
        }
        sub->setSubtitleText(text_sub);
        sub->setStatusOfReady(true);
        delete(bff_reader);
        return sub;

    }


int64_t ExtratorSRT::str_to_time(std::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 ExtratorSRT::notifyPCRBase(uint64_t pcrbase){
    //DDPRINTF("PCRBase = %ld\n", pcrbase);
    this->pcr_base = pcrbase;
    this->hasPCRBase = true;
}

uint64_t ExtratorSRT::calcula_pts(double msec) {
    return (uint64_t)(pcr_base + ((msec/1000) * 90000.0));    
}