diff --git a/Makefile b/Makefile index daff99a..3cd4f9d 100644 --- a/Makefile +++ b/Makefile @@ -40,6 +40,7 @@ extratorOBJS = \ extratorFactory.o \ extratorSRT.o \ extratorTXT.o \ + extratorVTT.o \ subtitle.o inputOBJS = \ @@ -63,7 +64,7 @@ servicoOBJS = \ serviceException.o \ serviceTester.o \ serviceWindowGenerationFromRec.o \ - serviceWindowGenerationFromSRT.o \ + serviceWindowGenerationFromSubtitle.o \ serviceWindowGenerationFromText.o tradutorOBJS = \ diff --git a/extrator/src/extratorFactory.cpp b/extrator/src/extratorFactory.cpp index 9bb8a2e..6685f95 100644 --- a/extrator/src/extratorFactory.cpp +++ b/extrator/src/extratorFactory.cpp @@ -9,5 +9,8 @@ Extrator* ExtratorFactory::getExtrator(Extrator::ExtratorType extrator_type) { case Extrator::TXT: PRINTL(util::_DEBUG, "ExtratorTXT selected!\n"); return new ExtratorTXT(); + case Extrator::VTT: + PRINTL(util::_DEBUG, "ExtratorVTT selected!\n"); + return new ExtratorVTT(); } } \ No newline at end of file diff --git a/extrator/src/extratorSRT.cpp b/extrator/src/extratorSRT.cpp index cc878bd..d549ed8 100644 --- a/extrator/src/extratorSRT.cpp +++ b/extrator/src/extratorSRT.cpp @@ -1,7 +1,7 @@ #include "extratorSRT.h" ExtratorSRT::ExtratorSRT(){ - listeners = new list(); + listeners = new list(); finish = false; seek_pos = 0; hasNextSub = true; @@ -32,19 +32,19 @@ void ExtratorSRT::initialize(){ } -void ExtratorSRT::addListener(ListenerSRT* listener){ +void ExtratorSRT::addListener(ListenerSub* listener){ listeners->push_back(listener); } void ExtratorSRT::notifyListeners(unsigned char* subtitle, int64_t pts) { - for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ + for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ (*it)->notifySubtitle(subtitle, pts); } } void ExtratorSRT::notifyEndExtraction(int size) { PRINTL(util::_DEBUG, "Extrator SRT concluiu a extração: %d legendas.\n", size); - for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ + for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ (*it)->notifyEnd(size); } } @@ -136,15 +136,32 @@ Subtitle* ExtratorSRT::next() { seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE; } catch (lavidlib::EOFException &ex) { - sub->setSubtitleText(text_sub); + sub->setSubtitleText(formatText(text_sub)); seek_pos += (int64_t) text_sub.size() + SIZE_CSCAPE; hasNextSub = false; return sub; } - sub->setSubtitleText(text_sub); + sub->setSubtitleText(formatText(text_sub)); delete(bff_reader); return sub; } + +string ExtratorSRT::formatText(string line){ + int lessThanPos; + int moreThanPos; + string f_line = line; + + lessThanPos = f_line.find_first_of(LESS_THAN); //pega a posição do simbolo '<' + moreThanPos = f_line.find_first_of(MORE_THAN); //pega a posição do simbolo '>' + + while(lessThanPos != string::npos && moreThanPos != string::npos){ + f_line = f_line.erase(lessThanPos, moreThanPos - (lessThanPos-1)); //remove o trecho '' + lessThanPos = f_line.find_first_of(LESS_THAN); + moreThanPos = f_line.find_first_of(MORE_THAN); + } + + return f_line; +} int64_t ExtratorSRT::str_to_time(string str_time) { diff --git a/extrator/src/extratorVTT.cpp b/extrator/src/extratorVTT.cpp new file mode 100644 index 0000000..631f6ea --- /dev/null +++ b/extrator/src/extratorVTT.cpp @@ -0,0 +1,148 @@ +#include "extratorVTT.h" + +ExtratorVTT::ExtratorVTT() { + listeners = new list(); + seekPos = 0; + this->finish = false; + hasNextCue = true; + PRINTL(util::_DEBUG, "ExtratorVTT Done!\n"); +} + +ExtratorVTT::~ExtratorVTT() { + listeners->clear(); + delete listeners; + if (bff_reader) delete bff_reader; + if (file_io) delete file_io; + PRINTL(util::_DEBUG, "ExtratorVTT finalized!\n"); +} + +void ExtratorVTT::setFilePath(char* path) { + this->filePath = path; +} + +bool ExtratorVTT::isFinished() { + return this->finish; +} + +void ExtratorVTT::addListener(ListenerSub* listener){ + listeners->push_back(listener); +} + +void ExtratorVTT::notifyListeners(unsigned char* subtitle, uint64_t pts) { + for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ + (*it)->notifySubtitle(subtitle, pts); + } +} + +void ExtratorVTT::notifyEndExtraction(int size) { + PRINTL(util::_DEBUG, "Extrator webVTT concluiu a extração: %d legendas.\n", size); + for(list::iterator it = listeners->begin(); it != listeners->end(); it++){ + (*it)->notifyEnd(size); + } +} + +void ExtratorVTT::initialize() { + file = new lavidlib::File(this->filePath); + + try{ + file_io = new lavidlib::FileIO(file->getPath(), FileIO::MODE_READ); + bff_reader = new BufferedReader(file_io); + }catch(Exception &ex){ + finish = true; + Logging::instance()->writeLog("extratorVTT.cpp : Arquivo de legenda não encontrado."); + throw lavidlib::RuntimeException("Falha ao abrir o arquivo de legenda! Verifique se o mesmo existe.\n"); + } + this->Start(); +} + +Subtitle* ExtratorVTT::nextCue() { + string line; + string cueText = ""; + int target_pos; + int64_t time_in; + + Subtitle* cue = new Subtitle(); + + try{ + do{ + line = bff_reader->readLine(); + seekPos += line.size() + SIZE_SCAPE; + }while(line.find(TARGET_TIME) == string::npos); + + target_pos = line.find(TARGET_TIME); + time_in = str_to_time(line.substr(0, target_pos)); + cue->setTimeIn(time_in); + + while((line = bff_reader->readLine()) != ""){ + cueText += line; + cueText += " "; + } + + }catch(lavidlib::EOFException &ex){ + cue->setSubtitleText(formatText(cueText)); + seekPos += (int64_t) cueText.size() + SIZE_SCAPE; + hasNextCue =false; + return cue; + } + + cue->setSubtitleText(formatText(cueText)); + seekPos += (int64_t) cueText.size() + SIZE_SCAPE; + return cue; +} + +string ExtratorVTT::formatText(string line){ + int lessThanPos; + int moreThanPos; + string f_line = line; + + lessThanPos = f_line.find_first_of(LESS_THAN); //pega a posição do simbolo '<' + moreThanPos = f_line.find_first_of(MORE_THAN); //pega a posição do simbolo '>' + + while(lessThanPos != string::npos && moreThanPos != string::npos){ + f_line = f_line.erase(lessThanPos, moreThanPos - (lessThanPos-1)); //remove o trecho '' + lessThanPos = f_line.find_first_of(LESS_THAN); + moreThanPos = f_line.find_first_of(MORE_THAN); + } + + return f_line; +} + +int64_t ExtratorVTT::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; +} + +void ExtratorVTT::Run() { + PRINTL(util::_INFO, "Extraindo Legendas...\n"); + + int sub_index = 0; + string cue_text = ""; + while(hasNextCue){ + subtitle = nextCue(); + cue_text = subtitle->getSubtitleText(); + notifyListeners((unsigned char*)cue_text.c_str(), (uint64_t) subtitle->getTimeIn()); + sub_index++; + free(subtitle); + } + if(sub_index == 0) + notifyListeners((unsigned char*)"ARQUIVO_INVALIDO", 0); + this->finish = true; + notifyEndExtraction(sub_index); +} \ No newline at end of file diff --git a/extrator/src/include/extrator.h b/extrator/src/include/extrator.h index 3f44f44..24b5c86 100644 --- a/extrator/src/include/extrator.h +++ b/extrator/src/include/extrator.h @@ -33,10 +33,7 @@ protected: BufferedReader* bff_reader; public: - enum ExtratorType { - SRT, - TXT - }; + enum ExtratorType {SRT, TXT, VTT}; /** Notifica o fim da extração do conteúdo do arquivo. * diff --git a/extrator/src/include/extratorFactory.h b/extrator/src/include/extratorFactory.h index 54fc8fa..53663dc 100644 --- a/extrator/src/include/extratorFactory.h +++ b/extrator/src/include/extratorFactory.h @@ -10,6 +10,7 @@ #include "extrator.h" #include "extratorSRT.h" #include "extratorTXT.h" +#include "extratorVTT.h" /** \brief Classe que implementa o factory pattern. */ class ExtratorFactory{ diff --git a/extrator/src/include/extratorSRT.h b/extrator/src/include/extratorSRT.h index 895dfa1..0c466a7 100644 --- a/extrator/src/include/extratorSRT.h +++ b/extrator/src/include/extratorSRT.h @@ -16,11 +16,13 @@ #include "jthread.h" #include "extrator.h" #include "subtitle.h" -#include "listenerSRT.h" +#include "listenerSub.h" #include "extratorException.h" #define SIZE_CSCAPE 1 #define TARGET_TIME "-->" +#define LESS_THAN "<" +#define MORE_THAN ">" #define INPUT_SRT "vlibras_user/inputSRT.srt" //#define MAX_LINE 1024 @@ -48,7 +50,7 @@ public: * * \param listener O ouvinte a ser registrado. */ - void addListener(ListenerSRT* listener); + void addListener(ListenerSub* listener); /** Notifica os ouvintes sobre novas extrações realizadas. * @@ -98,12 +100,13 @@ public: void Run(); private: - list *listeners; + list *listeners; Subtitle *subtitle; int64_t seek_pos; bool hasNextSub; - + + string formatText(string line); uint64_t calcula_pts(double msec); int64_t str_to_time(std::string str_time); }; diff --git a/extrator/src/include/extratorVTT.h b/extrator/src/include/extratorVTT.h new file mode 100644 index 0000000..22a08d8 --- /dev/null +++ b/extrator/src/include/extratorVTT.h @@ -0,0 +1,52 @@ +#ifndef EXTRATORVTT_H +#define EXTRATORVTT_H + +#include +#include +#include +#include +#include "jthread.h" +#include "extrator.h" +#include "subtitle.h" +#include "listenerSub.h" +#include + +#define SIGNATURE "WEBVTT" +#define TARGET_TIME "-->" +#define LESS_THAN "<" +#define MORE_THAN ">" +#define SIZE_SCAPE 1 + +using namespace std; +using namespace sndesc; +using namespace jthread; + +class ExtratorVTT: public Extrator, public Thread { + +public: + ExtratorVTT(); + ~ExtratorVTT(); + + void setFilePath(char* path); + void addListener(ListenerSub* listener); + + void initialize(); + bool isFinished(); + void Run(); + +private: + Subtitle* subtitle; + list *listeners; + + int64_t seekPos; + bool hasNextCue; + + void notifyEndExtraction(int size); + void notifyListeners(unsigned char* subtitle, uint64_t pts); + + Subtitle* nextCue(); + string formatText(string line); + int64_t str_to_time(string str_time); +}; + +#endif /* EXTRATORVTT_H */ \ No newline at end of file diff --git a/extrator/src/include/listenerSRT.h b/extrator/src/include/listenerSRT.h deleted file mode 100644 index 0a67142..0000000 --- a/extrator/src/include/listenerSRT.h +++ /dev/null @@ -1,17 +0,0 @@ -/** - * \file listenerSRT.h - */ - -#ifndef LISTENERSRT_H -#define LISTENERSRT_H - -#include - -class ListenerSRT{ - -public: - virtual void notifySubtitle(unsigned char* subtitle, int64_t pts) = 0; - virtual void notifyEnd(int sub_size) = 0; -}; - -#endif /* LISTENEREXTRATOR_H */ \ No newline at end of file diff --git a/extrator/src/include/listenerSub.h b/extrator/src/include/listenerSub.h new file mode 100644 index 0000000..e0105c0 --- /dev/null +++ b/extrator/src/include/listenerSub.h @@ -0,0 +1,17 @@ +/** + * \file listenerSRT.h + */ + +#ifndef LISTENERSUB_H +#define LISTENERSUB_H + +#include + +class ListenerSub{ + +public: + virtual void notifySubtitle(unsigned char* subtitle, uint64_t pts) = 0; + virtual void notifyEnd(int sub_size) = 0; +}; + +#endif /* LISTENERSUB_H */ \ No newline at end of file diff --git a/main.cpp b/main.cpp index 9626b5a..c252bbf 100644 --- a/main.cpp +++ b/main.cpp @@ -18,7 +18,7 @@ #include "argParser.h" #include "serviceTester.h" #include "serviceException.h" -#include "serviceWindowGenerationFromSRT.h" +#include "serviceWindowGenerationFromSubtitle.h" #include "serviceWindowGenerationFromRec.h" #include "serviceWindowGenerationFromText.h" #include @@ -184,8 +184,8 @@ void serviceSRT(int service, string path_video, string path_srt, int language, i setPathContents(mode, id); - ServiceWindowGenerationFromSRT* service_srt; - service_srt = new ServiceWindowGenerationFromSRT(video, srt, language, position, size, background, name, mode, service); + ServiceWindowGenerationFromSubtitle* service_srt; + service_srt = new ServiceWindowGenerationFromSubtitle(video, srt, language, position, size, background, name, mode, service); try{ service_srt->initialize(); @@ -270,8 +270,8 @@ void serviceOnlySRT(int service, string path_srt, int language, int background, setPathContents(mode, id); - ServiceWindowGenerationFromSRT* service_srt; - service_srt = new ServiceWindowGenerationFromSRT(srt, language, background, name, mode, service); + ServiceWindowGenerationFromSubtitle* service_srt; + service_srt = new ServiceWindowGenerationFromSubtitle(srt, language, background, name, mode, service); try{ service_srt->initialize(); }catch(ServiceException ex){ diff --git a/renderer/src/include/renderer.h b/renderer/src/include/renderer.h index 3ea8fb1..0f06c2d 100644 --- a/renderer/src/include/renderer.h +++ b/renderer/src/include/renderer.h @@ -22,6 +22,7 @@ #include #include #include + #include #define HOST "0.0.0.0" #define PORT 5555 diff --git a/renderer/src/renderer.cpp b/renderer/src/renderer.cpp index e0a492a..2bd4235 100644 --- a/renderer/src/renderer.cpp +++ b/renderer/src/renderer.cpp @@ -56,7 +56,7 @@ void Renderer::connectToUnityPlayer() { i++; sleep(1); }catch(lavidlib::SocketException &ex){ - if(i == 7){ // Numeros de tentativas (pode ser alterado) + if(i == 10){ // Numeros de tentativas (pode ser alterado) PRINTL(util::_ERROR, "Número de tentativas de conexão excedido!\n"); throw lavidlib::RuntimeException(ex.getMessage().c_str()); } @@ -73,7 +73,7 @@ void Renderer::receiveGlosa(string glosa, int64_t pts) { string formatedGlosa; //Formato da glosa que será enviada para o player: "glosa#pts" if(glosa == BADSENTENCE || glosa == BADTEXT) - formatedGlosa = "_DEFAULT"; //O player entende "#pts" como pose neutra + formatedGlosa = ""; //O player entende "#pts" como pose neutra else formatedGlosa = glosa; @@ -95,6 +95,8 @@ void Renderer::exportGlosa() { glosaBff = new char[glosaSize]; strcpy(glosaBff, glosaCpy.c_str()); + cout << "glosa: " << glosaBff << endl; + try { cSocket->write(glosaBff, glosaSize); //Envia a glosa formatada p/ o player }catch(lavidlib::IOException &ex){ diff --git a/servico/src/include/serviceTester.h b/servico/src/include/serviceTester.h index e3c3ccb..192058e 100644 --- a/servico/src/include/serviceTester.h +++ b/servico/src/include/serviceTester.h @@ -13,7 +13,7 @@ #include #include "serviceException.h" #include "serviceWindowGenerationFromRec.h" -#include "serviceWindowGenerationFromSRT.h" +#include "serviceWindowGenerationFromSubtitle.h" #include "serviceWindowGenerationFromText.h" #define MODE_TEST 3 @@ -69,7 +69,7 @@ private: FileIO* fIO_out; ServiceWindowGenerationFromRec* service_rec; - ServiceWindowGenerationFromSRT* service_srt; + ServiceWindowGenerationFromSubtitle* service_srt; ServiceWindowGenerationFromText* service_text; /** Checa o serviço de vídeo com legendas */ diff --git a/servico/src/include/serviceWindowGenerationFromSRT.h b/servico/src/include/serviceWindowGenerationFromSRT.h deleted file mode 100644 index a28ecd1..0000000 --- a/servico/src/include/serviceWindowGenerationFromSRT.h +++ /dev/null @@ -1,136 +0,0 @@ -/** - * \file serviceWindowGenerationFromSRT.h - */ - -#ifndef SERVICEWINDOWGENERATIONFROMSRT_H -#define SERVICEWINDOWGENERATIONFROMSRT_H - -#include "listenerSRT.h" -#include "extratorFactory.h" -#include "serviceWindowGeneration.h" - -#define SERVICE_TYPE_SRT 1 -#define SERVICE_TYPE_SRT_ONLY 4 - -/** \brief Classe que implementa o serviço de extração de legendas. - * - * \headerfile servico/src/include/serviceWindowGenerationFromSRT.h - */ -class ServiceWindowGenerationFromSRT : public ServiceWindowGeneration, public ListenerSRT, public ListenerTradutor, public ListenerRenderer, public Thread { - -private: - ExtratorFactory* extrator_factory; - ExtratorSRT* extratorSRT; - - char* path_srt; - - /** Adiciona a etiqueta de tempo. - * - * Cada sentença conterá sua respectiva de tempo. - * \param pts A etiqueta de tempo. - */ - void addPTS(int64_t pts); - - /** Seta o número de legendas. - * - * \param A quantidade de legendas. - * \exception ServiceException Se houver algum erro durante a execução. - */ - void setSizeOfSubtitles(int sub_size); - - /** Define o path do vídeo de LIBRAS. */ - void setPathLibras(); - - /** Define o path dos arquivos de saída. - * - * \exception RuntimeException Se houver algum erro durante a execução. - */ - void setPathContents(); - - /** Indica se o serviço está sendo executado. - * - * \return O status do serviço. - */ - bool isRunning(); -public: - /** Construtor do serviço de vídeo com legendas. - * - * \param pathVideo Path do vídeo de entrada. - * \param pathSRT Path do arquivo de legendas. - * \param sublanguage Linguagem das legendas do arquivo. - * \param pos Posição do vídeo de LIBRAS em relação ao vídeo original. - * \param size Tamanho do vídeo de LIBRAS. - * \param transp Transparência do plano de fundo do vídeo. - * \param id Identificação do cliente. - * \param mode Modo de execução. - * \param serviceType Tipo do serviço. - */ - ServiceWindowGenerationFromSRT(char* pathVideo, char* pathSRT, int sublanguage, int pos, - int size, int transp, char* id, int mode, int serviceType); - - /** Construtor do serviço de legendas. - * - * \param pathSRT Path do arquivo de legendas. - * \param sublanguage Linguagem das legendas do arquivo. - * \param transparency Transparência do plano de fundo do vídeo. - * \param id Identificação do cliente. - * \param mode Modo de execução. - * \param serviceType Tipo do serviço. - */ - ServiceWindowGenerationFromSRT(char* pathSRT, int sublanguage, int transparency, char* id, int mode, int serviceType); - - /** Destrutor */ - ~ServiceWindowGenerationFromSRT(); - - /** Notifica novas legendas extraídas. - * - * \param subtitle A legenda extraída. - * \param pts A etiqueta de tempo da legenda. - */ - void notifySubtitle(unsigned char* subtitle, int64_t pts); - - /** Recebe a notificação do fim da renderização do vídeo */ - void notifyEndOfRenderization(); - - /** Recebe a notificação do fim da tradução da legenda. - * - * \param glosa A legenda traduzida. - */ - void notifyTranslation(char* glosas); - - /** Envia para a tradução a legenda obtida. - * - * \param text A legenda obtida. - */ - void notifyTranslator(unsigned char* text); - - /** Envia a glosa para o renderizador. - * - * \param glosa A glosa obtida. - * \exception ServiceException Se houver algum erro durante a execução. - */ - void notifyRenderer(string glosa); - - /** Notifica o fim da extração de legendas. - * - * \param sub_size O número de legendas extraídas. - */ - void notifyEnd(int sub_size); - - /** Inicia o serviço de extração de legendas. - * - * \exception ServiceException Se houver algum erro durante a execução. - */ - void initialize(); - - /** Indica o fim do processo do serviço. - * - * \return O status do processo. - */ - bool isFinished(); - - /** Este método é chamado quando a Thread for iniciada. */ - void Run(); -}; - -#endif /* SERVICEWINDOWGENERATIONFROMSRT_H_ */ \ No newline at end of file diff --git a/servico/src/include/serviceWindowGenerationFromSubtitle.h b/servico/src/include/serviceWindowGenerationFromSubtitle.h new file mode 100644 index 0000000..af7bdcb --- /dev/null +++ b/servico/src/include/serviceWindowGenerationFromSubtitle.h @@ -0,0 +1,150 @@ +/** + * \file ServiceWindowGenerationFromSubtitle.h + */ + +#ifndef SERVICEWINDOWGENERATIONFROMSUB_H +#define SERVICEWINDOWGENERATIONFROMSUB_H + +#include "listenerSub.h" +#include "extratorFactory.h" +#include "serviceWindowGeneration.h" +#include +#include +#include +#include +#include + +#define SIGNATURE "WEBVTT" +#define SERVICE_TYPE_SRT 1 +#define SERVICE_TYPE_SRT_ONLY 4 + +/** \brief Classe que implementa o serviço de extração de legendas. + * + * \headerfile servico/src/include/ServiceWindowGenerationFromSubtitle.h + */ +class ServiceWindowGenerationFromSubtitle : public ServiceWindowGeneration, public ListenerSub, public ListenerTradutor, public ListenerRenderer, public Thread { + +private: + char* path_srt; + + ExtratorFactory* extrator_factory; + ExtratorSRT* extratorSRT; + ExtratorVTT* extratorVTT; + + File* file; + FileIO* fileIO; + BufferedReader* bffReader; + + /** Adiciona a etiqueta de tempo. + * + * Cada sentença conterá sua respectiva de tempo. + * \param pts A etiqueta de tempo. + */ + void addPTS(int64_t pts); + + /** Seta o número de legendas. + * + * \param A quantidade de legendas. + * \exception ServiceException Se houver algum erro durante a execução. + */ + void setSizeOfSubtitles(int sub_size); + + /** Define o path do vídeo de LIBRAS. */ + void setPathLibras(); + + /** Define o path dos arquivos de saída. + * + * \exception RuntimeException Se houver algum erro durante a execução. + */ + void setPathContents(); + + /** Retorna o extrator espefifico do arquivo de legenda. */ + Extrator::ExtratorType getExtratorType(); + + /** Indica se o serviço está sendo executado. + * + * \return O status do serviço. + */ + bool isRunning(); +public: + /** Construtor do serviço de vídeo com legendas. + * + * \param pathVideo Path do vídeo de entrada. + * \param pathSRT Path do arquivo de legendas. + * \param sublanguage Linguagem das legendas do arquivo. + * \param pos Posição do vídeo de LIBRAS em relação ao vídeo original. + * \param size Tamanho do vídeo de LIBRAS. + * \param transp Transparência do plano de fundo do vídeo. + * \param id Identificação do cliente. + * \param mode Modo de execução. + * \param serviceType Tipo do serviço. + */ + ServiceWindowGenerationFromSubtitle(char* pathVideo, char* pathSRT, int sublanguage, int pos, + int size, int transp, char* id, int mode, int serviceType); + + /** Construtor do serviço de legendas. + * + * \param pathSRT Path do arquivo de legendas. + * \param sublanguage Linguagem das legendas do arquivo. + * \param transparency Transparência do plano de fundo do vídeo. + * \param id Identificação do cliente. + * \param mode Modo de execução. + * \param serviceType Tipo do serviço. + */ + ServiceWindowGenerationFromSubtitle(char* pathSRT, int sublanguage, int transparency, char* id, int mode, int serviceType); + + /** Destrutor */ + ~ServiceWindowGenerationFromSubtitle(); + + /** Notifica novas legendas extraídas. + * + * \param subtitle A legenda extraída. + * \param pts A etiqueta de tempo da legenda. + */ + void notifySubtitle(unsigned char* subtitle, uint64_t pts); + + /** Recebe a notificação do fim da renderização do vídeo */ + void notifyEndOfRenderization(); + + /** Recebe a notificação do fim da tradução da legenda. + * + * \param glosa A legenda traduzida. + */ + void notifyTranslation(char* glosas); + + /** Envia para a tradução a legenda obtida. + * + * \param text A legenda obtida. + */ + void notifyTranslator(unsigned char* text); + + /** Envia a glosa para o renderizador. + * + * \param glosa A glosa obtida. + * \exception ServiceException Se houver algum erro durante a execução. + */ + void notifyRenderer(string glosa); + + /** Notifica o fim da extração de legendas. + * + * \param sub_size O número de legendas extraídas. + */ + void notifyEnd(int sub_size); + + /** Inicia o serviço de extração de legendas. + * + * \exception ServiceException Se houver algum erro durante a execução. + */ + void initialize(); + + /** Indica o fim do processo do serviço. + * + * \return O status do processo. + */ + bool isFinished(); + + /** Este método é chamado quando a Thread for iniciada. */ + void Run(); +}; + +#endif /* SERVICEWINDOWGENERATIONFROMSUB_H_ */ \ No newline at end of file diff --git a/servico/src/serviceTester.cpp b/servico/src/serviceTester.cpp index a6bb94f..fb4d234 100644 --- a/servico/src/serviceTester.cpp +++ b/servico/src/serviceTester.cpp @@ -26,7 +26,7 @@ void ServiceTester::checkServiceSRT() { PRINTL(util::_DEBUG, "Checando extração de legenda...\n"); setPathContents(); - service_srt = new ServiceWindowGenerationFromSRT((char*)VID_FILE, (char*)SRT_FILE, 1, position, + service_srt = new ServiceWindowGenerationFromSubtitle((char*)VID_FILE, (char*)SRT_FILE, 1, position, resolution, background, (char*)TESTER_ID, MODE_TEST, 1); try{ diff --git a/servico/src/serviceWindowGenerationFromSRT.cpp b/servico/src/serviceWindowGenerationFromSRT.cpp deleted file mode 100644 index 099dc33..0000000 --- a/servico/src/serviceWindowGenerationFromSRT.cpp +++ /dev/null @@ -1,223 +0,0 @@ -#include "serviceWindowGenerationFromSRT.h" - -ServiceWindowGenerationFromSRT::ServiceWindowGenerationFromSRT(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(); - extrator_factory = new ExtratorFactory(); - try{ - setPathContents(); - }catch(RuntimeException ex){ - throw ServiceException(ex.getMessage()); - } - running = true; - finish = false; - PRINTL(util::_DEBUG, "Service SRT Done!\n"); -} - -ServiceWindowGenerationFromSRT::ServiceWindowGenerationFromSRT(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(); - extrator_factory = new ExtratorFactory(); - try{ - setPathContents(); - }catch(RuntimeException ex){ - throw ServiceException(ex.getMessage()); - } - running = true; - finish = false; - PRINTL(util::_DEBUG, "Service SRT Done!\n"); -} - -ServiceWindowGenerationFromSRT::~ServiceWindowGenerationFromSRT() { - free(vetor_pts); - if (tradutor) delete tradutor; - // if (mixer) delete mixer; - if (renderer) delete renderer; - if (extratorSRT)delete extratorSRT; - if (extrator_factory) delete extrator_factory; - PRINTL(util::_DEBUG, "Service SRT finalized!\n"); -} - -void ServiceWindowGenerationFromSRT::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!"); - } -} - -void ServiceWindowGenerationFromSRT::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 ServiceWindowGenerationFromSRT::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 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); - if (sub_language == 1) - notifyTranslator(subtitle); - else{ - string glosa(reinterpret_cast(subtitle)); - notifyRenderer(glosa); - } -} - -void ServiceWindowGenerationFromSRT::notifyTranslation(char* glosa) { - string sGlosa(glosa); - notifyRenderer(sGlosa); -} - -void ServiceWindowGenerationFromSRT::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 ServiceWindowGenerationFromSRT::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 ServiceWindowGenerationFromSRT::notifyEnd(int sub_size) { - PRINTL(util::_DEBUG, "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() { - PRINTL(util::_DEBUG, "Service SRT Initialize.\n"); - setPathLibras(); - extratorSRT = (ExtratorSRT*) extrator_factory->getExtrator(Extrator::SRT); - extratorSRT->addListener(this); - extratorSRT->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{ - extratorSRT->initialize(); - }catch(ExtratorException ex){ - throw ServiceException(ex.getMessage()); - }catch(RuntimeException &ex){ - throw ServiceException(ex.getMessage().c_str()); - } - this->Start(); -} - -void ServiceWindowGenerationFromSRT::Run() { - while(isRunning()){ - usleep(200000); - } - finish = true; -} \ No newline at end of file diff --git a/servico/src/serviceWindowGenerationFromSubtitle.cpp b/servico/src/serviceWindowGenerationFromSubtitle.cpp new file mode 100644 index 0000000..fb7b499 --- /dev/null +++ b/servico/src/serviceWindowGenerationFromSubtitle.cpp @@ -0,0 +1,276 @@ +#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(); + extrator_factory = new ExtratorFactory(); + try{ + setPathContents(); + }catch(RuntimeException ex){ + throw ServiceException(ex.getMessage()); + } + running = true; + finish = false; + PRINTL(util::_DEBUG, "Service SRT 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(); + extrator_factory = new ExtratorFactory(); + try{ + setPathContents(); + }catch(RuntimeException ex){ + throw ServiceException(ex.getMessage()); + } + running = true; + finish = false; + PRINTL(util::_DEBUG, "Service SRT 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 SRT 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 : 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; + } + + 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 glosa(reinterpret_cast(subtitle)); + 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 SRT 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 SRT 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; +} \ No newline at end of file -- libgit2 0.21.2