#include "renderer.h" Renderer::Renderer(char* videoPath, char* user_id) { this->folder_id = user_id; this->path_video = videoPath; running = true; count_task = 0; glosa_processed = 0; core_socket = new StreamSocket(); listeners = new list(); serverInitialize(); PRINTL(util::_DEBUG, "Renderer Done!\n"); } Renderer::~Renderer() { listeners->clear(); delete listeners; if(core_socket) delete core_socket; PRINTL(util::_DEBUG, "Renderer finalized!\n"); } void Renderer::serverInitialize(){ string render = "python render.py "; render.append(folder_id).append(" >/dev/null 2>&1 &"); string command = "cd "; char* shPath; shPath = getenv("RENDERER"); if(shPath != NULL) command.append(shPath); else command.append(PATH_RENDERER); command.append(" && ").append(render); system(command.c_str()); sleep(5); } void Renderer::receiveGlosa(std::string glosa, int64_t pts) { if(glosa == "SENTENCACOMBAIXAQUALIDADE") glosa_copy = "_DEFAULT"; else glosa_copy = glosa; ostringstream oss; oss << pts; glosa_copy += "#"; // formato da string enviada p/ o player: Glosa#pts glosa_copy += oss.str(); count_task++; } void Renderer::sendGlosa() { try{ // while(!core_socket->isConnected()) // sleep(1); int glosa_size = strlen(glosa_copy.c_str())+1; char* glosa_buffer = new char[glosa_size]; strcpy(glosa_buffer, glosa_copy.c_str()); core_socket->write(glosa_buffer, glosa_size); char* ok_core = new char[3]; do { core_socket->read(ok_core, 3); //aguarda o unity confirmar o recebimento da glosa }while(strcmp(ok_core, "OK") != 0); glosa_processed++; delete [] ok_core; delete [] glosa_buffer; }catch(lavidlib::RuntimeException &ex){ throw lavidlib::RuntimeException(ex.getMessage().c_str()); }catch(lavidlib::IOException &ex){ throw lavidlib::RuntimeException(ex.getMessage().c_str()); } } void Renderer::connectToUnity() { try{ static InetAddress* addr = InetAddress::createByName(HOST); while(!core_socket->isConnected()){ PRINTL(util::_DEBUG, "Conectando ao Unity...\n"); core_socket->connect(addr, PORTNO); sleep(1); } }catch(lavidlib::UnknownHostException &ex){ throw RuntimeException(ex.getMessage().c_str()); }catch(lavidlib::SocketException &ex){ throw RuntimeException(ex.getMessage().c_str()); } } void Renderer::waitScreenShots() { PRINTL(util::_INFO, "Gerando vídeo...\n"); char* endgeneration = new char[strlen(END_FLAG)+1]; int connected; try{ do{ connected = core_socket->read(endgeneration, sizeof(endgeneration)); }while(strcmp(endgeneration, END_FLAG) != 0 && connected != 0); core_socket->close(); }catch(IOException &ex){ throw RuntimeException(ex.getMessage().c_str()); } } void Renderer::addListener(ListenerRenderer* listener) { listeners->push_back(listener); } void Renderer::notifyListeners() { PRINTL(util::_DEBUG, "Renderização finalizada!\n"); for (list::iterator i = listeners->begin(); i != listeners->end(); i++) { (*i)->notifyEndOfRenderization(); } } void Renderer::finalize() { while(glosa_processed < count_task) usleep(10000); receiveGlosa(END_FLAG, (int64_t) -1); this->running = false; } bool Renderer::isSending() { if(glosa_processed < count_task) return true; else return false; } void Renderer::Run() { try{ while(running){ while(count_task <= glosa_processed){ usleep(10000); } if(!core_socket->isConnected()) connectToUnity(); sendGlosa(); } waitScreenShots(); render(); cleanFiles(); }catch(lavidlib::RuntimeException &ex){ PRINTL(util::_ERROR, "%s\n", ex.getMessage().c_str()); Logging::instance()->writeLog("renderer.cpp : Falha na comunicação com o Unity player"); throw RuntimeException(ex.getMessage().c_str()); } } void Renderer::render() { string command = "ffmpeg -y -loglevel quiet -framerate 30 -i "; command.append(PATH_SCREENS).append(folder_id).append("/frame_%d.png ") .append("-vcodec libx264 -pix_fmt yuv420p ").append(path_video); system(command.c_str()); notifyListeners(); } void Renderer::cleanFiles() { string clean = "rm -rf "; clean.append(PATH_SCREENS).append(folder_id).append("/"); system(clean.c_str()); }