serviceWindowGeneration.cpp 8.64 KB

#include "serviceWindowGeneration.h"

#define VIDEO_POSE_NEUTRA "poseneutra"
#define BASEDIR "vlibras_user/dicionario_libras/"
#define BASEDIRTRANSP "vlibras_user/dicionarioTransp_libras/"
#define EXTENSAO_DICIONARIO ".ts"
#define PATH_API "vlibras_user/vlibras-api/videos/"
#define MAX_SIZE_PATH 256


ServiceWindowGeneration::ServiceWindowGeneration() {
    if (getRunningOption() != '3') {
        tradutor = new TradutorPortGlosa();
    }
    vetor_pts = new vector<int64_t >();
    numero_legendas = INT_MAX;
    legendas_enviadas = 0;
    this->running = true;
	serviceType = 0;
    DPRINTF("Done!\n");
}

ServiceWindowGeneration::~ServiceWindowGeneration() {
    free(vetor_pts);
    //free(path_input);
    free(path_libras);
    if (inputfile) delete inputfile;
    if (monitor_pcr_base) delete monitor_pcr_base;
    if (mixer) delete mixer;
    if (tradutor) delete tradutor;
    if (sincronizador) delete sincronizador;

    DDDPRINTF("Service finalized!\n");

}

void ServiceWindowGeneration::adicionaPTS(int64_t pts) {
    vetor_pts->push_back(pts);
}

/* Checado pela subclasse para saber quando o sincronizador terminar. */
bool ServiceWindowGeneration::isRunning() {
    return this->running;
}

/* Quando o sincronizador termina, ele invoca esse método para avisar! */
void ServiceWindowGeneration::finalizouSincronizacao() {
    if (getRunningOption() != '2' && serviceType != SERVICE_TYPE_TEXT && serviceType != SERVICE_TYPE_SRT_ONLY) {
        mixer = new Mixer();
        mixer->initialize(this->path_input, this->path_libras,this->position,this->size,this->transparency, this->user_id);
        createThumbnail();
    }else
        transcodeVideoToMp4();
    this->running = false;

}

char ServiceWindowGeneration::getRunningOption() {
    char option;
    if(!option){
	    int file_d = open("vlibras_user/vlibras-core/data/runningoption.xml", O_RDONLY);
	    int cont = read(file_d, &option, 1);
	    close(file_d);    	
	}
    return option;
}

void ServiceWindowGeneration::setSizeOfSubtitles(int sub_size) {
    numero_legendas = sub_size;
    if (legendas_enviadas >= numero_legendas) {
        sincronizador->stop();
    }
}

void ServiceWindowGeneration::setPathLibras() {
	char* final_path = new char[MAX_SIZE_PATH];
    strcpy(final_path, "vlibras_user/vlibras-api/uploads/");
    strcat(final_path, this->user_id);
    strcat(final_path, "/libras.ts");

    this->path_libras = final_path;
    //DDPRINTF("Path TS File: %s\n", this->path_libras);
}

char* ServiceWindowGeneration::getPathLibras() {
    return path_libras;
}

void ServiceWindowGeneration::setPathInput(char* _path_input) {
    this->path_input = _path_input;
}

char* ServiceWindowGeneration::getPathInput() {
    return path_input;
}

string ServiceWindowGeneration::getPathAPI() {
    return PATH_API;
}

void ServiceWindowGeneration::setUserId(char* _userId) {
	this->user_id = _userId;
}

char* ServiceWindowGeneration::getClientType(){
    return client_type;
}

char* ServiceWindowGeneration::getUserId() {
    return user_id;
}

void ServiceWindowGeneration::setServiceType(int type) {
	serviceType = type;
}

void ServiceWindowGeneration::setClientType(char* client_type) {
    this->client_type = client_type;
}

void ServiceWindowGeneration::setSize(int size){
	this->size = size;
}

void ServiceWindowGeneration::setPosition(int position){
	this->position = position;
}

void ServiceWindowGeneration::setTransparency(int transparency){
	this->transparency = transparency;
}

void ServiceWindowGeneration::setSubLanguage(int sublang){
	this->sublanguage = sublang;
}

void ServiceWindowGeneration::initialize() {	

    setPathLibras();

    this->finish = false;
    if (getRunningOption() != '3' && this->sublanguage == 1) {
        tradutor->registraOuvinte(this);
    }
	
    // o path do arquivo só poderá conter um "."(ponto), esse identifica a extensão.
    
    vector<string> tokens;
    /* Se for texto não é necessário vídeo de entrada (path_input) */
    if (serviceType != SERVICE_TYPE_TEXT && serviceType != SERVICE_TYPE_SRT_ONLY &&
            serviceType != SERVICE_TYPE_REC_ONLY_LIBRAS) {
        char * pathtmp = this->path_input;
    	int size = strlen(pathtmp);
    	char vtemp [size];
    	strcpy(vtemp, pathtmp);
    	pathtmp = strtok(vtemp, ".");
    	while (pathtmp != NULL) {
            tokens.push_back(string(pathtmp));
            pathtmp = strtok(NULL, ".");
    	}
    	string buildstrpath = tokens[0] + "_libras" + EXTENSAO_DICIONARIO;
    	this->path_libras = new char[buildstrpath.size()];
    	strcpy(this->path_libras, buildstrpath.c_str());
        //printf("O ServiceWGeneration montou o seguinte path para o vídeo de Libras: %s\n", path_libras);

    } else {
	   tradutor->registraOuvinte(this);
    }
	    
    if(this->transparency == 0) {	//pega dicionario com BackGround opaco
    	sincronizador = new Synchronizer(BASEDIR, EXTENSAO_DICIONARIO, 
            this->path_libras, this->transparency);
    } else { 
    	if(this->transparency == 1) {	//pega dicionario com BackGround transparente
    	   sincronizador = new Synchronizer(BASEDIRTRANSP, EXTENSAO_DICIONARIO,
            this->path_libras,this->transparency);
    	}
    }

	/* Se for SERVICE_TYPE_REC (Recognized) não é necessário usar o monitor_pcr_base */
	if (serviceType == SERVICE_TYPE_CC || serviceType == SERVICE_TYPE_SRT) {

		char* extensao = (char*) tokens[1].c_str();
		this->monitor_pcr_base->extvideo =  new char[strlen(extensao)];
		strcpy(this->monitor_pcr_base->extvideo, extensao);
		monitor_pcr_base->addListenerPCRBase(sincronizador);

	} else {
		uint64_t pcr_base = (uint64_t) 1000; //FIXME: macro
		sincronizador->setPCRBase(pcr_base);
		if (serviceType == SERVICE_TYPE_SRT_ONLY) {
			monitor_pcr_base->addListenerPCRBase(sincronizador);
		}
	}

    sincronizador->registraOuvinte(this);
    sincronizador->Start();
}

/* Método utilizado pelo Tradutor para notificar o texto traduzido. */
void ServiceWindowGeneration::codifica(vector<string> * glosas) {

    if (serviceType != SERVICE_TYPE_TEXT) {
	    for (int i = 0; i < glosas->size(); i++) {
            std::locale loc;
            std::string glosa_lower = "";
            for (int k = 0; k < glosas->at(i).length(); k++)
                glosa_lower += std::tolower(glosas->at(i).at(k), loc);

            //cout << "__Glosa [" << i << "] = " << glosa_lower << endl;
            int64_t pts_notificado = vetor_pts->front();
            sincronizador->recebeglosa(glosa_lower, pts_notificado);
    	}
        /* O 'numero_legendas' é informado pela subclasse através do método setSizeOfSubtitles.
           Então, inicialmente, seu valor corresponde a um número inteiro máximo.
         */
        /*printf("numero_legendas = %d\nlegendas_enviadas = %d\n", numero_legendas, legendas_enviadas);
        if (legendas_enviadas >= numero_legendas) {
	    sincronizador->stop();
	}*/
	vetor_pts->erase(vetor_pts->begin());
    } else {
        //Nova versão!
        for (int i = 0; i < glosas->size(); i++) {
            std::locale loc;
            std::string glosa_lower = "";
            for (int k = 0; k < glosas->at(i).length(); k++)
                glosa_lower += std::tolower(glosas->at(i).at(k), loc);

            //cout << "__Glosa [" << i << "] = " << glosa_lower << endl;
            sincronizador->recebeglosa(glosa_lower, 1000);
        }
        sincronizador->stop();
    }
    legendas_enviadas++;        
}

void ServiceWindowGeneration::transcodeVideoToWebm() {

    //printf("[INFO]: A transcodificação para .webm está ativada!\n");

    string command = "ffmpeg -i ";
    command.append(path_libras)
    .append(" -vcodec libvpx -acodec libvorbis ")
    .append(PATH_API)
    .append(getUserId())
    .append(".webm");
    //printf("[INFO]: Transcodification command -> %s\n", command.c_str());
    system(command.c_str());
}

void ServiceWindowGeneration::transcodeVideoToMp4() {

    if (serviceType == SERVICE_TYPE_TEXT && strcmp(client_type, (char*)"WEB") == 0)
            transcodeVideoToWebm();
    else{
         //printf("[INFO]: A transcodificação para .mp4 está ativada!\n");
        string command = "ffmpeg -i ";
        command.append(path_libras)
        .append(" -strict experimental -vcodec mpeg2video -r 30 ")
        .append(PATH_API)
        .append(getUserId())
        .append(".mp4");
        //printf("[INFO]: Transcodification command -> %s\n", command.c_str());
        system(command.c_str());

        //.append(" -strict experimental -vcodec mjpeg -r 30 -pix_fmt yuvj422p ")

    }
}

void ServiceWindowGeneration::createThumbnail(){

    string command = "ffmpeg -ss 10 -i ";
    command.append(getPathInput())
    .append(" -vcodec png -vframes 1 -an -f rawvideo -y -vf scale=200:200 ")
    .append(PATH_API).append(user_id).append(".png");
    system(command.c_str());
}