MistInBuffer no longer boots if the process starting it has no data to fill it with. Optimized and simplified HTTP internal output.
This commit is contained in:
		
							parent
							
								
									7fae3e6739
								
							
						
					
					
						commit
						26f74accdf
					
				
					 8 changed files with 75 additions and 86 deletions
				
			
		| 
						 | 
					@ -115,11 +115,11 @@ bool Util::streamAlive(std::string & streamname){
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Assures the input for the given stream name is active.
 | 
					/// Assures the input for the given stream name is active.
 | 
				
			||||||
/// Does stream name sanitizion first, followed by a stream name length check (<= 100 chars).
 | 
					/// Does stream name sanitation first, followed by a stream name length check (<= 100 chars).
 | 
				
			||||||
/// Then, checks if an input is already active by running streamAlive(). If yes, aborts.
 | 
					/// Then, checks if an input is already active by running streamAlive(). If yes, return true.
 | 
				
			||||||
/// If no, loads up the server configuration and attempts to start the given stream according to current config.
 | 
					/// If no, loads up the server configuration and attempts to start the given stream according to current configuration.
 | 
				
			||||||
/// At this point, fails and aborts if MistController isn't running.
 | 
					/// At this point, fails and aborts if MistController isn't running.
 | 
				
			||||||
bool Util::startInput(std::string streamname, std::string filename, bool forkFirst) {
 | 
					bool Util::startInput(std::string streamname, std::string filename, bool forkFirst, bool isProvider) {
 | 
				
			||||||
  sanitizeName(streamname);
 | 
					  sanitizeName(streamname);
 | 
				
			||||||
  if (streamname.size() > 100){
 | 
					  if (streamname.size() > 100){
 | 
				
			||||||
    FAIL_MSG("Stream opening denied: %s is longer than 100 characters (%lu).", streamname.c_str(), streamname.size());
 | 
					    FAIL_MSG("Stream opening denied: %s is longer than 100 characters (%lu).", streamname.c_str(), streamname.size());
 | 
				
			||||||
| 
						 | 
					@ -172,6 +172,7 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
 | 
				
			||||||
  DTSC::Scan inputs = config.getMember("capabilities").getMember("inputs");
 | 
					  DTSC::Scan inputs = config.getMember("capabilities").getMember("inputs");
 | 
				
			||||||
  DTSC::Scan input;
 | 
					  DTSC::Scan input;
 | 
				
			||||||
  unsigned int input_size = inputs.getSize();
 | 
					  unsigned int input_size = inputs.getSize();
 | 
				
			||||||
 | 
					  bool noProviderNoPick = false;
 | 
				
			||||||
  for (unsigned int i = 0; i < input_size; ++i){
 | 
					  for (unsigned int i = 0; i < input_size; ++i){
 | 
				
			||||||
    DTSC::Scan tmp_input = inputs.getIndice(i);
 | 
					    DTSC::Scan tmp_input = inputs.getIndice(i);
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -185,6 +186,10 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
 | 
				
			||||||
          MEDIUM_MSG("Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), tmp_input.getMember("name").asString().c_str(), source.c_str());
 | 
					          MEDIUM_MSG("Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), tmp_input.getMember("name").asString().c_str(), source.c_str());
 | 
				
			||||||
          
 | 
					          
 | 
				
			||||||
          if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
 | 
					          if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
 | 
				
			||||||
 | 
					            if (tmp_input.getMember("non-provider") && !isProvider){
 | 
				
			||||||
 | 
					              noProviderNoPick = true;
 | 
				
			||||||
 | 
					              continue;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            player_bin = Util::getMyPath() + "MistIn" + tmp_input.getMember("name").asString();
 | 
					            player_bin = Util::getMyPath() + "MistIn" + tmp_input.getMember("name").asString();
 | 
				
			||||||
            curPrio = tmp_input.getMember("priority").asInt();
 | 
					            curPrio = tmp_input.getMember("priority").asInt();
 | 
				
			||||||
            selected = true;
 | 
					            selected = true;
 | 
				
			||||||
| 
						 | 
					@ -198,6 +203,10 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
 | 
				
			||||||
        MEDIUM_MSG("Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), tmp_input.getMember("name").asString().c_str(), source.c_str());
 | 
					        MEDIUM_MSG("Checking input %s: %s (%s)", inputs.getIndiceName(i).c_str(), tmp_input.getMember("name").asString().c_str(), source.c_str());
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
 | 
					        if (filename.substr(0,front.size()) == front && filename.substr(filename.size()-back.size()) == back){
 | 
				
			||||||
 | 
					          if (tmp_input.getMember("non-provider") && !isProvider){
 | 
				
			||||||
 | 
					            noProviderNoPick = true;
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
          player_bin = Util::getMyPath() + "MistIn" + tmp_input.getMember("name").asString();
 | 
					          player_bin = Util::getMyPath() + "MistIn" + tmp_input.getMember("name").asString();
 | 
				
			||||||
          curPrio = tmp_input.getMember("priority").asInt();
 | 
					          curPrio = tmp_input.getMember("priority").asInt();
 | 
				
			||||||
          selected = true;
 | 
					          selected = true;
 | 
				
			||||||
| 
						 | 
					@ -210,7 +219,11 @@ bool Util::startInput(std::string streamname, std::string filename, bool forkFir
 | 
				
			||||||
  
 | 
					  
 | 
				
			||||||
  if (!selected){
 | 
					  if (!selected){
 | 
				
			||||||
    configLock.post();//unlock the config semaphore
 | 
					    configLock.post();//unlock the config semaphore
 | 
				
			||||||
    FAIL_MSG("No compatible input found for stream %s: %s", streamname.c_str(), filename.c_str());
 | 
					    if (noProviderNoPick){
 | 
				
			||||||
 | 
					      INFO_MSG("Not a media provider for stream %s: %s", streamname.c_str(), filename.c_str());
 | 
				
			||||||
 | 
					    }else{
 | 
				
			||||||
 | 
					      FAIL_MSG("No compatible input found for stream %s: %s", streamname.c_str(), filename.c_str());
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    return false;
 | 
					    return false;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,7 @@ namespace Util {
 | 
				
			||||||
  std::string getTmpFolder();
 | 
					  std::string getTmpFolder();
 | 
				
			||||||
  void sanitizeName(std::string & streamname);
 | 
					  void sanitizeName(std::string & streamname);
 | 
				
			||||||
  bool streamAlive(std::string & streamname);
 | 
					  bool streamAlive(std::string & streamname);
 | 
				
			||||||
  bool startInput(std::string streamname, std::string filename = "", bool forkFirst = true);
 | 
					  bool startInput(std::string streamname, std::string filename = "", bool forkFirst = true, bool isProvider = false);
 | 
				
			||||||
  JSON::Value getStreamConfig(std::string streamname);
 | 
					  JSON::Value getStreamConfig(std::string streamname);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -261,7 +261,8 @@ namespace Mist {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    finish();
 | 
					    finish();
 | 
				
			||||||
    DEBUG_MSG(DLVL_DEVEL,"Input for stream %s closing clean", streamName.c_str());
 | 
					    DEBUG_MSG(DLVL_DEVEL, "Input for stream %s closing clean", streamName.c_str());
 | 
				
			||||||
 | 
					    userPage.finishEach();
 | 
				
			||||||
    //end player functionality
 | 
					    //end player functionality
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -301,7 +302,7 @@ namespace Mist {
 | 
				
			||||||
      WARN_MSG("Stream already online, cancelling");
 | 
					      WARN_MSG("Stream already online, cancelling");
 | 
				
			||||||
      return;
 | 
					      return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    if (!Util::startInput(streamName, "push://INTERNAL_ONLY:"+config->getString("input"))) {//manually override stream url to start the buffer
 | 
					    if (!Util::startInput(streamName, "push://INTERNAL_ONLY:"+config->getString("input"), true, true)) {//manually override stream url to start the buffer
 | 
				
			||||||
      pullLock.post();
 | 
					      pullLock.post();
 | 
				
			||||||
      pullLock.close();
 | 
					      pullLock.close();
 | 
				
			||||||
      pullLock.unlink();
 | 
					      pullLock.unlink();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,6 +51,7 @@ namespace Mist {
 | 
				
			||||||
    option.null();
 | 
					    option.null();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    capa["source_match"] = "push://*";
 | 
					    capa["source_match"] = "push://*";
 | 
				
			||||||
 | 
					    capa["non-provider"] = true;//Indicates we don't provide data, only collect it
 | 
				
			||||||
    capa["priority"] = 9ll;
 | 
					    capa["priority"] = 9ll;
 | 
				
			||||||
    capa["desc"] = "Provides buffered live input";
 | 
					    capa["desc"] = "Provides buffered live input";
 | 
				
			||||||
    capa["codecs"][0u][0u].append("*");
 | 
					    capa["codecs"][0u][0u].append("*");
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -186,7 +186,7 @@ namespace Mist{
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }else{
 | 
					    }else{
 | 
				
			||||||
      if (!Util::startInput(streamName)){
 | 
					      if (!Util::startInput(streamName, "", true, isPushing())){
 | 
				
			||||||
        FAIL_MSG("Opening stream %s failed - aborting initialization", streamName.c_str());
 | 
					        FAIL_MSG("Opening stream %s failed - aborting initialization", streamName.c_str());
 | 
				
			||||||
        onFail();
 | 
					        onFail();
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
| 
						 | 
					@ -224,8 +224,8 @@ namespace Mist{
 | 
				
			||||||
    updateMeta();
 | 
					    updateMeta();
 | 
				
			||||||
    selectDefaultTracks();
 | 
					    selectDefaultTracks();
 | 
				
			||||||
    if (!myMeta.vod && !isReadyForPlay()){
 | 
					    if (!myMeta.vod && !isReadyForPlay()){
 | 
				
			||||||
      unsigned long long waitUntil = Util::epoch() + 15;
 | 
					      unsigned long long waitUntil = Util::epoch() + 30;
 | 
				
			||||||
      while (!myMeta.vod && !isReadyForPlay()){
 | 
					      while (!myMeta.vod && !isReadyForPlay() && nProxy.userClient.isAlive()){
 | 
				
			||||||
        if (Util::epoch() > waitUntil + 45 || (!selectedTracks.size() && Util::epoch() > waitUntil)){
 | 
					        if (Util::epoch() > waitUntil + 45 || (!selectedTracks.size() && Util::epoch() > waitUntil)){
 | 
				
			||||||
          INFO_MSG("Giving up waiting for playable tracks. Stream: %s, IP: %s", streamName.c_str(), getConnectedHost().c_str());
 | 
					          INFO_MSG("Giving up waiting for playable tracks. Stream: %s, IP: %s", streamName.c_str(), getConnectedHost().c_str());
 | 
				
			||||||
          break;
 | 
					          break;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -224,32 +224,34 @@ namespace Mist {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      INFO_MSG("Received request %s", H.getUrl().c_str());
 | 
					      INFO_MSG("Received request %s", H.getUrl().c_str());
 | 
				
			||||||
      selectedTracks.clear();
 | 
					      if (H.GetVar("audio") != "" || H.GetVar("video") != ""){
 | 
				
			||||||
      if (H.GetVar("audio") != ""){
 | 
					        selectedTracks.clear();
 | 
				
			||||||
        selectedTracks.insert(JSON::Value(H.GetVar("audio")).asInt());
 | 
					        if (H.GetVar("audio") != ""){
 | 
				
			||||||
      }
 | 
					          selectedTracks.insert(JSON::Value(H.GetVar("audio")).asInt());
 | 
				
			||||||
      if (H.GetVar("video") != ""){
 | 
					        }
 | 
				
			||||||
        selectedTracks.insert(JSON::Value(H.GetVar("video")).asInt());
 | 
					        if (H.GetVar("video") != ""){
 | 
				
			||||||
      }
 | 
					          selectedTracks.insert(JSON::Value(H.GetVar("video")).asInt());
 | 
				
			||||||
      selectDefaultTracks();
 | 
					        }
 | 
				
			||||||
      std::set<unsigned long> toRemove;
 | 
					        selectDefaultTracks();
 | 
				
			||||||
      if (H.GetVar("video") == "0"){
 | 
					        std::set<unsigned long> toRemove;
 | 
				
			||||||
        for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
 | 
					        if (H.GetVar("video") == "0"){
 | 
				
			||||||
          if (myMeta.tracks.at(*it).type=="video"){
 | 
					          for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
 | 
				
			||||||
            toRemove.insert(*it);
 | 
					            if (myMeta.tracks.at(*it).type=="video"){
 | 
				
			||||||
 | 
					              toRemove.insert(*it);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					        if (H.GetVar("audio") == "0"){
 | 
				
			||||||
      if (H.GetVar("audio") == "0"){
 | 
					          for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
 | 
				
			||||||
        for (std::set<unsigned long>::iterator it = selectedTracks.begin(); it != selectedTracks.end(); it++){
 | 
					            if (myMeta.tracks.at(*it).type=="audio"){
 | 
				
			||||||
          if (myMeta.tracks.at(*it).type=="audio"){
 | 
					              toRemove.insert(*it);
 | 
				
			||||||
            toRemove.insert(*it);
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					        //remove those from selectedtracks
 | 
				
			||||||
      //remove those from selectedtracks
 | 
					        for (std::set<unsigned long>::iterator it = toRemove.begin(); it != toRemove.end(); it++){
 | 
				
			||||||
      for (std::set<unsigned long>::iterator it = toRemove.begin(); it != toRemove.end(); it++){
 | 
					          selectedTracks.erase(*it);
 | 
				
			||||||
        selectedTracks.erase(*it);
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      onHTTP();
 | 
					      onHTTP();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -53,11 +53,6 @@ namespace Mist {
 | 
				
			||||||
    Output::onFail();
 | 
					    Output::onFail();
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  /// The HTTP output is always ready to play
 | 
					 | 
				
			||||||
  bool OutHTTP::isReadyForPlay() {
 | 
					 | 
				
			||||||
    return true;
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
  
 | 
					 | 
				
			||||||
  void OutHTTP::init(Util::Config * cfg){
 | 
					  void OutHTTP::init(Util::Config * cfg){
 | 
				
			||||||
    HTTPOutput::init(cfg);
 | 
					    HTTPOutput::init(cfg);
 | 
				
			||||||
    capa.removeMember("deps");
 | 
					    capa.removeMember("deps");
 | 
				
			||||||
| 
						 | 
					@ -65,6 +60,7 @@ namespace Mist {
 | 
				
			||||||
    capa["desc"] = "Generic HTTP handler, required for all other HTTP-based outputs.";
 | 
					    capa["desc"] = "Generic HTTP handler, required for all other HTTP-based outputs.";
 | 
				
			||||||
    capa["provides"] = "HTTP";
 | 
					    capa["provides"] = "HTTP";
 | 
				
			||||||
    capa["protocol"] = "http://";
 | 
					    capa["protocol"] = "http://";
 | 
				
			||||||
 | 
					    capa["codecs"][0u][0u].append("*");
 | 
				
			||||||
    capa["url_match"].append("/crossdomain.xml");
 | 
					    capa["url_match"].append("/crossdomain.xml");
 | 
				
			||||||
    capa["url_match"].append("/clientaccesspolicy.xml");
 | 
					    capa["url_match"].append("/clientaccesspolicy.xml");
 | 
				
			||||||
    capa["url_match"].append("/$.html");
 | 
					    capa["url_match"].append("/$.html");
 | 
				
			||||||
| 
						 | 
					@ -321,12 +317,11 @@ namespace Mist {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      
 | 
					      
 | 
				
			||||||
      std::string trackSources;//this string contains all track sources for MBR smil
 | 
					      std::string trackSources;//this string contains all track sources for MBR smil
 | 
				
			||||||
      DTSC::Scan tracks = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("streams").getMember(streamName).getMember("meta").getMember("tracks");
 | 
					      initialize();
 | 
				
			||||||
      unsigned int track_ctr = tracks.getSize();
 | 
					      if (!myConn){return;}
 | 
				
			||||||
      for (unsigned int i = 0; i < track_ctr; ++i){//for all video tracks
 | 
					      for (std::map<unsigned int, DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
 | 
				
			||||||
        DTSC::Scan trk = tracks.getIndice(i);
 | 
					        if (trit->second.type == "video"){
 | 
				
			||||||
        if (trk.getMember("type").asString() == "video"){
 | 
					          trackSources += "      <video src='"+ streamName + "?track=" + JSON::Value((long long)trit->first).asString() + "' height='" + JSON::Value((long long)trit->second.height).asString() + "' system-bitrate='" + JSON::Value((long long)trit->second.bps).asString() + "' width='" + JSON::Value((long long)trit->second.width).asString() + "' />\n";
 | 
				
			||||||
          trackSources += "      <video src='"+ streamName + "?track=" + trk.getMember("trackid").asString() + "' height='" + trk.getMember("height").asString() + "' system-bitrate='" + trk.getMember("bps").asString() + "' width='" + trk.getMember("width").asString() + "' />\n";
 | 
					 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      configLock.post();
 | 
					      configLock.post();
 | 
				
			||||||
| 
						 | 
					@ -370,59 +365,41 @@ namespace Mist {
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      response = "// Generating info code for stream " + streamName + "\n\nif (!mistvideo){var mistvideo = {};}\n";
 | 
					      response = "// Generating info code for stream " + streamName + "\n\nif (!mistvideo){var mistvideo = {};}\n";
 | 
				
			||||||
      JSON::Value json_resp;
 | 
					      JSON::Value json_resp;
 | 
				
			||||||
 | 
					      initialize();
 | 
				
			||||||
 | 
					      if (!myConn){
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
      IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
 | 
					      IPC::semaphore configLock(SEM_CONF, O_CREAT | O_RDWR, ACCESSPERMS, 1);
 | 
				
			||||||
      static char liveSemName[NAME_BUFFER_SIZE];
 | 
					 | 
				
			||||||
      snprintf(liveSemName, NAME_BUFFER_SIZE, SEM_LIVE, streamName.c_str());
 | 
					 | 
				
			||||||
      IPC::semaphore metaLocker(liveSemName, O_CREAT | O_RDWR, ACCESSPERMS, 1);
 | 
					 | 
				
			||||||
      bool metaLock = false;
 | 
					 | 
				
			||||||
      configLock.wait();
 | 
					      configLock.wait();
 | 
				
			||||||
      IPC::sharedPage serverCfg(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
 | 
					      IPC::sharedPage serverCfg(SHM_CONF, DEFAULT_CONF_PAGE_SIZE);
 | 
				
			||||||
      DTSC::Scan strm = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("streams").getMember(streamName).getMember("meta");
 | 
					 | 
				
			||||||
      IPC::sharedPage streamIndex;
 | 
					 | 
				
			||||||
      if (!strm){
 | 
					 | 
				
			||||||
        configLock.post();
 | 
					 | 
				
			||||||
        //Stream metadata not found - attempt to start it
 | 
					 | 
				
			||||||
        if (Util::startInput(streamName)){
 | 
					 | 
				
			||||||
          char pageId[NAME_BUFFER_SIZE];
 | 
					 | 
				
			||||||
          snprintf(pageId, NAME_BUFFER_SIZE, SHM_STREAM_INDEX, streamName.c_str());
 | 
					 | 
				
			||||||
          streamIndex.init(pageId, DEFAULT_STRM_PAGE_SIZE);
 | 
					 | 
				
			||||||
          if (streamIndex.mapped){
 | 
					 | 
				
			||||||
            metaLock = true;
 | 
					 | 
				
			||||||
            metaLocker.wait();
 | 
					 | 
				
			||||||
            strm = DTSC::Packet(streamIndex.mapped, streamIndex.len, true).getScan();
 | 
					 | 
				
			||||||
          }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        if (!strm){
 | 
					 | 
				
			||||||
          //stream failed to start or isn't configured
 | 
					 | 
				
			||||||
          response += "// Stream isn't configured and/or couldn't be started. Sorry.\n";
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        configLock.wait();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      DTSC::Scan prots = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("config").getMember("protocols");
 | 
					      DTSC::Scan prots = DTSC::Scan(serverCfg.mapped, serverCfg.len).getMember("config").getMember("protocols");
 | 
				
			||||||
      if (strm && prots){
 | 
					      if (prots){
 | 
				
			||||||
        DTSC::Scan trcks = strm.getMember("tracks");
 | 
					        bool hasVideo = false;
 | 
				
			||||||
        unsigned int trcks_ctr = trcks.getSize();
 | 
					        for (std::map<unsigned int, DTSC::Track>::iterator trit = myMeta.tracks.begin(); trit != myMeta.tracks.end(); trit++){
 | 
				
			||||||
        for (unsigned int i = 0; i < trcks_ctr; ++i){
 | 
					          if (trit->second.type == "video"){
 | 
				
			||||||
          if (trcks.getIndice(i).getMember("width").asInt() > json_resp["width"].asInt()){
 | 
					            hasVideo = true;
 | 
				
			||||||
            json_resp["width"] = trcks.getIndice(i).getMember("width").asInt();
 | 
					            if (trit->second.width > json_resp["width"].asInt()){
 | 
				
			||||||
          }
 | 
					              json_resp["width"] = trit->second.width;
 | 
				
			||||||
          if (trcks.getIndice(i).getMember("height").asInt() > json_resp["height"].asInt()){
 | 
					            }
 | 
				
			||||||
            json_resp["height"] = trcks.getIndice(i).getMember("height").asInt();
 | 
					            if (trit->second.height > json_resp["height"].asInt()){
 | 
				
			||||||
 | 
					              json_resp["height"] = trit->second.height;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
          }
 | 
					          }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (json_resp["width"].asInt() < 1 || json_resp["height"].asInt() < 1){
 | 
					        if (json_resp["width"].asInt() < 1 || json_resp["height"].asInt() < 1){
 | 
				
			||||||
          json_resp["width"] = 640ll;
 | 
					          json_resp["width"] = 640ll;
 | 
				
			||||||
          json_resp["height"] = 480ll;
 | 
					          json_resp["height"] = 480ll;
 | 
				
			||||||
 | 
					          if (!hasVideo){json_resp["height"] = 20ll;}
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (strm.getMember("vod")){
 | 
					        if (myMeta.vod){
 | 
				
			||||||
          json_resp["type"] = "vod";
 | 
					          json_resp["type"] = "vod";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        if (strm.getMember("live")){
 | 
					        if (myMeta.live){
 | 
				
			||||||
          json_resp["type"] = "live";
 | 
					          json_resp["type"] = "live";
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // show ALL the meta datas!
 | 
					        // show ALL the meta datas!
 | 
				
			||||||
        json_resp["meta"] = strm.asJSON();
 | 
					        json_resp["meta"] = myMeta.toJSON();
 | 
				
			||||||
        jsonForEach(json_resp["meta"]["tracks"], it) {
 | 
					        jsonForEach(json_resp["meta"]["tracks"], it) {
 | 
				
			||||||
          if (it->isMember("lang")){
 | 
					          if (it->isMember("lang")){
 | 
				
			||||||
            (*it)["language"] = Encodings::ISO639::decode((*it)["lang"].asStringRef());
 | 
					            (*it)["language"] = Encodings::ISO639::decode((*it)["lang"].asStringRef());
 | 
				
			||||||
| 
						 | 
					@ -485,10 +462,6 @@ namespace Mist {
 | 
				
			||||||
      }else{
 | 
					      }else{
 | 
				
			||||||
        json_resp["error"] = "The specified stream is not available on this server.";
 | 
					        json_resp["error"] = "The specified stream is not available on this server.";
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
      if (metaLock){
 | 
					 | 
				
			||||||
        metaLocker.post();
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      
 | 
					 | 
				
			||||||
      configLock.post();
 | 
					      configLock.post();
 | 
				
			||||||
      configLock.close();
 | 
					      configLock.close();
 | 
				
			||||||
      if (rURL.substr(0, 6) != "/json_"){
 | 
					      if (rURL.substr(0, 6) != "/json_"){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -10,7 +10,6 @@ namespace Mist {
 | 
				
			||||||
      static bool listenMode();
 | 
					      static bool listenMode();
 | 
				
			||||||
      virtual void onFail();
 | 
					      virtual void onFail();
 | 
				
			||||||
      void onHTTP();
 | 
					      void onHTTP();
 | 
				
			||||||
      bool isReadyForPlay();
 | 
					 | 
				
			||||||
      void sendIcon();
 | 
					      void sendIcon();
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue