#include "rotord.h" /* ultimately- audio analysis request will spawn a task - there will be another call that will check progress audio analysis will be saved - to a file? into a db? for now - dump analysis into the http request architecture - running rendering process main vamp library segmenter, beat detector http://127.0.0.1:9000/vamp/qm-vamp-plugins/qm-segmenter/01.wav Running plugin: "qm-segmenter"... Using block size = 26460, step size = 8820 Plugin accepts 1 -> 1 channel(s) Sound file has 2 (will mix/augment if necessary) Output is: "segmentation" Done ./rotord: symbol lookup error: /usr/local/lib/vamp/qm-vamp-plugins.so: undefined symbol: clapack_dgetrf http://www.codeproject.com/Articles/252827/Learning-Poco-A-simple-HTTP-server next: load a movie and retreive frames save a movie how do we deal with frames in libavcodec - can we request a frame by number how do we deal with resolution avcodec class what does it have to do? -open files (could be video, audio, or both) -process files i.e. thumbnail the audio or do audio analysis, make a no-keyframe proxy of a movie -retrieve video frames (with caching- what's the best way to approach this) just for a quick think through: signal data is trivial: 1 floating point number per frame. to store a whole uncompressed video track for a 3 minute @ 720.25p in RGB \= 12GB caching the whole thing isn't a goer */ RotorRequestHandler::RotorRequestHandler(const std::string& format): _format(format){ } void RotorRequestHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) { Timestamp now; std::string dt(DateTimeFormatter::format(now, _format)); response.setChunkedTransferEncoding(true); response.setContentType("text/html"); std::ostream& ostr = response.send(); ostr << "RotorServer powered by " "POCO C++ Libraries"; ostr << ""; ostr << "

"; ostr << dt; ostr << "

"; } RenderContextHandler::RenderContextHandler(const std::string _content,const HTTPServerResponse::HTTPStatus _status){ content=_content; status=_status; } void RenderContextHandler::handleRequest(HTTPServerRequest& request,HTTPServerResponse& response) { response.setChunkedTransferEncoding(true); response.setContentType("text/html"); response.setStatus(status); std::ostream& ostr = response.send(); ostr << "\n"; ostr << content; } HTTPRequestHandler* RotorRequestHandlerFactory::createRequestHandler(const HTTPServerRequest& request){ Logger& logger = Logger::get("Rotor"); Poco::URI theuri=Poco::URI(request.getURI()); std::vector command; theuri.getPathSegments(command); logger.information(request.clientAddress().toString()+" "+request.getMethod()); string content=""; HTTPResponse::HTTPStatus status=HTTPResponse::HTTP_BAD_REQUEST; //by default std::string body; std::ostringstream os; os<\n"; status=HTTPResponse::HTTP_OK; } if (request.getMethod()=="PUT") { //undocumented manual thread name if (body.size()) { string sID=body; cerr << "Rotor: starting thread "<< sID << endl; manager.start(new Rotor::Render_context(sID)); content=""+sID+"\n"; status=HTTPResponse::HTTP_OK; } } } else if (command[0]=="list") { if (request.getMethod()=="GET") { //std::list < Poco::AutoPtr < Poco::Task > >::iterator it; //it=manager.taskList().begin(); //for (it=manager.taskList().begin();it !=manager.taskList().end();++it) { //content+=""+(*it)->name()+"\n"; //} //massive problems making an iterator for the tasklist, the above crashes //solution: auto type range-based for-loop //this is c++11 specific but works for (auto& task: manager.taskList()) { //c++11 content+=""+task->name()+" \n"; } status=HTTPResponse::HTTP_OK; } } else if (command[0]=="styles") { //eventually retrieve from sql; //a bit of weirdness here: prefer to just get whole file to a string. if (request.getMethod()=="GET") { std::string stylesfile = "styles.xml"; Poco::File f=Poco::File(stylesfile); if (f.exists()) { Poco::FileInputStream file(stylesfile); //while (!file.eof()) { // file >> content; //} Poco::StreamCopier::copyToString(file, content); status=HTTPResponse::HTTP_OK; } else { content="Rotor: internal error: styles not found\n"; } } else { content="Rotor: bad request\n"; } } else if (command[0]=="exit") { exit(0); } else { bool found=false; for (auto& task: manager.taskList()) { //c++11 if(task->name()==command[0]) { //valid session command found=true; if (command.size()==1) { //just invoking sID if (request.getMethod()=="DELETE") { task->cancel(); content="1\n"; status=HTTPResponse::HTTP_OK; } else { content="Rotor: render context invoked with no command\n"; } } else { //session modifier command- to be passed to render context //some commands need to return error codes //ie where the audio file isn't found //on the other hand, some commands need to know state of the renderer? vector sc; //method,id,command1,{command2,}{body} sc.push_back(request.getMethod()); for (auto& i: command){ sc.push_back(i); } sc.push_back(body); Rotor::Command_response response=((Poco::AutoPtr)task)->session_command(sc); content=response.description; status=response.status; } } } if (!found) { status=HTTPResponse::HTTP_NOT_FOUND; content="Rotor: render context not found\n"; } } } else { content="Rotor: empty request"; } return new RenderContextHandler(content, status); } RotorServer::RotorServer(): _helpRequested(false) { } RotorServer::~RotorServer() { } void RotorServer::initialize(Application& self){ loadConfiguration(); ServerApplication::initialize(self); } void RotorServer::uninitialize(){ ServerApplication::uninitialize(); } void RotorServer::defineOptions(OptionSet& options) { ServerApplication::defineOptions(options); options.addOption( Option("help", "h", "display argument help information") .required(false) .repeatable(false) .callback(OptionCallback(this, &RotorServer::handleHelp) ) ); } void RotorServer::handleHelp(const std::string& name, const std::string& value){ HelpFormatter helpFormatter(options()); helpFormatter.setCommand(commandName()); helpFormatter.setUsage("OPTIONS"); helpFormatter.setHeader( "Rotor"); helpFormatter.format(std::cout); stopOptionsProcessing(); _helpRequested = true; } int RotorServer::main(const std::vector& args){ if (!_helpRequested) { unsigned short port; xmlIO xml; if(xml.loadFile("settings.xml") ){ port=xml.getAttribute("Rotor","port",9980,0); } else cerr<<"Rotord: settings.xml not found, using defaults"<