static int FlagCommercials(ProgramInfo *program_info, int jobid, const QString &outputfilename, bool useDB, bool fullSpeed) { global_program_info = program_info; int breaksFound = 0; // configure commercial detection method SkipTypes commDetectMethod = (SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); if (cmdline.toBool("commmethod")) { // pull commercial detection method from command line QString commmethod = cmdline.toString("commmethod"); // assume definition as integer value bool ok = true; commDetectMethod = (SkipTypes) commmethod.toInt(&ok); if (!ok) { // not an integer, attempt comma separated list commDetectMethod = COMM_DETECT_UNINIT; QMap<QString, SkipTypes>::const_iterator sit; QStringList list = commmethod.split(",", QString::SkipEmptyParts); QStringList::const_iterator it = list.begin(); for (; it != list.end(); ++it) { QString val = (*it).toLower(); if (val == "off") { commDetectMethod = COMM_DETECT_OFF; break; } if (!skipTypes->contains(val)) { cerr << "Failed to decode --method option '" << val.toLatin1().constData() << "'" << endl; return GENERIC_EXIT_INVALID_CMDLINE; } if (commDetectMethod == COMM_DETECT_UNINIT) { commDetectMethod = (SkipTypes) skipTypes->value(val); } else { commDetectMethod = (SkipTypes) ((int)commDetectMethod | (int)skipTypes->value(val)); } } } if (commDetectMethod == COMM_DETECT_UNINIT) return GENERIC_EXIT_INVALID_CMDLINE; } else if (useDB) { // if not manually specified, and we have a database to access // pull the commflag type from the channel MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT commmethod FROM channel " "WHERE chanid = :CHANID;"); query.bindValue(":CHANID", program_info->GetChanID()); if (!query.exec()) { // if the query fails, return with an error commDetectMethod = COMM_DETECT_UNINIT; MythDB::DBError("FlagCommercials", query); } else if (query.next()) { commDetectMethod = (enum SkipTypes)query.value(0).toInt(); if (commDetectMethod == COMM_DETECT_COMMFREE) { // if the channel is commercial free, drop to the default instead commDetectMethod = (enum SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); LOG(VB_COMMFLAG, LOG_INFO, QString("Chanid %1 is marked as being Commercial Free, " "we will use the default commercial detection " "method").arg(program_info->GetChanID())); } else if (commDetectMethod == COMM_DETECT_UNINIT) // no value set, so use the database default commDetectMethod = (enum SkipTypes)gCoreContext->GetNumSetting( "CommercialSkipMethod", COMM_DETECT_ALL); LOG(VB_COMMFLAG, LOG_INFO, QString("Using method: %1 from channel %2") .arg(commDetectMethod).arg(program_info->GetChanID())); } } else if (!useDB) { // default to a cheaper method for debugging purposes commDetectMethod = COMM_DETECT_BLANK; } // if selection has failed, or intentionally disabled, drop out if (commDetectMethod == COMM_DETECT_UNINIT) return GENERIC_EXIT_NOT_OK; else if (commDetectMethod == COMM_DETECT_OFF) return GENERIC_EXIT_OK; frm_dir_map_t blanks; recorder = NULL; /* * is there a purpose to this not fulfilled by --getskiplist? if (onlyDumpDBCommercialBreakList) { frm_dir_map_t commBreakList; program_info->QueryCommBreakList(commBreakList); print_comm_flag_output(program_info, commBreakList, 0, NULL, outputfilename); global_program_info = NULL; return GENERIC_EXIT_OK; } */ if (!DoesFileExist(program_info)) { LOG(VB_GENERAL, LOG_ERR, "Unable to find file in defined storage paths."); return GENERIC_EXIT_PERMISSIONS_ERROR; } QString filename = get_filename(program_info); RingBuffer *tmprbuf = RingBuffer::Create(filename, false); if (!tmprbuf) { LOG(VB_GENERAL, LOG_ERR, QString("Unable to create RingBuffer for %1").arg(filename)); global_program_info = NULL; return GENERIC_EXIT_PERMISSIONS_ERROR; } if (useDB) { if (!MSqlQuery::testDBConnection()) { LOG(VB_GENERAL, LOG_ERR, "Unable to open commflag DB connection"); delete tmprbuf; global_program_info = NULL; return GENERIC_EXIT_DB_ERROR; } } PlayerFlags flags = (PlayerFlags)(kAudioMuted | kVideoIsNull | kDecodeLowRes | kDecodeSingleThreaded | kDecodeNoLoopFilter | kNoITV); /* blank detector needs to be only sample center for this optimization. */ if ((COMM_DETECT_BLANKS == commDetectMethod) || (COMM_DETECT_2_BLANK == commDetectMethod)) { flags = (PlayerFlags) (flags | kDecodeFewBlocks); } MythCommFlagPlayer *cfp = new MythCommFlagPlayer(flags); PlayerContext *ctx = new PlayerContext(kFlaggerInUseID); ctx->SetPlayingInfo(program_info); ctx->SetRingBuffer(tmprbuf); ctx->SetPlayer(cfp); cfp->SetPlayerInfo(NULL, NULL, ctx); if (useDB) { if (program_info->GetRecordingEndTime() > MythDate::current()) { gCoreContext->ConnectToMasterServer(); recorder = RemoteGetExistingRecorder(program_info); if (recorder && (recorder->GetRecorderNumber() != -1)) { recorderNum = recorder->GetRecorderNumber(); watchingRecording = true; ctx->SetRecorder(recorder); LOG(VB_COMMFLAG, LOG_INFO, QString("mythcommflag will flag recording " "currently in progress on cardid %1") .arg(recorderNum)); } else { recorderNum = -1; watchingRecording = false; LOG(VB_GENERAL, LOG_ERR, "Unable to find active recorder for this " "recording, realtime flagging will not be enabled."); } cfp->SetWatchingRecording(watchingRecording); } } // TODO: Add back insertion of job if not in jobqueue breaksFound = DoFlagCommercials( program_info, progress, fullSpeed, jobid, cfp, commDetectMethod, outputfilename, useDB); if (progress) cerr << breaksFound << "\n"; LOG(VB_GENERAL, LOG_NOTICE, QString("Finished, %1 break(s) found.") .arg(breaksFound)); delete ctx; global_program_info = NULL; return breaksFound; }
int main(int argc, char *argv[]) { int result = GENERIC_EXIT_OK; // QString allStart = "19700101000000"; // QString allEnd = MythDate::current().toString("yyyyMMddhhmmss"); int jobType = JOB_NONE; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } QCoreApplication a(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHCOMMFLAG); int retval = cmdline.ConfigureLogging("general", !cmdline.toBool("noprogress")); if (retval != GENERIC_EXIT_OK) return retval; CleanupGuard callCleanup(cleanup); #ifndef _WIN32 QList<int> signallist; signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE << SIGILL; #if ! CONFIG_DARWIN signallist << SIGRTMIN; #endif SignalHandler::Init(signallist); signal(SIGHUP, SIG_IGN); #endif gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init( false, /*use gui*/ false, /*prompt for backend*/ false, /*bypass auto discovery*/ cmdline.toBool("skipdb"))) /*ignoreDB*/ { LOG(VB_GENERAL, LOG_EMERG, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } cmdline.ApplySettingsOverride(); MythTranslation::load("mythfrontend"); if (cmdline.toBool("outputmethod")) { QString om = cmdline.toString("outputmethod"); if (outputTypes->contains(om)) outputMethod = outputTypes->value(om); } if (cmdline.toBool("chanid") && cmdline.toBool("starttime")) { // operate on a recording in the database uint chanid = cmdline.toUInt("chanid"); QDateTime starttime = cmdline.toDateTime("starttime"); if (cmdline.toBool("clearskiplist")) return ClearSkipList(chanid, starttime); if (cmdline.toBool("gencutlist")) return CopySkipListToCutList(chanid, starttime); if (cmdline.toBool("clearcutlist")) return SetCutList(chanid, starttime, ""); if (cmdline.toBool("setcutlist")) return SetCutList(chanid, starttime, cmdline.toString("setcutlist")); if (cmdline.toBool("getcutlist")) return GetMarkupList("cutlist", chanid, starttime); if (cmdline.toBool("getskiplist")) return GetMarkupList("commflag", chanid, starttime); // TODO: check for matching jobid // create temporary id to operate off of if not if (cmdline.toBool("queue")) QueueCommFlagJob(chanid, starttime, cmdline.toBool("rebuild")); else if (cmdline.toBool("rebuild")) result = RebuildSeekTable(chanid, starttime, -1); else result = FlagCommercials(chanid, starttime, -1, cmdline.toString("outputfile"), true); } else if (cmdline.toBool("jobid")) { jobID = cmdline.toInt("jobid"); uint chanid; QDateTime starttime; if (!JobQueue::GetJobInfoFromID(jobID, jobType, chanid, starttime)) { cerr << "mythcommflag: ERROR: Unable to find DB info for " << "JobQueue ID# " << jobID << endl; return GENERIC_EXIT_NO_RECORDING_DATA; } force = true; int jobQueueCPU = gCoreContext->GetNumSetting("JobQueueCPU", 0); if (jobQueueCPU < 2) { myth_nice(17); myth_ioprio((0 == jobQueueCPU) ? 8 : 7); } progress = false; int ret = 0; if (JobQueue::GetJobFlags(jobID) & JOB_REBUILD) RebuildSeekTable(chanid, starttime, jobID); else ret = FlagCommercials(chanid, starttime, jobID, "", jobQueueCPU != 0); if (ret > GENERIC_EXIT_NOT_OK) JobQueue::ChangeJobStatus(jobID, JOB_ERRORED, QCoreApplication::translate("(mythcommflag)", "Failed with exit status %1", "Job status").arg(ret)); else JobQueue::ChangeJobStatus(jobID, JOB_FINISHED, QCoreApplication::translate("(mythcommflag)", "%n commercial break(s)", "Job status", QCoreApplication::UnicodeUTF8, ret)); } else if (cmdline.toBool("video")) { // build skiplist for video file return RebuildSeekTable(cmdline.toString("video"), -1); } else if (cmdline.toBool("file")) { if (cmdline.toBool("skipdb")) { if (cmdline.toBool("rebuild")) { cerr << "The --rebuild parameter builds the seektable for " "internal MythTV use only. It cannot be used in " "combination with --skipdb." << endl; return GENERIC_EXIT_INVALID_CMDLINE; } if (!cmdline.toBool("outputfile")) cmdline.SetValue("outputfile", "-"); // perform commercial flagging on file outside the database FlagCommercials(cmdline.toString("file"), -1, cmdline.toString("outputfile"), !cmdline.toBool("skipdb"), true); } else { ProgramInfo pginfo(cmdline.toString("file")); // pass chanid and starttime // inefficient, but it lets the other function // handle sanity checking if (cmdline.toBool("rebuild")) result = RebuildSeekTable(pginfo.GetChanID(), pginfo.GetRecordingStartTime(), -1); else result = FlagCommercials(pginfo.GetChanID(), pginfo.GetRecordingStartTime(), -1, cmdline.toString("outputfile"), true); } } else if (cmdline.toBool("queue")) { // run flagging for all recordings with no skiplist MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT r.chanid, r.starttime, c.commmethod " "FROM recorded AS r " "LEFT JOIN channel AS c ON r.chanid=c.chanid " // "WHERE startime >= :STARTTIME AND endtime <= :ENDTIME " "ORDER BY starttime;"); //query.bindValue(":STARTTIME", allStart); //query.bindValue(":ENDTIME", allEnd); if (query.exec() && query.isActive() && query.size() > 0) { QDateTime starttime; uint chanid; while (query.next()) { starttime = MythDate::fromString(query.value(1).toString()); chanid = query.value(0).toUInt(); if (!cmdline.toBool("force") && !cmdline.toBool("rebuild")) { // recording is already flagged if (IsMarked(chanid, starttime)) continue; // channel is marked as commercial free if (query.value(2).toInt() == COMM_DETECT_COMMFREE) continue; // recording rule did not enable commflagging #if 0 RecordingInfo recinfo(chanid, starttime); if (!(recinfo.GetAutoRunJobs() & JOB_COMMFLAG)) continue; #endif } QueueCommFlagJob(chanid, starttime, cmdline.toBool("rebuild")); } } } else { LOG(VB_GENERAL, LOG_ERR, "No valid combination of command inputs received."); cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } return result; }
int main(int argc, char *argv[]) { int result = GENERIC_EXIT_OK; // QString allStart = "19700101000000"; // QString allEnd = MythDate::current().toString("yyyyMMddhhmmss"); int jobType = JOB_NONE; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } QCoreApplication a(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHCOMMFLAG); int retval = cmdline.ConfigureLogging("general", !cmdline.toBool("noprogress")); if (retval != GENERIC_EXIT_OK) return retval; CleanupGuard callCleanup(cleanup); #ifndef _WIN32 QList<int> signallist; signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE << SIGILL; #if ! CONFIG_DARWIN signallist << SIGRTMIN; #endif SignalHandler::Init(signallist); signal(SIGHUP, SIG_IGN); #endif gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init( false, /*use gui*/ false, /*prompt for backend*/ false, /*bypass auto discovery*/ cmdline.toBool("skipdb"))) /*ignoreDB*/ { LOG(VB_GENERAL, LOG_EMERG, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } cmdline.ApplySettingsOverride(); MythTranslation::load("mythfrontend"); if (cmdline.toBool("outputmethod")) { QString om = cmdline.toString("outputmethod"); if (outputTypes->contains(om)) outputMethod = outputTypes->value(om); } if (cmdline.toBool("chanid") && cmdline.toBool("starttime")) { // operate on a recording in the database uint chanid = cmdline.toUInt("chanid"); QDateTime starttime = cmdline.toDateTime("starttime"); if (cmdline.toBool("clearskiplist")) return ClearSkipList(chanid, starttime); if (cmdline.toBool("gencutlist")) return CopySkipListToCutList(chanid, starttime); if (cmdline.toBool("clearcutlist")) return SetCutList(chanid, starttime, ""); if (cmdline.toBool("setcutlist")) return SetCutList(chanid, starttime, cmdline.toString("setcutlist")); if (cmdline.toBool("getcutlist")) return GetMarkupList("cutlist", chanid, starttime); if (cmdline.toBool("getskiplist")) return GetMarkupList("commflag", chanid, starttime); // TODO: check for matching jobid // create temporary id to operate off of if not if (cmdline.toBool("queue")) QueueCommFlagJob(chanid, starttime, cmdline.toBool("rebuild")); else if (cmdline.toBool("rebuild")) result = RebuildSeekTable(chanid, starttime, -1); else result = FlagCommercials(chanid, starttime, -1, cmdline.toString("outputfile"), true); } else if (cmdline.toBool("jobid")) { jobID = cmdline.toInt("jobid"); uint chanid; QDateTime starttime; if (!JobQueue::GetJobInfoFromID(jobID, jobType, chanid, starttime)) { cerr << "mythcommflag: ERROR: Unable to find DB info for " << "JobQueue ID# " << jobID << endl; return GENERIC_EXIT_NO_RECORDING_DATA; } force = true; int jobQueueCPU = gCoreContext->GetNumSetting("JobQueueCPU", 0); if (jobQueueCPU < 2) { myth_nice(17); myth_ioprio((0 == jobQueueCPU) ? 8 : 7); } progress = false; int ret = 0; if (JobQueue::GetJobFlags(jobID) & JOB_REBUILD) RebuildSeekTable(chanid, starttime, jobID); else ret = FlagCommercials(chanid, starttime, jobID, "", jobQueueCPU != 0); if (ret > GENERIC_EXIT_NOT_OK) JobQueue::ChangeJobStatus(jobID, JOB_ERRORED, QCoreApplication::translate("(mythcommflag)", "Failed with exit status %1", "Job status").arg(ret)); else JobQueue::ChangeJobStatus(jobID, JOB_FINISHED, #if QT_VERSION < 0x050000 QCoreApplication::translate("(mythcommflag)", "%n commercial break(s)", "Job status", QCoreApplication::UnicodeUTF8, ret)); #else QCoreApplication::translate("(mythcommflag)", "%n commercial break(s)", "Job status", ret)); #endif }
int main(int argc, char *argv[]) { bool isVideo = false; int result = GENERIC_EXIT_OK; QString filename; QString outputfilename = QString::null; QDateTime starttime; QString allStart = "19700101000000"; QString allEnd = QDateTime::currentDateTime().toString("yyyyMMddhhmmss"); int jobType = JOB_NONE; QDir fullfile; QString newCutList = QString::null; if (!cmdline.Parse(argc, argv)) { cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } if (cmdline.toBool("showhelp")) { cmdline.PrintHelp(); return GENERIC_EXIT_OK; } if (cmdline.toBool("showversion")) { cmdline.PrintVersion(); return GENERIC_EXIT_OK; } QCoreApplication a(argc, argv); QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHCOMMFLAG); int retval; if ((retval = cmdline.ConfigureLogging( "important general", !cmdline.toBool("noprogress"))) != GENERIC_EXIT_OK) return retval; CleanupGuard callCleanup(cleanup); gContext = new MythContext(MYTH_BINARY_VERSION); if (!gContext->Init( false, /*use gui*/ false, /*prompt for backend*/ false, /*bypass auto discovery*/ cmdline.toBool("skipdb"))) /*ignoreDB*/ { LOG(VB_GENERAL, LOG_EMERG, "Failed to init MythContext, exiting."); return GENERIC_EXIT_NO_MYTHCONTEXT; } cmdline.ApplySettingsOverride(); MythTranslation::load("mythfrontend"); if (cmdline.toBool("chanid") && cmdline.toBool("starttime")) { // operate on a recording in the database uint chanid = cmdline.toUInt("chanid"); QDateTime starttime = cmdline.toDateTime("starttime"); if (cmdline.toBool("clearskiplist")) return ClearSkipList(chanid, starttime); if (cmdline.toBool("gencutlist")) return CopySkipListToCutList(chanid, starttime); if (cmdline.toBool("clearcutlist")) return SetCutList(chanid, starttime, ""); if (cmdline.toBool("setcutlist")) return SetCutList(chanid, starttime, cmdline.toString("setcutlist")); if (cmdline.toBool("getcutlist")) return GetMarkupList("cutlist", chanid, starttime); if (cmdline.toBool("getskiplist")) return GetMarkupList("commflag", chanid, starttime); // TODO: check for matching jobid // create temporary id to operate off of if not if (cmdline.toBool("queue")) QueueCommFlagJob(chanid, starttime, cmdline.toBool("rebuild")); else if (cmdline.toBool("rebuild")) result = RebuildSeekTable(chanid, starttime, -1); else result = FlagCommercials(chanid, starttime, -1, ""); } else if (cmdline.toBool("jobid")) { jobID = cmdline.toInt("jobid"); uint chanid; QDateTime starttime; if (!JobQueue::GetJobInfoFromID(jobID, jobType, chanid, starttime)) { cerr << "mythcommflag: ERROR: Unable to find DB info for " << "JobQueue ID# " << jobID << endl; return GENERIC_EXIT_NO_RECORDING_DATA; } inJobQueue = true; force = true; int jobQueueCPU = gCoreContext->GetNumSetting("JobQueueCPU", 0); if (jobQueueCPU < 2) { myth_nice(17); myth_ioprio((0 == jobQueueCPU) ? 8 : 7); } fullSpeed = jobQueueCPU != 0; progress = false; isVideo = false; int ret = 0; if (JobQueue::GetJobFlags(jobID) && JOB_REBUILD) RebuildSeekTable(chanid, starttime, jobID); else ret = FlagCommercials(chanid, starttime, jobID, ""); if (ret > GENERIC_EXIT_NOT_OK) JobQueue::ChangeJobStatus(jobID, JOB_ERRORED, QString("Failed with exit status %1").arg(ret)); else JobQueue::ChangeJobStatus(jobID, JOB_FINISHED, QString("%1 commercial breaks").arg(ret)); } else if (cmdline.toBool("video")) { // build skiplist for video file return RebuildSeekTable(cmdline.toString(filename), -1); } else if (cmdline.toBool("file")) { // TODO: add back handling of recording defined by the basename // perform commercial flagging on file outside the database FlagCommercials(cmdline.toString("file"), -1, cmdline.toString("outputfile"), !cmdline.toBool("skipdb")); } else if (cmdline.toBool("queue")) { // run flagging for all recordings with no skiplist MSqlQuery query(MSqlQuery::InitCon()); query.prepare("SELECT r.chanid, r.starttime, c.commmethod " "FROM recorded AS r " "LEFT JOIN channel AS c ON r.chanid=c.chanid " // "WHERE startime >= :STARTTIME AND endtime <= :ENDTIME " "ORDER BY starttime;"); //query.bindValue(":STARTTIME", allStart); //query.bindValue(":ENDTIME", allEnd); if (query.exec() && query.isActive() && query.size() > 0) { QDateTime starttime; uint chanid; while (query.next()) { starttime = QDateTime::fromString(query.value(1).toString(), Qt::ISODate); chanid = query.value(0).toUInt(); if (!cmdline.toBool("force") && !cmdline.toBool("rebuild")) { // recording is already flagged if (IsMarked(chanid, starttime)) continue; // channel is marked as commercial free if (query.value(2).toInt() == COMM_DETECT_COMMFREE) continue; // recording rule did not enable commflagging // RecordingInfo recinfo(chanid, starttime); // if (!(recinfo.GetAutoRunJobs() & JOB_COMMFLAG)) // continue; } QueueCommFlagJob(chanid, starttime, cmdline.toBool("rebuild")); } } } else { VERBOSE(VB_IMPORTANT, "No valid combination of command inputs received."); cmdline.PrintHelp(); return GENERIC_EXIT_INVALID_CMDLINE; } return result; }