void CheckAllStreams(JSON::Value & data){
   long long int currTime = Util::epoch();
   for (JSON::ObjIter jit = data.ObjBegin(); jit != data.ObjEnd(); jit++){
     if ( !Util::Procs::isActive(jit->first)){
       startStream(jit->first, jit->second);
     }
     if (currTime - lastBuffer[jit->first] > 5){
       if (jit->second.isMember("error") && jit->second["error"].asString() != ""){
         jit->second["online"] = jit->second["error"];
       }else{
         jit->second["online"] = 0;
       }
     }else{
       jit->second["online"] = 1;
     }
   }
   static JSON::Value strlist;
   bool changed = false;
   if (strlist["config"] != Storage["config"]){
     strlist["config"] = Storage["config"];
     changed = true;
   }
   if (strlist["streams"] != Storage["streams"]){
     strlist["streams"] = Storage["streams"];
     changed = true;
   }
   if (changed){
     WriteFile("/tmp/mist/streamlist", strlist.toString());
   }
 }
///\brief Checks all streams, restoring if needed.
///\param data The stream configuration for the server.
void CheckAllStreams(JSON::Value & data) {
    long long int currTime = Util::epoch();
    for (JSON::ObjIter jit = data.ObjBegin(); jit != data.ObjEnd(); jit++) {
        if ( !Util::Procs::isActive(jit->first)) {
            startStream(jit->first, jit->second);
        }
        if (currTime - lastBuffer[jit->first] > 5) {
            if (jit->second.isMember("source") && jit->second["source"].asString().substr(0, 1) == "/" && jit->second.isMember("error")
                    && jit->second["error"].asString() == "Available") {
                jit->second["online"] = 2;
            } else {
                if (jit->second.isMember("error") && jit->second["error"].asString() == "Available") {
                    jit->second.removeMember("error");
                }
                jit->second["online"] = 0;
            }
        } else {
            // assume all is fine
            jit->second.removeMember("error");
            jit->second["online"] = 1;
            // check if source is valid
            if (jit->second.isMember("live") && !jit->second.isMember("meta") || !jit->second["meta"]) {
                jit->second["online"] = 0;
                jit->second["error"] = "No (valid) source connected";
            } else {
                // for live streams, keep track of activity
                if (jit->second["meta"].isMember("live")) {
                    if (jit->second["meta"]["lastms"] != jit->second["lastms"]) {
                        jit->second["lastms"] = jit->second["meta"]["lastms"];
                        jit->second["last_active"] = currTime;
                    }
                    // mark stream as offline if no activity for 5 seconds
                    if (jit->second.isMember("last_active") && jit->second["last_active"].asInt() < currTime - 5) {
                        jit->second["online"] = 0;
                        jit->second["error"] = "No (valid) source connected";
                    }
                }
            }
        }
    }
    static JSON::Value strlist;
    bool changed = false;
    if (strlist["config"] != Storage["config"]) {
        strlist["config"] = Storage["config"];
        changed = true;
    }
    if (strlist["streams"] != Storage["streams"]) {
        strlist["streams"] = Storage["streams"];
        changed = true;
    }
    if (changed) {
        WriteFile("/tmp/mist/streamlist", strlist.toString());
    }
}
///\brief Parse a given stream configuration.
///\param in The requested configuration.
///\param out The new configuration after parsing.
void CheckStreams(JSON::Value & in, JSON::Value & out) {
    bool changed = false;

    //check for new streams and updates
    for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++) {
        if (out.isMember(jit->first)) {
            if ( !streamsEqual(jit->second, out[jit->first])) {
                Log("STRM", std::string("Updated stream ") + jit->first);
                Util::Procs::Stop(jit->first);
                startStream(jit->first, jit->second);
            }
        } else {
            Log("STRM", std::string("New stream ") + jit->first);
            startStream(jit->first, jit->second);
        }
    }

    //check for deleted streams
    for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++) {
        if ( !in.isMember(jit->first)) {
            Log("STRM", std::string("Deleted stream ") + jit->first);
            Util::Procs::Stop(jit->first);
        }
    }

    //update old-style configurations to new-style
    for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++) {
        if (jit->second.isMember("channel")) {
            if ( !jit->second.isMember("source")) {
                jit->second["source"] = jit->second["channel"]["URL"];
            }
            jit->second.removeMember("channel");
        }
        if (jit->second.isMember("preset")) {
            jit->second.removeMember("preset");
        }
    }

    out = in;
}
 void CheckStreams(JSON::Value & in, JSON::Value & out){
   bool changed = false;
   for (JSON::ObjIter jit = in.ObjBegin(); jit != in.ObjEnd(); jit++){
     if (out.isMember(jit->first)){
       if ( !streamsEqual(jit->second, out[jit->first])){
         Log("STRM", std::string("Updated stream ") + jit->first);
         Util::Procs::Stop(jit->first);
         startStream(jit->first, jit->second);
       }
     }else{
       Log("STRM", std::string("New stream ") + jit->first);
       startStream(jit->first, jit->second);
     }
   }
   for (JSON::ObjIter jit = out.ObjBegin(); jit != out.ObjEnd(); jit++){
     if ( !in.isMember(jit->first)){
       Log("STRM", std::string("Deleted stream ") + jit->first);
       Util::Procs::Stop(jit->first);
     }
   }
   out = in;
 }
Example #5
0
 int getInfo(int argc, char* argv[]) {
   if (argc < 2){
     fprintf( stderr, "Usage: %s <filename>\n", argv[0] );
     return 1;
   }
   DTSC::File F(argv[1]);
   JSON::Value fileSpecs = F.getMeta().toJSON();
   if( !fileSpecs ) {
     char ** cmd = (char**)malloc(3*sizeof(char*));
     cmd[0] = (char*)"ffprobe";
     cmd[1] = argv[1];
     cmd[2] = NULL;
     int outFD = -1;
     Util::Procs::StartPiped("FFProbe", cmd, 0, 0, &outFD);
     while( Util::Procs::isActive("FFProbe")){ Util::sleep(100); }
     FILE * outFile = fdopen( outFD, "r" );
     char * fileBuf = 0;
     size_t fileBufLen = 0;
     while ( !(feof(outFile) || ferror(outFile)) && (getline(&fileBuf, &fileBufLen, outFile) != -1)){
       std::string line = fileBuf;
       if (line.find("Input") != std::string::npos){
         std::string tmp = line.substr(line.find(", ") + 2);
         fileSpecs["format"] = tmp.substr(0, tmp.find(","));
       }
       if (line.find("Duration") != std::string::npos){
         std::string tmp = line.substr(line.find(": ", line.find("Duration")) + 2);
         tmp = tmp.substr(0, tmp.find(","));
         int length = (((atoi(tmp.substr(0,2).c_str()) * 60) + atoi(tmp.substr(3,2).c_str())) * 60) + atoi(tmp.substr(6,2).c_str());
         fileSpecs["length"] = length;
         length *= 100;
         length += atoi(tmp.substr(9,2).c_str());
         fileSpecs["lastms"] = length * 10;
       }
       if (line.find("bitrate") != std::string::npos ){
         std::string tmp = line.substr(line.find(": ", line.find("bitrate")) + 2);
         fileSpecs["bps"] = atoi(tmp.substr(0, tmp.find(" ")).c_str()) * 128;
       }
       if (line.find("Stream") != std::string::npos ){
         std::string tmp = line.substr(line.find(" ", line.find("Stream")) + 1);
         int strmIdx = fileSpecs["streams"].size();
         int curPos = 0;
         curPos = tmp.find(": ", curPos) + 2;
         fileSpecs["streams"][strmIdx]["type"] = tmp.substr(curPos, tmp.find(":", curPos) - curPos);
         curPos = tmp.find(":", curPos) + 2;
         fileSpecs["streams"][strmIdx]["codec"] = tmp.substr(curPos, tmp.find_first_of(", ", curPos) - curPos);
         curPos = tmp.find(",", curPos) + 2;
         if (fileSpecs["streams"][strmIdx]["type"] == "Video"){
           fileSpecs["streams"][strmIdx]["encoding"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos);
           curPos = tmp.find(",", curPos) + 2;
           fileSpecs["streams"][strmIdx]["width"] = atoi(tmp.substr(curPos, tmp.find("x", curPos) - curPos).c_str());
           curPos = tmp.find("x", curPos) + 1;
           fileSpecs["streams"][strmIdx]["height"] = atoi(tmp.substr(curPos, tmp.find(",", curPos) - curPos).c_str());
           curPos = tmp.find(",", curPos) + 2;
           fileSpecs["streams"][strmIdx]["bps"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 128;
           curPos = tmp.find(",", curPos) + 2;
           fileSpecs["streams"][strmIdx]["fpks"] = (int)(atof(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 1000);
           fileSpecs["streams"][strmIdx].removeMember( "type" );
           fileSpecs["video"] = fileSpecs["streams"][strmIdx];
         }else if (fileSpecs["streams"][strmIdx]["type"] == "Audio"){
           fileSpecs["streams"][strmIdx]["samplerate"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str());
           curPos = tmp.find(",", curPos) + 2;
           if (tmp.substr(curPos, tmp.find(",", curPos) - curPos) == "stereo"){
             fileSpecs["streams"][strmIdx]["channels"] = 2;
           }else if (tmp.substr(curPos, tmp.find(",", curPos) - curPos) == "mono"){
             fileSpecs["streams"][strmIdx]["channels"] = 1;
           }else{
             fileSpecs["streams"][strmIdx]["channels"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos);
           }
           curPos = tmp.find(",", curPos) + 2;
           fileSpecs["streams"][strmIdx]["samplewidth"] = tmp.substr(curPos, tmp.find(",", curPos) - curPos);
           curPos = tmp.find(",", curPos) + 2;
           fileSpecs["streams"][strmIdx]["bps"] = atoi(tmp.substr(curPos, tmp.find(" ", curPos) - curPos).c_str()) * 128;
           fileSpecs["streams"][strmIdx].removeMember( "type" );
           fileSpecs["audio"] = fileSpecs["streams"][strmIdx];
         }
       }
     }
     fclose( outFile );
     fileSpecs.removeMember( "streams" );
   } else {
     fileSpecs["format"] = "dtsc";
     if (DTSC::isFixed(fileSpecs)){
       fileSpecs["is_fixed"] = 1ll;
     }
     JSON::Value tracks = fileSpecs["tracks"];
     for(JSON::ObjIter trackIt = tracks.ObjBegin(); trackIt != tracks.ObjEnd(); trackIt++){
       fileSpecs["tracks"][trackIt->first].removeMember("fragments");
       fileSpecs["tracks"][trackIt->first].removeMember("keys");
       fileSpecs["tracks"][trackIt->first].removeMember("parts");
     }
   }
   printf( "%s", fileSpecs.toString().c_str() );
   return 0;
 }