serviceWindowGenerationFromSubtitle.cpp 8.79 KB
#include "serviceWindowGenerationFromSubtitle.h"

ServiceWindowGenerationFromSubtitle::ServiceWindowGenerationFromSubtitle(char* pathVideo, char* pathSRT, int sublanguage,
	int pos, int size, int transp, char* id, int mode, int serviceType) {

	this->path_input = pathVideo;
	this->path_srt = pathSRT;
	this->sub_language = sublanguage;
	this->position = pos;
	this->size = size;
	this->transparency = transp;
	this->user_id = id;
	this->exec_mode = mode;
	this->service_type = serviceType;
	numero_legendas = INT_MAX;
    legendas_enviadas = 0;
	vetor_pts = new vector<int64_t >();
	extrator_factory = new ExtratorFactory();
	try{
        setPathContents();
    }catch(RuntimeException ex){
        throw ServiceException(ex.getMessage());
    }
	running = true;
	finish = false;
	PRINTL(util::_DEBUG, "Service Subtitle Done!\n");
}

ServiceWindowGenerationFromSubtitle::ServiceWindowGenerationFromSubtitle(char* pathSRT, int sublanguage, int transp, char* id, int mode, int serviceType) {
	this->path_srt = pathSRT;
    this->sub_language = sublanguage;
	this->transparency = transp;
	this->user_id = id;
	this->exec_mode = mode;
	this->service_type = serviceType;
	numero_legendas = INT_MAX;
    legendas_enviadas = 0;
	vetor_pts = new vector<int64_t >();
	extrator_factory = new ExtratorFactory();
	try{
        setPathContents();
    }catch(RuntimeException ex){
        throw ServiceException(ex.getMessage());
    }
	running = true;
	finish = false;
	PRINTL(util::_DEBUG, "Service Subtitle Done!\n");
}

ServiceWindowGenerationFromSubtitle::~ServiceWindowGenerationFromSubtitle() {
	free(vetor_pts);
	if (tradutor) delete tradutor;
    // if (mixer) delete mixer;
	if (renderer) delete renderer;
	if (extratorVTT)delete extratorVTT;
	if (extrator_factory) delete extrator_factory;
    PRINTL(util::_DEBUG, "Service Subtitle finalized!\n");
}

void ServiceWindowGenerationFromSubtitle::setPathContents() {
    switch(exec_mode) {
        case DEVELOPER:
        {
            char* vStorage;
            char* vUploads;
            vStorage = getenv("VLSTORAGE");
            vUploads = getenv("VLUPLOADS");

            if(vStorage != NULL && vUploads != NULL){
                this->path_contents = vStorage;
                this->path_uploads = vUploads;
                PRINTL(util::_DEBUG, "Paths definidos pelo desenvolvedor:\n %s\n%s\n", path_contents, path_uploads);
            }else{
                this->path_contents = (char*) PATH_DEVEL_CONTENTS;
                this->path_uploads  = (char*) PATH_DEVEL_UPLOADS;
            }
        }break;

        case PRODUCTION:
        {
            ifstream conf_file(PATH_CONF_FILE, ifstream::binary);
            parsingSuccessful = reader.parse(conf_file, root);

            if(parsingSuccessful) {
                string attr = "vlibras_user/";
                attr += root.get("storage", PATH_VBOX_UPLOADS).asString();
                this->path_contents = new char[MAX_SIZE_PATH];
                strcpy(this->path_contents, attr.c_str());
                this->path_uploads = (char*) PATH_VBOX_UPLOADS;
            }else{
                conf_file.close();
                Logging::instance()->writeLog("Erro com a leitura do arquivo params.json");
                throw new RuntimeException("Fail to parsing params.json");
            }
            conf_file.close();
        }break;

        case TESTER:
        {
            this->path_contents = (char*) PATH_TESTER_CONTENTS;
            this->path_uploads  = (char*) PATH_TESTER_UPLOADS;
        }break;

        default:
            throw ServiceException("Invalid execution mode!");
    }
}

Extrator::ExtratorType ServiceWindowGenerationFromSubtitle::getExtratorType(){
    this->file = new lavidlib::File(this->path_srt);
    try{
        this->fileIO = new lavidlib::FileIO(file->getPath(), FileIO::MODE_READ);
        this->bffReader = new BufferedReader(fileIO);
    }catch(Exception &ex){
        Logging::instance()->writeLog("ServiceWindowGenerationFromSubtitle.cpp <Error>: Arquivo de legenda não encontrado.");
        throw ServiceException("Falha ao abrir o arquivo de legenda! Verifique se o mesmo existe.\n");
    }

    string signature;
    try{
        signature = bffReader->readLine();
    }catch(lavidlib::EOFException &ex){
        throw ServiceException("Arquivo sem conteúdo.");
    }

    /* As verificações a seguir estão de acordo com o padrão
     * definido pelo W3C Community Group.
     */
    if(signature.size() < 6){
        return Extrator::SRT;
    }

    if(signature.size() == 6 && strcmp(SIGNATURE, signature.c_str()) == 0){
        return Extrator::VTT;
    }else{
        return Extrator::SRT;
    }

    if(signature.size() > 6 && signature.find(SIGNATURE) == string::npos){
        return Extrator::SRT;
    }else if(!isspace(signature.at(6))){
        return Extrator::SRT;
    }

    delete bffReader;
    delete fileIO;

    return Extrator::VTT;
}

void ServiceWindowGenerationFromSubtitle::setPathLibras() {
    string final_path = "";
    path_libras = new char[MAX_SIZE_PATH];

    if(this->service_type == SERVICE_TYPE_SRT)
        final_path.append(this->path_uploads).append("/").append(this->user_id);
    else
        final_path.append(this->path_contents);

    final_path.append("/").append(this->user_id).append(".mp4");
    strcpy(this->path_libras, final_path.c_str());
}

void ServiceWindowGenerationFromSubtitle::setSizeOfSubtitles(int sub_size) {
	numero_legendas = sub_size;
    if (legendas_enviadas >= numero_legendas){
       try{
            renderer->initialize();
        }catch(lavidlib::RuntimeException &ex){
            throw ServiceException(ex.getMessage().c_str());
        }
    }
}

void ServiceWindowGenerationFromSubtitle::addPTS(int64_t pts){
	vetor_pts->push_back(pts);
}

void ServiceWindowGenerationFromSubtitle::notifyTranslator(unsigned char* subtitle) {
    const char* constchar = (const char*) subtitle;
    char* legenda_copy = new char[strlen(constchar)+1];
    strcpy(legenda_copy, constchar);
    tradutor->traduz((unsigned char*) legenda_copy);
    free(legenda_copy);
}

void ServiceWindowGenerationFromSubtitle::notifySubtitle(unsigned char *subtitle, uint64_t pts){
    addPTS(pts);
    if (sub_language == 1) {
        notifyTranslator(subtitle);
    }else{
        string subt(reinterpret_cast<char*>(subtitle));

				locale loc;
				string glosa = "";
				for (string::size_type i=0; i< subt.length(); ++i) {
					glosa += std::toupper(subt[i], loc);
				}
    		cout << glosa << endl;
        notifyRenderer(glosa);
    }
}

void ServiceWindowGenerationFromSubtitle::notifyTranslation(char* glosa) {
    string sGlosa(glosa);
    notifyRenderer(sGlosa);
}

void ServiceWindowGenerationFromSubtitle::notifyRenderer(string glosa) {
    try{
        renderer->receiveGlosa(glosa, vetor_pts->front());
        legendas_enviadas++;
    }catch(lavidlib::RuntimeException &ex){
        throw ServiceException(ex.getMessage().c_str());
    }
    vetor_pts->erase(vetor_pts->begin());
}

void ServiceWindowGenerationFromSubtitle::notifyEndOfRenderization() {
    if(this->service_type == SERVICE_TYPE_SRT){
        mixer = new Mixer(this->path_input, this->path_libras, this->size, this->position,
            this->transparency, this->user_id, this->path_uploads, this->path_contents);
        mixer->initialize();
        delete mixer;
    }
    this->running = false;
}

void ServiceWindowGenerationFromSubtitle::notifyEnd(int sub_size) {
    PRINTL(util::_DEBUG, "Service Subtitle recebeu: %d legendas.\n", sub_size);
    setSizeOfSubtitles(sub_size);
}

bool ServiceWindowGenerationFromSubtitle::isRunning() {
	return this->running;
}

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

void ServiceWindowGenerationFromSubtitle::initialize() {
    PRINTL(util::_DEBUG, "Service Subtitle Initialize.\n");
    setPathLibras();

    Extrator::ExtratorType extrator_t = getExtratorType();

    if(extrator_t == Extrator::SRT){
        extratorSRT = (ExtratorSRT*) extrator_factory->getExtrator(Extrator::SRT);
        extratorSRT->addListener(this);
        extratorSRT->setFilePath(path_srt);
    }else{
        extratorVTT = (ExtratorVTT*) extrator_factory->getExtrator(Extrator::VTT);
        extratorVTT->addListener(this);
        extratorVTT->setFilePath(path_srt);
    }

    tradutor = new TradutorPortGlosa();
	if (this->sub_language == 1) {
        tradutor->addListener(this);
    }

    renderer = new Renderer(this->path_libras ,this->user_id);
	renderer->addListener(this);

    try{
        if(extrator_t == Extrator::SRT)
            extratorSRT->initialize();
        else
            extratorVTT->initialize();
    }catch(ExtratorException ex){
        throw ServiceException(ex.getMessage());
    }catch(RuntimeException &ex){
        throw ServiceException(ex.getMessage().c_str());
    }
	this->Start();
}

void ServiceWindowGenerationFromSubtitle::Run() {
	while(isRunning()){
		usleep(200000);
	}
	finish = true;
}