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; }
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; }