Improved embeds, controller now stores metadata.

This commit is contained in:
Thulinma 2012-08-29 15:01:58 +02:00
parent a04adbca78
commit b151b13f66
3 changed files with 75 additions and 23 deletions

View file

@ -60,7 +60,10 @@ std::string Buffer::Stream::getStats(){
Storage["totals"]["up"] = tot_up; Storage["totals"]["up"] = tot_up;
Storage["totals"]["count"] = tot_count; Storage["totals"]["count"] = tot_count;
Storage["totals"]["now"] = now; Storage["totals"]["now"] = now;
Storage["totals"]["buffer"] = name; Storage["buffer"] = name;
Storage["meta"] = Strm->metadata;
if (Storage["meta"].isMember("audio")){Storage["meta"]["audio"].removeMember("init");}
if (Storage["meta"].isMember("video")){Storage["meta"]["video"].removeMember("init");}
std::string ret = Storage.toString(); std::string ret = Storage.toString();
Storage["log"].null(); Storage["log"].null();
stats_mutex.unlock(); stats_mutex.unlock();

View file

@ -101,7 +101,9 @@ namespace Connector_HTTP{
/// Handles internal requests. /// Handles internal requests.
void Handle_Internal(HTTP::Parser & H, Socket::Connection * conn){ void Handle_Internal(HTTP::Parser & H, Socket::Connection * conn){
if (H.url == "/crossdomain.xml"){ std::string url = H.url;
if (url == "/crossdomain.xml"){
H.Clean(); H.Clean();
H.SetHeader("Content-Type", "text/xml"); H.SetHeader("Content-Type", "text/xml");
H.SetHeader("Server", "mistserver/" PACKAGE_VERSION "/" + Util::Config::libver); H.SetHeader("Server", "mistserver/" PACKAGE_VERSION "/" + Util::Config::libver);
@ -110,22 +112,60 @@ namespace Connector_HTTP{
return; return;
}//crossdomain.xml }//crossdomain.xml
if (H.url.length() > 10 && H.url.substr(0, 7) == "/embed_" && H.url.substr(H.url.length() - 3, 3) == ".js"){ if ((url.length() > 9 && url.substr(0, 6) == "/info_" && url.substr(url.length() - 3, 3) == ".js") || (url.length() > 10 && url.substr(0, 7) == "/embed_" && url.substr(H.url.length() - 3, 3) == ".js")){
std::string streamname = H.url.substr(7, H.url.length() - 10); std::string streamname;
if (url.substr(0, 6) == "/info_"){
streamname = url.substr(6, url.length() - 9);
}else{
streamname = url.substr(7, url.length() - 10);
}
JSON::Value ServConf = JSON::fromFile("/tmp/mist/streamlist"); JSON::Value ServConf = JSON::fromFile("/tmp/mist/streamlist");
std::string response; std::string response;
std::string host = H.GetHeader("Host");
if (host.find(':')){host.resize(host.find(':'));}
H.Clean(); H.Clean();
H.SetHeader("Server", "mistserver/" PACKAGE_VERSION "/" + Util::Config::libver); H.SetHeader("Server", "mistserver/" PACKAGE_VERSION "/" + Util::Config::libver);
H.SetHeader("Content-Type", "application/javascript"); H.SetHeader("Content-Type", "application/javascript");
response = "// Generating embed code for stream " + streamname + "\n\n"; response = "// Generating info code for stream " + streamname + "\n\nif (!mistvideo){var mistvideo = {};}\n";
if (ServConf["streams"].isMember(streamname)){ JSON::Value json_resp;
std::string streamurl = "http://" + H.GetHeader("Host") + "/" + streamname + ".flv"; if (ServConf["streams"].isMember(streamname) && ServConf["config"]["protocols"].size() > 0){
response += "// Stream URL: " + streamurl + "\n\n"; json_resp["width"] = ServConf["statistics"][streamname]["meta"]["video"]["width"].asInt();
response += "document.write('<object width=\"600\" height=\"409\"><param name=\"movie\" value=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\"></param><param name=\"flashvars\" value=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"600\" height=\"409\" flashvars=\"src="+HTTP::Parser::urlencode(streamurl)+"&controlBarMode=floating\"></embed></object>');\n"; json_resp["height"] = ServConf["statistics"][streamname]["meta"]["video"]["height"].asInt();
//first, see if we have RTMP working and output all the RTMP.
for (JSON::ArrIter it = ServConf["config"]["protocols"].ArrBegin(); it != ServConf["config"]["protocols"].ArrEnd(); it++){
if ((*it)["connector"].asString() == "RTMP"){
JSON::Value tmp;
tmp["type"] = "rtmp";
tmp["url"] = "rtmp://" + host + ":" + (*it)["port"].asString() + "/play/" + streamname;
json_resp["source"].append(tmp);
}
}
//then, see if we have HTTP working and output all the dynamic.
for (JSON::ArrIter it = ServConf["config"]["protocols"].ArrBegin(); it != ServConf["config"]["protocols"].ArrEnd(); it++){
if ((*it)["connector"].asString() == "HTTP"){
JSON::Value tmp;
tmp["type"] = "f4v";
tmp["url"] = "http://" + host + ":" + (*it)["port"].asString() + "/"+streamname+"/manifest.f4m";
json_resp["source"].append(tmp);
}
}
//and all the progressive.
for (JSON::ArrIter it = ServConf["config"]["protocols"].ArrBegin(); it != ServConf["config"]["protocols"].ArrEnd(); it++){
if ((*it)["connector"].asString() == "HTTP"){
JSON::Value tmp;
tmp["type"] = "flv";
tmp["url"] = "http://" + host + ":" + (*it)["port"].asString() + "/"+streamname+".flv";
json_resp["source"].append(tmp);
}
}
}else{ }else{
response += "// Stream not available at this server.\nalert(\"This stream is currently not available at this server.\\\\nPlease try again later!\");"; json_resp["error"] = "The specified stream is not available on this server.";
json_resp["bbq"] = "sauce";//for legacy purposes ^_^
}
response += "mistvideo['" + streamname + "'] = "+json_resp.toString()+";\n";
if (url.substr(0, 6) != "/info_" && !json_resp.isMember("error")){
response += "\n\nif(!mistvideo.hasSupport||!mistvideo.buildPlayer){mistvideo.flashVersion=function(){var version=0;try{version=navigator.mimeTypes['application/x-shockwave-flash'].enabledPlugin.description.replace(/([^0-9\\.])/g,'').split('.')[0];}catch(e){}try{version=new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable(\"$version\").replace(/([^0-9\\,])/g,'').split(',')[0];}catch(e){}return version;};mistvideo.supports={flashversion:parseInt(mistvideo.flashVersion(),10)};mistvideo.hasSupport=function(type){switch(type){case'f4v':return mistvideo.supports.flashversion>=11;break;case'rtmp':return mistvideo.supports.flashversion>=10;break;case'flv':return mistvideo.supports.flashversion>=7;break;default:return false;}};mistvideo.buildPlayer=function(src,container,width,height){switch(src.type){case'f4v':case'rtmp':case'flv':container.innerHTML='<object width=\"'+width+'\" height=\"'+height+'\"><param name=\"movie\" value=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\"></param><param name=\"flashvars\" value=\"src='+encodeURI(src.url)+'&controlBarMode=floating\"></param><param name=\"allowFullScreen\" value=\"true\"></param><param name=\"allowscriptaccess\" value=\"always\"></param><embed src=\"http://fpdownload.adobe.com/strobe/FlashMediaPlayback.swf\" type=\"application/x-shockwave-flash\" allowscriptaccess=\"always\" allowfullscreen=\"true\" width=\"'+width+'\" height=\"'+height+'\" flashvars=\"src='+encodeURI(src.url)+'&controlBarMode=floating\"></embed></object>';break;}};}var video=mistvideo['"+streamname+"'],container=document.createElement('div'),scripts=document.getElementsByTagName('script'),me=scripts[scripts.length-1];me.parentNode.insertBefore(container,me);container.setAttribute('class','mistvideo');me.parentNode.removeChild(me);if(video.error){container.innerHTML=['<strong>Error: ',video.error,'</strong>'].join('');}else if(video.source.length<1){container.innerHTML='<strong>Error: no streams found</strong>';}else{var i,videofoundPlayer=false,len=video.source.length;for(i=0;i<len;i++){if(mistvideo.hasSupport(video.source[i].type)){mistvideo.buildPlayer(video.source[i],container,video.width,video.height);foundPlayer=true;break;}}if(!foundPlayer){container.innerHTML='fallback here';}}\n";
} }
response += "";
H.SetBody(response); H.SetBody(response);
conn->Send(H.BuildResponse("200", "OK")); conn->Send(H.BuildResponse("200", "OK"));
return; return;
@ -261,6 +301,7 @@ namespace Connector_HTTP{
} }
if (H.url == "/crossdomain.xml"){return "internal";} if (H.url == "/crossdomain.xml"){return "internal";}
if (H.url.length() > 10 && H.url.substr(0, 7) == "/embed_" && H.url.substr(H.url.length() - 3, 3) == ".js"){return "internal";} if (H.url.length() > 10 && H.url.substr(0, 7) == "/embed_" && H.url.substr(H.url.length() - 3, 3) == ".js"){return "internal";}
if (H.url.length() > 9 && H.url.substr(0, 6) == "/info_" && H.url.substr(H.url.length() - 3, 3) == ".js"){return "internal";}
return "none"; return "none";
} }

View file

@ -171,7 +171,11 @@ void CheckProtocols(JSON::Value & p){
} }
counter = counter.asInt() + 1; counter = counter.asInt() + 1;
new_connectors[std::string("Conn")+counter.asString()] = tmp; new_connectors[std::string("Conn")+counter.asString()] = tmp;
(*ait)["online"] = Util::Procs::isActive(std::string("Conn")+counter.asString()); if (Util::Procs::isActive(std::string("Conn")+counter.asString())){
(*ait)["online"] = 1;
}else{
(*ait)["online"] = 0;
}
} }
//shut down deleted/changed connectors //shut down deleted/changed connectors
@ -423,18 +427,22 @@ int main(int argc, char ** argv){
size_t newlines = it->Received().find("\n\n"); size_t newlines = it->Received().find("\n\n");
while (newlines != std::string::npos){ while (newlines != std::string::npos){
Request = JSON::fromString(it->Received().substr(0, newlines)); Request = JSON::fromString(it->Received().substr(0, newlines));
if (Request.isMember("totals") && Request["totals"].isMember("buffer")){ if (Request.isMember("buffer")){
std::string thisbuffer = Request["totals"]["buffer"]; std::string thisbuffer = Request["buffer"];
Connector::lastBuffer[thisbuffer] = time(0); Connector::lastBuffer[thisbuffer] = time(0);
Connector::Storage["statistics"][thisbuffer]["curr"] = Request["curr"]; if (Request.isMember("meta")){
std::stringstream st; Connector::Storage["statistics"][thisbuffer]["meta"] = Request["meta"];
st << Request["totals"]["now"].asInt(); }
std::string nowstr = st.str(); if (Request.isMember("totals")){
Connector::Storage["statistics"][thisbuffer]["totals"][nowstr] = Request["totals"]; Connector::Storage["statistics"][thisbuffer]["curr"] = Request["curr"];
Connector::Storage["statistics"][thisbuffer]["totals"].shrink(600);//limit to 10 minutes of data std::string nowstr = Request["totals"]["now"].asString();
for (JSON::ObjIter jit = Request["log"].ObjBegin(); jit != Request["log"].ObjEnd(); jit++){ Connector::Storage["statistics"][thisbuffer]["totals"][nowstr] = Request["totals"];
Connector::Storage["statistics"][thisbuffer]["log"].append(jit->second); Connector::Storage["statistics"][thisbuffer]["totals"].shrink(600);//limit to 10 minutes of data
Connector::Storage["statistics"][thisbuffer]["log"].shrink(1000);//limit to 1000 users per buffer //if metadata is available, store it
for (JSON::ObjIter jit = Request["log"].ObjBegin(); jit != Request["log"].ObjEnd(); jit++){
Connector::Storage["statistics"][thisbuffer]["log"].append(jit->second);
Connector::Storage["statistics"][thisbuffer]["log"].shrink(1000);//limit to 1000 users per buffer
}
} }
} }
it->Received().erase(0, newlines+2); it->Received().erase(0, newlines+2);