Go to the documentation of this file.
2 #if defined ANDROID && __ANDROID_API__ < 24
21 #include <QCoreApplication>
35 #include "libmythbase/mythversion.h"
54 #define LOC QString("MythCommFlag: ")
55 #define LOC_WARN QString("MythCommFlag, Warning: ")
56 #define LOC_ERR QString("MythCommFlag, Error: ")
88 auto *
tmp =
new QMap<QString,SkipType>;
119 auto *
tmp =
new QMap<QString,OutputMethod>;
142 QString
tmp = QString(
143 "Unable to find program info for chanid %1 @ %2")
144 .arg(chanid).arg(startstring);
145 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
152 QString
tmp = QString(
"Job have been queued for chanid %1 @ %2")
153 .arg(chanid).arg(startstring);
154 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
160 rebuild ?
JOB_REBUILD : 0, JOB_QUEUED, QDateTime());
166 QString
tmp = QString(
"Job Queued for chanid %1 @ %2")
167 .arg(chanid).arg(startstring);
168 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
175 QString
tmp = QString(
"Error queueing job for chanid %1 @ %2")
176 .arg(chanid).arg(startstring);
177 std::cerr <<
tmp.toLocal8Bit().constData() << std::endl;
186 output <<
"----------------------------" << std::endl;
188 if (commercialBreakList.empty())
191 output <<
"No breaks" << std::endl;
195 frm_dir_map_t::const_iterator it = commercialBreakList.begin();
196 for (; it != commercialBreakList.end(); ++it)
198 output <<
"framenum: " << it.key() <<
"\tmarktype: " << *it
204 output <<
"----------------------------" << std::endl;
210 uint64_t frame_count,
212 const QString &output_filename)
214 if (output_filename.isEmpty())
217 std::ostream *out = &std::cout;
218 if (output_filename !=
"-")
220 QByteArray
tmp = output_filename.toLocal8Bit();
221 out =
new std::fstream(
tmp.constData(), std::ios::app | std::ios::out );
229 tmp = QString(
"commercialBreakListFor: %1 on %2 @ %3")
236 tmp = QString(
"commercialBreakListFor: %1")
240 const QByteArray tmp2 =
tmp.toLocal8Bit();
241 *out << tmp2.constData() << std::endl;
244 *out <<
"totalframecount: " << frame_count << std::endl;
252 if (out != &std::cout)
260 qApp->processEvents();
278 QCoreApplication::translate(
"(mythcommflag)",
279 "Paused",
"Job status"));
286 QCoreApplication::translate(
"(mythcommflag)",
287 "Running",
"Job status"));
309 QString message =
"COMMFLAG_UPDATE ";
312 for (
auto it = newCommercialMap.begin();
313 it != newCommercialMap.end(); ++it)
315 if (it != newCommercialMap.begin())
319 message += QString(
"%1:%2").arg(it.key())
323 LOG(VB_COMMFLAG, LOG_INFO,
324 QString(
"mythcommflag sending update: %1").arg(message));
337 QString message = me->
Message();
339 message = message.simplified();
340 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
341 QStringList tokens = message.split(
" ", QString::SkipEmptyParts);
343 QStringList tokens = message.split(
" ", Qt::SkipEmptyParts);
346 LOG(VB_COMMFLAG, LOG_INFO,
347 QString(
"mythcommflag: Received Event: '%1'") .arg(message));
350 (tokens[0] ==
"DONE_RECORDING"))
352 int cardnum = tokens[1].toInt();
353 int filelen = tokens[2].toInt();
355 message = QString(
"mythcommflag: Received a "
356 "DONE_RECORDING event for card %1. ")
363 message +=
"Informed CommDetector that recording has finished.";
364 LOG(VB_COMMFLAG, LOG_INFO, message);
368 if ((tokens.size() >= 2) && (tokens[0] ==
"COMMFLAG_REQUEST"))
371 QDateTime recstartts;
374 message = QString(
"mythcommflag: Received a "
375 "COMMFLAG_REQUEST event for chanid %1 @ %2. ")
376 .arg(chanid).arg(recstartts.toString(
Qt::ISODate));
382 message +=
"Requested CommDetector to generate new break list.";
383 LOG(VB_COMMFLAG, LOG_INFO, message);
391 bool showPercentage,
bool fullSpeed,
int jobid,
393 const QString &outputfilename,
bool useDB)
396 commDetectMethod, showPercentage,
405 LOG(VB_COMMFLAG, LOG_INFO,
406 QString(
"mythcommflag processing JobID %1").arg(jobid));
424 LOG(VB_COMMFLAG, LOG_INFO,
425 "mythcommflag sending COMMFLAG_START notification");
426 QString message =
"COMMFLAG_START ";
440 comms_found = commBreakList.size() / 2;
502 LOG(VB_GENERAL, LOG_ERR, QString(
"Couldn't find file %1, aborting.")
509 LOG(VB_GENERAL, LOG_ERR, QString(
"File %1 is zero-byte, aborting.")
528 mark_query.
prepare(
"SELECT commflagged, count(rm.type) "
530 "LEFT JOIN recordedmarkup rm ON "
531 "( r.chanid = rm.chanid AND "
532 "r.starttime = rm.starttime AND "
533 "type in (:MARK_START,:MARK_END)) "
534 "WHERE r.chanid = :CHANID AND "
535 "r.starttime = :STARTTIME "
536 "GROUP BY COMMFLAGGED;");
540 mark_query.
bindValue(
":STARTTIME", starttime);
543 mark_query.
size() > 0)
545 if (mark_query.
next())
547 int flagStatus = mark_query.
value(0).toInt();
548 int marksFound = mark_query.
value(1).toInt();
550 QString flagStatusStr =
"UNKNOWN";
551 switch (flagStatus) {
553 flagStatusStr =
"Not Flagged";
556 flagStatusStr = QString(
"Flagged with %1 breaks")
557 .arg(marksFound / 2);
560 flagStatusStr =
"Flagging";
563 flagStatusStr =
"Commercial Free";
567 LOG(VB_COMMFLAG, LOG_INFO,
568 QString(
"Status for chanid %1 @ %2 is '%3'")
569 .arg(QString::number(chanid),
581 const QString &outputfilename,
bool useDB,
bool fullSpeed)
598 commDetectMethod = (
SkipType) commmethod.toInt(&ok);
604 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
605 QStringList list = commmethod.split(
",", QString::SkipEmptyParts);
607 QStringList list = commmethod.split(
",", Qt::SkipEmptyParts);
609 for (
const auto & it : qAsConst(list))
611 QString val = it.toLower();
620 std::cerr <<
"Failed to decode --method option '"
621 << val.toLatin1().constData()
627 commDetectMethod =
skipTypes->value(val);
629 commDetectMethod = (
SkipType) ((
int)commDetectMethod
643 query.
prepare(
"SELECT commmethod FROM channel "
644 "WHERE chanid = :CHANID;");
653 else if (query.
next())
661 LOG(VB_COMMFLAG, LOG_INFO,
662 QString(
"Chanid %1 is marked as being Commercial Free, "
663 "we will use the default commercial detection "
664 "method").arg(program_info->
GetChanID()));
672 LOG(VB_COMMFLAG, LOG_INFO,
673 QString(
"Using method: %1 from channel %2")
674 .arg(commDetectMethod).arg(program_info->
GetChanID()));
709 LOG(VB_GENERAL, LOG_ERR,
710 "Unable to find file in defined storage paths.");
719 LOG(VB_GENERAL, LOG_ERR,
720 QString(
"Unable to create RingBuffer for %1").arg(
filename));
729 LOG(VB_GENERAL, LOG_ERR,
"Unable to open commflag DB connection");
745 LOG(VB_GENERAL, LOG_INFO,
"Enabling experimental flagging speedup (low resolution)");
758 ctx->SetPlayingInfo(program_info);
759 ctx->SetRingBuffer(tmprbuf);
775 LOG(VB_COMMFLAG, LOG_INFO,
776 QString(
"mythcommflag will flag recording "
777 "currently in progress on cardid %1")
785 LOG(VB_GENERAL, LOG_ERR,
786 "Unable to find active recorder for this "
787 "recording, realtime flagging will not be enabled.");
796 program_info,
progress, fullSpeed, jobid,
797 cfp, commDetectMethod, outputfilename, useDB);
800 std::cerr << breaksFound <<
"\n";
802 LOG(VB_GENERAL, LOG_NOTICE, QString(
"Finished, %1 break(s) found.")
812 int jobid,
const QString &outputfilename,
820 LOG(VB_GENERAL, LOG_ERR,
821 QString(
"No program data exists for channel %1 at %2")
822 .arg(chanid).arg(startstring));
830 std::cerr <<
"IN USE\n";
832 "(the program is already being flagged elsewhere)\n";
834 LOG(VB_GENERAL, LOG_ERR,
"Program is already being flagged elsewhere");
841 std::cerr <<
"MythTV Commercial Flagger, flagging commercials for:" << std::endl;
843 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() << std::endl;
845 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() <<
" - "
846 << pginfo.
GetSubtitle().toLocal8Bit().constData() << std::endl;
849 return FlagCommercials(&pginfo, jobid, outputfilename,
true, fullSpeed);
853 const QString &outputfilename,
bool useDB,
859 std::cerr <<
"MythTV Commercial Flagger, flagging commercials for:" << std::endl
860 <<
" " <<
filename.toLatin1().constData() << std::endl;
864 return FlagCommercials(&pginfo, jobid, outputfilename, useDB, fullSpeed);
877 filename = QString(
"myth://Videos@%1/%2")
882 LOG(VB_GENERAL, LOG_ERR,
883 QString(
"Unable to find file in defined storage "
884 "paths for JobQueue ID# %1.").arg(jobid));
896 LOG(VB_GENERAL, LOG_ERR,
897 QString(
"Unable to create RingBuffer for %1").arg(
filename));
905 ctx->SetPlayingInfo(pginfo);
906 ctx->SetRingBuffer(tmprbuf);
911 QString time = QDateTime::currentDateTime().toString(Qt::TextDate);
912 std::cerr <<
"Rebuild started at " << qPrintable(time) << std::endl;
923 QString time = QDateTime::currentDateTime().toString(Qt::TextDate);
924 std::cerr <<
"Rebuild completed at " << qPrintable(time) << std::endl;
936 std::cerr <<
"MythTV Commercial Flagger, building seek table for:" << std::endl
937 <<
" " <<
filename.toLatin1().constData() << std::endl;
948 std::cerr <<
"MythTV Commercial Flagger, building seek table for:" << std::endl;
950 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() << std::endl;
952 std::cerr <<
" " << pginfo.
GetTitle().toLocal8Bit().constData() <<
" - "
953 << pginfo.
GetSubtitle().toLocal8Bit().constData() << std::endl;
958 int main(
int argc,
char *argv[])
984 QCoreApplication a(argc, argv);
1003 LOG(VB_GENERAL, LOG_EMERG,
"Failed to init MythContext, exiting.");
1038 QDateTime starttime;
1042 std::cerr <<
"mythcommflag: ERROR: Unable to find DB info for "
1043 <<
"JobQueue ID# " <<
jobID << std::endl;
1049 if (jobQueueCPU < 2)
1067 QCoreApplication::translate(
"(mythcommflag)",
1068 "Failed with exit status %1",
1069 "Job status").arg(ret));
1074 QCoreApplication::translate(
"(mythcommflag)",
1075 "%n commercial break(s)",
1091 std::cerr <<
"The --rebuild parameter builds the seektable for "
1092 "internal MythTV use only. It cannot be used in "
1093 "combination with --skipdb." << std::endl;
1131 query.
prepare(
"SELECT r.chanid, r.starttime, c.commmethod "
1132 "FROM recorded AS r "
1133 "LEFT JOIN channel AS c ON r.chanid=c.chanid "
1135 "ORDER BY starttime;");
1141 QDateTime starttime;
1143 while (query.
next())
1173 LOG(VB_GENERAL, LOG_ERR,
1174 "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.
static int FlagCommercials(ProgramInfo *program_info, int jobid, const QString &outputfilename, bool useDB, bool fullSpeed)
virtual void SaveFilesize(uint64_t fsize)
Sets recording file size in database, and sets "filesize" field.
static QMap< QString, OutputMethod > * init_output_types()
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.
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 const Type kMythEventMessage
uint64_t GetTotalFrameCount(void) const
int GetRecorderNumber(void) const
CommDetectorBase * commDetector
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())
bool myth_ioprio(int)
Allows setting the I/O priority of the current process/thread.
int main(int argc, char *argv[])
MythCommFlagCommandLineParser cmdline
void UnregisterFileForWrite(const QString &file)
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Holds information on a TV Program one might wish to record.
OutputMethod outputMethod
void gotNewCommercialBreakList()
Startup context for MythTV.
static int QueueCommFlagJob(uint chanid, const QDateTime &starttime, bool rebuild)
This class is used as a container for messages.
void RegisterFileForWrite(const QString &file, uint64_t size=0LL)
static void commDetectorGotNewCommercialBreakList(void)
@ COMM_DETECT_BLANK_SCENE
QVariant value(int i) const
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().
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_)
static int DoFlagCommercials(ProgramInfo *program_info, bool showPercentage, bool fullSpeed, int jobid, MythCommFlagPlayer *cfp, SkipType commDetectMethod, const QString &outputfilename, bool useDB)
QMap< QString, SkipType > * skipTypes
QDateTime GetRecordingEndTime(void) const
Approximate time the recording should have ended, did end, or is intended to end.
@ GENERIC_EXIT_OK
Exited with no error.
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
void SaveCommBreakList(frm_dir_map_t &frames) const
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
void SetPathname(const QString &pn)
static void UpdateFileSize(ProgramInfo *program_info)
virtual void recordingFinished([[maybe_unused]] long long totalFileSize)
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.
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
static void commDetectorStatusUpdate(const QString &status)
@ kFilename
Default UTC, "yyyyMMddhhmmss".
static bool ChangeJobComment(int jobID, const QString &comment="")
static constexpr const char * MYTH_APPNAME_MYTHCOMMFLAG
static bool DoesFileExist(ProgramInfo *program_info)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
QString GetTitle(void) const
static qint64 GetFileSize(ProgramInfo *program_info)
static void DBError(const QString &where, const MSqlQuery &query)
static bool testDBConnection()
Checks DB connection + login (login info via Mythcontext)
static bool IsMarked(uint chanid, const QDateTime &starttime)
int GetAutoRunJobs(void) const
Returns a bitmap of which jobs are attached to this RecordingInfo.
static QMap< QString, SkipType > * init_skip_types()
static void PrintVersion(void)
Print application version information.
@ GENERIC_EXIT_NO_RECORDING_DATA
No program/recording data.
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.
@ GENERIC_EXIT_NOT_OK
Exited with error.
static QString get_filename(ProgramInfo *program_info)
virtual void GetCommercialBreakList(frm_dir_map_t &comms)=0
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
void ApplySettingsOverride(void)
Apply all overrides to the global context.
@ GENERIC_EXIT_PERMISSIONS_ERROR
File permissions error.
int GetNumSetting(const QString &key, int defaultval=0)
static QString cleanup(const QString &str)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
static void streamOutCommercialBreakList(std::ostream &output, const frm_dir_map_t &commercialBreakList)
static void Init(QObject *parent=nullptr)
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Holds information on recordings and videos.
static int RebuildSeekTable(ProgramInfo *pginfo, int jobid, bool writefile=false)
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
ProgramInfo * global_program_info
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.
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 commDetectorBreathe()
SkipType
This is used as a bitmask.
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.
QMap< QString, OutputMethod > * outputTypes
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)
@ kOutputMethodEssentials
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="")
static void incomingCustomEvent(QEvent *e)
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
@ GENERIC_EXIT_IN_USE
Recording in use, can't flag.
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.
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)
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
@ GENERIC_EXIT_DB_ERROR
Database error.