serviceWindowGenerationFromSRT.cpp 7.83 KB
#include "serviceWindowGenerationFromSRT.h"

ServiceWindowGenerationFromSRT::ServiceWindowGenerationFromSRT(char* pathVideo, char* pathSRT, int sublanguage,
	int pos, int size, int transp, char* id, char* client, 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->client_type = client;
	this->service_type = serviceType;
	numero_legendas = INT_MAX;
    legendas_enviadas = 0;
	vetor_pts = new vector<int64_t >();
	tradutor = new TradutorPortGlosa();
	extrator_factory = new ExtratorFactory();
	try{
        setPathContents();
    }catch(RuntimeException ex){
        throw ServiceException(ex.getMessage());
    }
	running = true;
	finish = false;
	DPRINTF("Done!\n");
}

ServiceWindowGenerationFromSRT::ServiceWindowGenerationFromSRT(char* pathSRT, int transp, char* id, char* client, int serviceType) {

	this->path_srt = pathSRT;
	this->transparency = transp;
	this->user_id = id;
	this->client_type = client;
	this->service_type = serviceType;
	numero_legendas = INT_MAX;
    legendas_enviadas = 0;
	vetor_pts = new vector<int64_t >();
	tradutor = new TradutorPortGlosa();
	extrator_factory = new ExtratorFactory();
	try{
        setPathContents();
    }catch(RuntimeException ex){
        throw ServiceException(ex.getMessage());
    }
	running = true;
	finish = false;
	DPRINTF("Done!\n");
}

ServiceWindowGenerationFromSRT::~ServiceWindowGenerationFromSRT() {
	free(vetor_pts);
	if (mixer) delete mixer;
	if (tradutor) delete tradutor;
	if (sincronizador) delete sincronizador;
	if (extratorSRT)delete extratorSRT;
	if (extrator_factory) delete extrator_factory;
    DDDPRINTF("Service SRT finalized!\n");
}

void ServiceWindowGenerationFromSRT::setPathContents() {
	if(strcmp(client_type,DEVELOPER) == 0){
        this->path_contents = PATH_DEVEL;
        this->path_uploads = PATH_DEVEL_UPLOADS;
    }else if(strcmp(client_type, PRODUCTION) == 0){
        ifstream conf_file(PATH_CONF_FILE, ifstream::binary);
        parsingSuccessful = reader.parse(conf_file, root);
        if(!parsingSuccessful){
            throw ServiceException("Fail to parsing param.json");
        }
        string 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 = PATH_VBOX_UPLOADS;
    }else{
        throw ServiceException("Invalid client!");
    }
}

void ServiceWindowGenerationFromSRT::setPathLibras() {
	char* final_path = new char[MAX_SIZE_PATH];
    strcpy(final_path, this->path_uploads);
    strcat(final_path, this->user_id);
    strcat(final_path, "/video_libras.ts");

    this->path_libras = final_path;
}

void ServiceWindowGenerationFromSRT::setBackground() {
	if(this->transparency == 0) { //pega dicionario com BackGround opaco
		char* dicPath;
		dicPath = getenv("DIC_LIBRAS");
		if(dicPath != NULL)
    		sincronizador = new Synchronizer(dicPath, EXTENSAO_DICIONARIO, this->path_libras, this->transparency);
    	else
    		sincronizador = new Synchronizer(BASEDIR, EXTENSAO_DICIONARIO, this->path_libras, this->transparency);

    } else if(this->transparency == 1) { //pega dicionario com BackGround transparente
    	char* dicTPath;
    	dicTPath = getenv("DICTRANSP_LIBRAS");
    	if(dicTPath != NULL)
    	   	sincronizador = new Synchronizer(dicTPath, EXTENSAO_DICIONARIO, this->path_libras, this->transparency);
    	else
    		sincronizador = new Synchronizer(BASEDIRTRANSP, EXTENSAO_DICIONARIO, this->path_libras, this->transparency);
    }
}

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

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

void ServiceWindowGenerationFromSRT::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 ServiceWindowGenerationFromSRT::notifySubtitle(unsigned char *subtitle, int64_t pts){
    addPTS(pts);
    notifyTranslator(subtitle);    
}

void ServiceWindowGenerationFromSRT::notifyEndOfSynchronization() {
	if (this->service_type == SERVICE_TYPE_SRT) {
        mixer = new Mixer();
        mixer->initialize(this->path_input, this->path_libras,this->position,this->size,
        	this->transparency, this->user_id, this->path_uploads, this->path_contents);
        createThumbnail();
    }else{
        transcodeVideoToMp4();
    }
    this->running = false;
}

void ServiceWindowGenerationFromSRT::notifyTranslation(vector<string> * glosas) {
	for (int i = 0; i < glosas->size(); i++) {
	    locale loc;
	    string glosa_lower = "";
	    for (int k = 0; k < glosas->at(i).length(); k++){
	        glosa_lower += std::tolower(glosas->at(i).at(k), loc);
	    }
	    int64_t pts_notificado = vetor_pts->front();
	    sincronizador->recebeglosa(glosa_lower, pts_notificado);	
	}
	vetor_pts->erase(vetor_pts->begin());
	legendas_enviadas++;              
}

void ServiceWindowGenerationFromSRT::notifyEnd(int sub_size) {
	DPRINTF("Service SRT recebeu: %d legendas.\n", sub_size);
    setSizeOfSubtitles(sub_size);
}

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

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

void ServiceWindowGenerationFromSRT::initialize() {
	DPRINTF("Service SRT Initialize.\n");
	extratorSRT = (ExtratorSRT*) extrator_factory->getExtrator(Extrator::SRT);
	extratorSRT->addListener(this);
	extratorSRT->setFilePath(path_srt);

	setPathLibras();

    if (this->sub_language == 1)
        tradutor->addListener(this);
    
    if(this->service_type != SERVICE_TYPE_SRT_ONLY){
		vector<string> tokens;
		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 Serviço montou o seguinte path para o vídeo de Libras: %s\n", path_libras);

	}else{
		tradutor->addListener(this);
	}

	setBackground();

	if (service_type != SERVICE_TYPE_SRT) {
		uint64_t pcr_base = (uint64_t) 1000; //FIXME: macro
        sincronizador->setPCRBase(pcr_base);
	}

	sincronizador->addListener(this);
    sincronizador->Start();

    try{                               
        extratorSRT->initialize();  
    }catch(ExtratorException ex){
        throw ServiceException(ex.getMessage());
    }
	this->Start();
}

void ServiceWindowGenerationFromSRT::transcodeVideoToMp4(){
	DPRINTF("[AGUARDE] Transcodificando o vídeo de Libras...\n");
    string command = "ffmpeg -i ";
    command.append(path_libras)
    .append(" -qscale 0 -strict experimental -vcodec libx264 -preset fast -r 30 ").append(" -v quiet ")
	.append(path_contents).append(user_id).append(".mp4");
    //printf("[INFO]: Transcodification command -> %s\n", command.c_str());
    system(command.c_str());
}

void ServiceWindowGenerationFromSRT::createThumbnail(){
    string command = "ffmpeg -ss 10 -i ";
	command.append(path_contents).append(user_id).append(".mp4")
	.append(" -vcodec png -vframes 1 -an -f rawvideo -y -vf scale=200:200 ").append(" -v quiet ")
	.append(path_contents).append(user_id).append(".png");
	//printf("[INFO]: Thumbnail command -> %s\n", command.c_str());
    system(command.c_str());
}

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