Go to the documentation of this file.
2 #if defined ANDROID && __ANDROID_API__ < 24
24 #include <QCoreApplication>
58 #define LOC QString("MythCommFlag: ")
59 #define LOC_WARN QString("MythCommFlag, Warning: ")
60 #define LOC_ERR QString("MythCommFlag, Error: ")
92 auto *
tmp =
new QMap<QString,SkipType>;
123 auto *
tmp =
new QMap<QString,OutputMethod>;
146 QString
tmp = QString(
147 "Unable to find program info for chanid %1 @ %2")
148 .arg(chanid).arg(startstring);
149 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
156 QString
tmp = QString(
"Job have been queued for chanid %1 @ %2")
157 .arg(chanid).arg(startstring);
158 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
164 rebuild ?
JOB_REBUILD : 0, JOB_QUEUED, QDateTime());
170 QString
tmp = QString(
"Job Queued for chanid %1 @ %2")
171 .arg(chanid).arg(startstring);
172 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
179 QString
tmp = QString(
"Error queueing job for chanid %1 @ %2")
180 .arg(chanid).arg(startstring);
181 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
189 frm_dir_map_t::const_iterator it;
196 LOG(VB_GENERAL, LOG_ERR,
197 QString(
"No program data exists for channel %1 at %2")
198 .
arg(chanid).
arg(startstring));
203 for (it = cutlist.cbegin(); it != cutlist.cend(); ++it)
222 LOG(VB_GENERAL, LOG_ERR,
223 QString(
"No program data exists for channel %1 at %2")
224 .
arg(chanid).
arg(startstring));
231 LOG(VB_GENERAL, LOG_NOTICE,
"Commercial skip list cleared");
236 static int SetCutList(
uint chanid,
const QDateTime& starttime, QString newCutList)
240 newCutList.replace(QRegExp(
" "),
"");
242 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
243 QStringList tokens = newCutList.split(
",", QString::SkipEmptyParts);
245 QStringList tokens = newCutList.split(
",", Qt::SkipEmptyParts);
248 for (
int i = 0; i < tokens.size(); i++)
250 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
251 QStringList cutpair = tokens[i].split(
"-", QString::SkipEmptyParts);
253 QStringList cutpair = tokens[i].split(
"-", Qt::SkipEmptyParts);
264 LOG(VB_GENERAL, LOG_ERR,
265 QString(
"No program data exists for channel %1 at %2")
266 .
arg(chanid).
arg(startstring));
272 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Cutlist set to: %1").
arg(newCutList));
280 frm_dir_map_t::const_iterator it;
288 LOG(VB_GENERAL, LOG_ERR,
289 QString(
"No program data exists for channel %1 at %2")
290 .
arg(chanid).
arg(startstring));
294 if (list ==
"cutlist")
299 uint64_t lastStart = 0;
300 for (it = cutlist.cbegin(); it != cutlist.cend(); ++it)
305 if (!result.isEmpty())
307 lastStart = it.key();
308 result += QString(
"%1-").arg(lastStart);
312 if (result.isEmpty())
314 result += QString(
"%1").arg(it.key());
318 if (result.endsWith(
'-'))
321 if (lastFrame > lastStart)
322 result += QString(
"%1").arg(lastFrame);
325 if (list ==
"cutlist")
326 std::cout << QString(
"Cutlist: %1\n").arg(result).toLocal8Bit().constData();
329 std::cout << QString(
"Commercial Skip List: %1\n")
330 .arg(result).toLocal8Bit().constData();
340 output <<
"----------------------------" << std::endl;
342 if (commercialBreakList.empty())
345 output <<
"No breaks" << std::endl;
349 frm_dir_map_t::const_iterator it = commercialBreakList.begin();
350 for (; it != commercialBreakList.end(); ++it)
352 output <<
"framenum: " << it.key() <<
"\tmarktype: " << *it
358 output <<
"----------------------------" << std::endl;
364 uint64_t frame_count,
366 const QString &output_filename)
368 if (output_filename.isEmpty())
371 std::ostream *out = &std::cout;
372 if (output_filename !=
"-")
374 QByteArray
tmp = output_filename.toLocal8Bit();
375 out =
new std::fstream(
tmp.constData(), std::ios::app | std::ios::out );
383 tmp = QString(
"commercialBreakListFor: %1 on %2 @ %3")
390 tmp = QString(
"commercialBreakListFor: %1")
394 const QByteArray tmp2 =
tmp.toLocal8Bit();
395 *out << tmp2.constData() << std::endl;
398 *out <<
"totalframecount: " << frame_count << std::endl;
406 if (out != &std::cout)
414 qApp->processEvents();
432 QCoreApplication::translate(
"(mythcommflag)",
433 "Paused",
"Job status"));
440 QCoreApplication::translate(
"(mythcommflag)",
441 "Running",
"Job status"));
463 QString message =
"COMMFLAG_UPDATE ";
466 for (
auto it = newCommercialMap.begin();
467 it != newCommercialMap.end(); ++it)
469 if (it != newCommercialMap.begin())
473 message += QString(
"%1:%2").arg(it.key())
477 LOG(VB_COMMFLAG, LOG_INFO,
478 QString(
"mythcommflag sending update: %1").
arg(message));
491 QString message = me->
Message();
493 message = message.simplified();
494 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
495 QStringList tokens = message.split(
" ", QString::SkipEmptyParts);
497 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
500 LOG(VB_COMMFLAG, LOG_INFO,
501 QString(
"mythcommflag: Received Event: '%1'") .
arg(message));
504 (tokens[0] ==
"DONE_RECORDING"))
506 int cardnum = tokens[1].toInt();
507 int filelen = tokens[2].toInt();
509 message = QString(
"mythcommflag: Received a "
510 "DONE_RECORDING event for card %1. ")
517 message +=
"Informed CommDetector that recording has finished.";
518 LOG(VB_COMMFLAG, LOG_INFO, message);
522 if ((tokens.size() >= 2) && (tokens[0] ==
"COMMFLAG_REQUEST"))
525 QDateTime recstartts;
528 message = QString(
"mythcommflag: Received a "
529 "COMMFLAG_REQUEST event for chanid %1 @ %2. ")
530 .arg(chanid).arg(recstartts.toString(
Qt::ISODate));
536 message +=
"Requested CommDetector to generate new break list.";
537 LOG(VB_COMMFLAG, LOG_INFO, message);
545 bool showPercentage,
bool fullSpeed,
int jobid,
547 const QString &outputfilename,
bool useDB)
550 commDetectMethod, showPercentage,
559 LOG(VB_COMMFLAG, LOG_INFO,
560 QString(
"mythcommflag processing JobID %1").
arg(jobid));
578 LOG(VB_COMMFLAG, LOG_INFO,
579 "mythcommflag sending COMMFLAG_START notification");
580 QString message =
"COMMFLAG_START ";
594 comms_found = commBreakList.size() / 2;
656 LOG(VB_GENERAL, LOG_ERR, QString(
"Couldn't find file %1, aborting.")
663 LOG(VB_GENERAL, LOG_ERR, QString(
"File %1 is zero-byte, aborting.")
682 mark_query.
prepare(
"SELECT commflagged, count(rm.type) "
684 "LEFT JOIN recordedmarkup rm ON "
685 "( r.chanid = rm.chanid AND "
686 "r.starttime = rm.starttime AND "
687 "type in (:MARK_START,:MARK_END)) "
688 "WHERE r.chanid = :CHANID AND "
689 "r.starttime = :STARTTIME "
690 "GROUP BY COMMFLAGGED;");
694 mark_query.
bindValue(
":STARTTIME", starttime);
697 mark_query.
size() > 0)
699 if (mark_query.
next())
701 int flagStatus = mark_query.
value(0).toInt();
702 int marksFound = mark_query.
value(1).toInt();
704 QString flagStatusStr =
"UNKNOWN";
705 switch (flagStatus) {
707 flagStatusStr =
"Not Flagged";
710 flagStatusStr = QString(
"Flagged with %1 breaks")
711 .arg(marksFound / 2);
714 flagStatusStr =
"Flagging";
717 flagStatusStr =
"Commercial Free";
721 LOG(VB_COMMFLAG, LOG_INFO,
722 QString(
"Status for chanid %1 @ %2 is '%3'")
724 .arg(flagStatusStr));
734 const QString &outputfilename,
bool useDB,
bool fullSpeed)
751 commDetectMethod = (
SkipType) commmethod.toInt(&ok);
757 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
758 QStringList list = commmethod.split(
",", QString::SkipEmptyParts);
760 QStringList list = commmethod.split(
",", Qt::SkipEmptyParts);
762 for (
const auto & it : qAsConst(list))
764 QString val = it.toLower();
773 std::cerr <<
"Failed to decode --method option '"
774 << val.toLatin1().constData()
780 commDetectMethod =
skipTypes->value(val);
782 commDetectMethod = (
SkipType) ((
int)commDetectMethod
797 "WHERE chanid = :CHANID;");
814 LOG(VB_COMMFLAG, LOG_INFO,
815 QString(
"Chanid %1 is marked as being Commercial Free, "
816 "we will use the default commercial detection "
825 LOG(VB_COMMFLAG, LOG_INFO,
826 QString(
"Using method: %1 from channel %2")
862 LOG(VB_GENERAL, LOG_ERR,
863 "Unable to find file in defined storage paths.");
872 LOG(VB_GENERAL, LOG_ERR,
873 QString(
"Unable to create RingBuffer for %1").
arg(
filename));
882 LOG(VB_GENERAL, LOG_ERR,
"Unable to open commflag DB connection");
898 LOG(VB_GENERAL, LOG_INFO,
"Enabling experimental flagging speedup (low resolution)");
911 ctx->SetPlayingInfo(program_info);
912 ctx->SetRingBuffer(tmprbuf);
928 LOG(VB_COMMFLAG, LOG_INFO,
929 QString(
"mythcommflag will flag recording "
930 "currently in progress on cardid %1")
938 LOG(VB_GENERAL, LOG_ERR,
939 "Unable to find active recorder for this "
940 "recording, realtime flagging will not be enabled.");
949 program_info,
progress, fullSpeed, jobid,
950 cfp, commDetectMethod, outputfilename, useDB);
953 std::cerr << breaksFound <<
"\n";
955 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Finished, %1 break(s) found.")
965 int jobid,
const QString &outputfilename,
973 LOG(VB_GENERAL, LOG_ERR,
974 QString(
"No program data exists for channel %1 at %2")
975 .
arg(chanid).
arg(startstring));
983 std::cerr <<
"IN USE\n";
985 "(the program is already being flagged elsewhere)\n";
987 LOG(VB_GENERAL, LOG_ERR,
"Program is already being flagged elsewhere");
994 std::cerr <<
"MythTV Commercial Flagger, flagging commercials for:" << std::endl;
996 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() << std::endl;
998 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() <<
" - "
999 << pginfo.
GetSubtitle().toLocal8Bit().constData() << std::endl;
1002 return FlagCommercials(&pginfo, jobid, outputfilename,
true, fullSpeed);
1006 const QString &outputfilename,
bool useDB,
1012 std::cerr <<
"MythTV Commercial Flagger, flagging commercials for:" << std::endl
1013 <<
" " <<
filename.toLatin1().constData() << std::endl;
1017 return FlagCommercials(&pginfo, jobid, outputfilename, useDB, fullSpeed);
1030 filename = QString(
"myth://Videos@%1/%2")
1035 LOG(VB_GENERAL, LOG_ERR,
1036 QString(
"Unable to find file in defined storage "
1037 "paths for JobQueue ID# %1.").
arg(jobid));
1049 LOG(VB_GENERAL, LOG_ERR,
1050 QString(
"Unable to create RingBuffer for %1").
arg(
filename));
1058 ctx->SetPlayingInfo(pginfo);
1059 ctx->SetRingBuffer(tmprbuf);
1060 ctx->SetPlayer(cfp);
1064 QString time = QDateTime::currentDateTime().toString(Qt::TextDate);
1065 std::cerr <<
"Rebuild started at " << qPrintable(time) << std::endl;
1076 QString time = QDateTime::currentDateTime().toString(Qt::TextDate);
1077 std::cerr <<
"Rebuild completed at " << qPrintable(time) << std::endl;
1089 std::cerr <<
"MythTV Commercial Flagger, building seek table for:" << std::endl
1090 <<
" " <<
filename.toLatin1().constData() << std::endl;
1101 std::cerr <<
"MythTV Commercial Flagger, building seek table for:" << std::endl;
1103 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() << std::endl;
1105 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() <<
" - "
1106 << pginfo.
GetSubtitle().toLocal8Bit().constData() << std::endl;
1137 QCoreApplication a(argc, argv);
1147 QList<int> signallist;
1148 signallist << SIGINT << SIGTERM << SIGSEGV << SIGABRT << SIGBUS << SIGFPE
1151 signallist << SIGRTMIN;
1163 LOG(VB_GENERAL, LOG_EMERG,
"Failed to init MythContext, exiting.");
1211 QDateTime starttime;
1215 std::cerr <<
"mythcommflag: ERROR: Unable to find DB info for "
1216 <<
"JobQueue ID# " <<
jobID << std::endl;
1222 if (jobQueueCPU < 2)
1240 QCoreApplication::translate(
"(mythcommflag)",
1241 "Failed with exit status %1",
1242 "Job status").
arg(ret));
1247 QCoreApplication::translate(
"(mythcommflag)",
1248 "%n commercial break(s)",
1264 std::cerr <<
"The --rebuild parameter builds the seektable for "
1265 "internal MythTV use only. It cannot be used in "
1266 "combination with --skipdb." << std::endl;
1304 query.
prepare(
"SELECT r.chanid, r.starttime, c.commmethod "
1305 "FROM recorded AS r "
1306 "LEFT JOIN channel AS c ON r.chanid=c.chanid "
1308 "ORDER BY starttime;");
1314 QDateTime starttime;
1346 LOG(VB_GENERAL, LOG_ERR,
1347 "No valid combination of command inputs received.");
static enum JobCmds GetJobCmd(int jobID)
bool isActive(void) const
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
QSqlQuery wrapper that fetches a DB connection from the connection pool.
virtual void SaveFilesize(uint64_t fsize)
Sets recording file size in database, and sets "filesize" field.
QString MakeUniqueKey(void) const
Creates a unique string that can be used to identify an existing recording.
void SendMessage(const QString &message)
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
static Type MythEventMessage
static bool DoesFileExist(ProgramInfo *program_info)
#define GENERIC_EXIT_OK
Exited with no error.
virtual uint64_t GetFilesize(void) const
RemoteEncoder * RemoteGetExistingRecorder(const ProgramInfo *pginfo)
Abstract base class for all CommDetectors. Please use the CommDetectFactory to make actual instances.
static int ClearSkipList(uint chanid, const QDateTime &starttime)
uint64_t GetTotalFrameCount(void) const
int GetRecorderNumber(void) const
long long GetFileSize(void) const
GetFileSize: returns the remote file's size at the time it was first opened Will query the server in ...
static bool QueueJob(int jobType, uint chanid, const QDateTime &recstartts, const QString &args="", const QString &comment="", QString host="", int flags=0, int status=JOB_QUEUED, QDateTime schedruntime=QDateTime())
CommDetectorBase * commDetector
bool myth_ioprio(int)
Allows setting the I/O priority of the current process/thread.
static int DoFlagCommercials(ProgramInfo *program_info, bool showPercentage, bool fullSpeed, int jobid, MythCommFlagPlayer *cfp, SkipType commDetectMethod, const QString &outputfilename, bool useDB)
void UnregisterFileForWrite(const QString &file)
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Holds information on a TV Program one might wish to record.
void gotNewCommercialBreakList()
Startup context for MythTV.
This class is used as a container for messages.
static void incomingCustomEvent(QEvent *e)
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
@ COMM_DETECT_BLANK_SCENE
QVariant value(int i) const
static QMap< QString, OutputMethod > * init_output_types()
arg(title).arg(filename).arg(doDelete))
void statusUpdate(const QString &a)
QMap< uint64_t, MarkTypes > frm_dir_map_t
Frame # -> Mark map.
static bool GetJobInfoFromID(int jobID, int &jobType, uint &chanid, QDateTime &recstartts)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
static bool ExtractKey(const QString &uniquekey, uint &chanid, QDateTime &recstartts)
Extracts chanid and recstartts from a unique key generated by MakeUniqueKey().
@ kOutputMethodEssentials
void SaveCommFlagged(CommFlagStatus flag)
Set "commflagged" field in "recorded" table to "flag".
QDateTime GetScheduledEndTime(void) const
The scheduled end time of the program.
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
int main(int argc, char *argv[])
#define GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
static void UpdateFileSize(ProgramInfo *program_info)
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
const QString & Message() const
static bool IsJobRunning(int jobType, uint chanid, const QDateTime &recstartts)
QDateTime GetRecordingStartTime(void) const
Approximate time the recording started.
QString GetPathname(void) const
static int CopySkipListToCutList(uint chanid, const QDateTime &starttime)
void SaveCommBreakList(frm_dir_map_t &frames) const
static void commDetectorStatusUpdate(const QString &status)
virtual void recordingFinished(long long totalFileSize)
unsigned sleep(unsigned int x)
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
ProgramInfo * global_program_info
static QString get_filename(ProgramInfo *program_info)
void SetPathname(const QString &pn)
QMap< QString, OutputMethod > * outputTypes
virtual void PrintFullMap(std::ostream &out, const frm_dir_map_t *comm_breaks, bool verbose) const =0
QDateTime GetScheduledStartTime(void) const
The scheduled start time of program.
OutputMethod outputMethod
QMap< QString, SkipType > * skipTypes
@ kFilename
Default UTC, "yyyyMMddhhmmss".
static bool ChangeJobComment(int jobID, const QString &comment="")
static int RebuildSeekTable(ProgramInfo *pginfo, int jobid, bool writefile=false)
static void commDetectorBreathe()
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetTitle(void) const
static void DBError(const QString &where, const MSqlQuery &query)
static bool testDBConnection()
Checks DB connection + login (login info via Mythcontext)
int GetAutoRunJobs(void) const
Returns a bitmap of which jobs are attached to this RecordingInfo.
#define GENERIC_EXIT_NO_RECORDING_DATA
No program/recording data.
bool QueryCutList(frm_dir_map_t &delMap, bool loadAutosave=false) const
static void PrintVersion(void)
Print application version information.
uint toUInt(const QString &key) const
Returns stored QVariant as an unsigned integer, falling to default if not provided.
void PrintHelp(void) const
Print command line option help.
virtual void GetCommercialBreakList(frm_dir_map_t &comms)=0
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
#define GENERIC_EXIT_PERMISSIONS_ERROR
File permissions error.
static int FlagCommercials(ProgramInfo *program_info, int jobid, const QString &outputfilename, bool useDB, bool fullSpeed)
void ApplySettingsOverride(void)
Apply all overrides to the global context.
int GetNumSetting(const QString &key, int defaultval=0)
static void commDetectorGotNewCommercialBreakList(void)
static QString cleanup(const QString &str)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
#define MYTH_BINARY_VERSION
Update this whenever the plug-in ABI changes.
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
#define GENERIC_EXIT_DB_ERROR
Database error.
MythCommFlagCommandLineParser cmdline
Holds information on recordings and videos.
static int QueueCommFlagJob(uint chanid, const QDateTime &starttime, bool rebuild)
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
#define GENERIC_EXIT_IN_USE
Recording in use, can't flag.
uint64_t QueryLastFrameInPosMap(void) const
Returns last frame in position map or 0.
#define GENERIC_EXIT_NOT_OK
Exited with error.
bool SetValue(const QString &key, const QVariant &value)
Set a new stored value for an existing argument definition, or spawn a new definition store value in.
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
static QMap< QString, SkipType > * init_skip_types()
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
static enum JobFlags GetJobFlags(int jobID)
static void print_comm_flag_output(const ProgramInfo *program_info, const frm_dir_map_t &commBreakList, uint64_t frame_count, const CommDetectorBase *commDetect, const QString &output_filename)
static qint64 GetFileSize(ProgramInfo *program_info)
static int SetCutList(uint chanid, const QDateTime &starttime, QString newCutList)
void SaveCutList(frm_dir_map_t &delMap, bool isAutoSave=false) const
#define GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
static void SetHandler(int signum, SigHandlerFunc handler)
#define MYTH_APPNAME_MYTHCOMMFLAG
static bool IsMarked(uint chanid, const QDateTime &starttime)
static int GetMarkupList(const QString &list, uint chanid, const QDateTime &starttime)
SkipType
This is used as a bitmask.
void QueryCommBreakList(frm_dir_map_t &frames) const
QString GetHostName(void)
void SaveMarkupFlag(MarkTypes type) const
Clears the specified flag, then if sets it.
void SaveTotalDuration(void)
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
static CommDetectorBase * makeCommDetector(SkipType commDetectMethod, bool showProgress, bool fullSpeed, MythCommFlagPlayer *player, int chanid, const QDateTime &startedAt, const QDateTime &stopsAt, const QDateTime &recordingStartedAt, const QDateTime &recordingStopsAt, bool useDB)
static void streamOutCommercialBreakList(std::ostream &output, const frm_dir_map_t &commercialBreakList)
virtual void requestCommBreakMapUpdate(void)
const QString kFlaggerInUseID
static void load(const QString &module_name)
Load a QTranslator for the user's preferred language.
int toInt(const QString &key) const
Returns stored QVariant as an integer, falling to default if not provided.
static bool ChangeJobStatus(int jobID, int newStatus, const QString &comment="")
MSqlQuery query(MSqlQuery::InitCon())
QDateTime toDateTime(const QString &key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
MythContext * gContext
This global variable contains the MythContext instance for the application.
bool Init(bool gui=true, bool promptForBackend=false, bool disableAutoDiscovery=false, bool ignoreDB=false)
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
QString GetSubtitle(void) const
static void Init(QList< int > &signallist, QObject *parent=nullptr)