smil support by Oswald de Bruin

This commit is contained in:
Thulinma 2014-06-20 19:58:05 +02:00
parent f09e58e034
commit f538bd0d93
3 changed files with 115 additions and 0 deletions

View file

@ -309,6 +309,54 @@ namespace Connector_HTTP {
return ret;
}
// send smil MBR index
if (url.length() > 6 && url.substr(url.length() - 5, 5) == ".smil"){
std::string streamname = url.substr(1, url.length() - 6);
Util::Stream::sanitizeName(streamname);
JSON::Value ServConf = JSON::fromFile(Util::getTmpFolder() + "streamlist");
std::string host = H.GetHeader("Host");
if (host.find(':')){
host.resize(host.find(':'));
}
std::string port, url_rel;
for (JSON::ArrIter it = ServConf["config"]["protocols"].ArrBegin(); it != ServConf["config"]["protocols"].ArrEnd(); it++){
const std::string & cName = ( *it)["connector"].asStringRef();
if (cName != "RTMP"){continue;}
//if we have the RTMP port,
if (capabilities.isMember(cName) && capabilities[cName].isMember("optional") && capabilities[cName]["optional"].isMember("port")){
//get the default port if none is set
if (( *it)["port"].asInt() == 0){
port = capabilities[cName]["optional"]["port"]["default"].asString();
}
//extract url
if (capabilities[cName].isMember("url_rel")){
url_rel = capabilities[cName]["url_rel"].asString();
if (url_rel.find('$')){
url_rel.resize(url_rel.find('$'));
}
}
}
}
std::string trackSources;//this string contains all track sources for MBR smil
for (JSON::ObjIter it = ServConf["streams"][streamname]["meta"]["tracks"].ObjBegin(); it != ServConf["streams"][streamname]["meta"]["tracks"].ObjEnd(); it++){//for all tracks
if (it->second.isMember("type") && it->second["type"].asString() == "video"){
trackSources += " <video src='"+ streamname + "?track=" + it->second["trackid"].asString() + "' height='" + it->second["height"].asString() + "' system-bitrate='" + it->second["bps"].asString() + "' width='" + it->second["width"].asString() + "' />\n";
}
}
H.Clean();
H.SetHeader("Content-Type", "application/smil");
H.SetHeader("Server", "mistserver/" PACKAGE_VERSION "/" + Util::Config::libver);
H.SetBody("<smil>\n <head>\n <meta base='rtmp://" + host + ":" + port + url_rel + "' />\n </head>\n <body>\n <switch>\n"+trackSources+" </switch>\n </body>\n</smil>");
long long int ret = Util::getMS();
conn.SendNow(H.BuildResponse("200", "OK"));
return ret;
}
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(url.length() - 3, 3) == ".js")){
std::string streamname;
@ -549,6 +597,9 @@ namespace Connector_HTTP {
if (url.length() > 6 && url.substr(url.length() - 5, 5) == ".html"){
return "internal";
}
if (url.length() > 6 && url.substr(url.length() - 5, 5) == ".smil"){
return "internal";
}
}
if (url == "/crossdomain.xml"){
return "internal";

View file

@ -38,6 +38,61 @@ namespace Mist {
OutRTMP::~OutRTMP() {}
void OutRTMP::parseVars(std::string data){
std::string varname;
std::string varval;
bool trackSwitch = false;
// position where a part start (e.g. after &)
size_t pos = 0;
while (pos < data.length()){
size_t nextpos = data.find('&', pos);
if (nextpos == std::string::npos){
nextpos = data.length();
}
size_t eq_pos = data.find('=', pos);
if (eq_pos < nextpos){
// there is a key and value
varname = data.substr(pos, eq_pos - pos);
varval = data.substr(eq_pos + 1, nextpos - eq_pos - 1);
}else{
// no value, only a key
varname = data.substr(pos, nextpos - pos);
varval.clear();
}
//SetVar(urlunescape(varname), urlunescape(varval));
if (varname == "track"){
long long int selTrack = JSON::Value(varval).asInt();
if (myMeta){
if (myMeta.tracks.count(selTrack)){
std::string & delThis = myMeta.tracks[selTrack].type;
for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
if (myMeta.tracks[*it].type == delThis){
selectedTracks.erase(it);
trackSwitch = true;
break;
}
}
selectedTracks.insert(selTrack);
}
}else{
selectedTracks.insert(selTrack);
}
}
if (nextpos == std::string::npos){
// in case the string is gigantic
break;
}
// erase &
pos = nextpos + 1;
}
if (trackSwitch){
seek(currentPacket.getTime());
}
}
void OutRTMP::init(Util::Config * cfg) {
Output::init(cfg);
capa["name"] = "RTMP";
@ -446,6 +501,14 @@ namespace Mist {
int playMessageType = messageType;
int playStreamId = streamId;
streamName = amfData.getContentP(3)->StrValue();
//handle variables
if (streamName.find('?') != std::string::npos){
std::string tmpVars = streamName.substr(streamName.find('?') + 1);
Util::Stream::sanitizeName(streamName);
parseVars(tmpVars);
}
initialize();
//send a status reply

View file

@ -14,6 +14,7 @@ namespace Mist {
void sendNext();
void sendHeader();
protected:
void parseVars(std::string data);
std::string app_name;
bool sending;
int counter;