MythTV master
mythpreviewgen.cpp
Go to the documentation of this file.
1// C++ headers
2#include <cerrno>
3#include <csignal>
4#include <cstdlib>
5#include <fcntl.h>
6#include <fstream>
7#include <iostream>
8#include <libgen.h>
9#include <sys/stat.h>
10#include <sys/types.h>
11#include <unistd.h>
12
13// Qt
14#include <QtGlobal>
15#if QT_VERSION >= QT_VERSION_CHECK(6,5,0)
16#include <QtSystemDetection>
17#endif
18#ifndef Q_OS_WINDOWS
19#include <QCoreApplication>
20#else
21#include <QApplication>
22#endif
23#include <QDir>
24#include <QFile>
25#include <QFileInfo>
26#include <QMap>
27
28// MythTV
29#include "libmyth/mythcontext.h"
30#include "libmythbase/mythconfig.h"
31#include "libmythbase/compat.h"
34#include "libmythbase/mythdb.h"
36#include "libmythbase/mythversion.h"
38#include "libmythtv/dbcheck.h"
42
43//MythPreviewGen
45
46#define LOC QString("MythPreviewGen: ")
47
48#ifdef Q_OS_MACOS
49// 10.6 uses some file handles for its new Grand Central Dispatch thingy
50static constexpr long UNUSED_FILENO { 5 };
51#else
52static constexpr long UNUSED_FILENO { 3 };
53#endif
54
55int preview_helper(uint chanid, QDateTime starttime,
56 long long previewFrameNumber, std::chrono::seconds previewSeconds,
57 const QSize previewSize,
58 const QString &infile, const QString &outfile)
59{
60 if (!QFileInfo(infile).isReadable() && ((chanid == 0U) || !starttime.isValid()))
61 ProgramInfo::QueryKeyFromPathname(infile, chanid, starttime);
62
63 ProgramInfo *pginfo = nullptr;
64 if (chanid && starttime.isValid())
65 {
66 pginfo = new ProgramInfo(chanid, starttime);
67 if (!pginfo->GetChanID())
68 {
69 LOG(VB_GENERAL, LOG_ERR,
70 QString("Cannot locate recording made on '%1' at '%2'")
71 .arg(chanid).arg(starttime.toString(Qt::ISODate)));
72 delete pginfo;
74 }
75 pginfo->SetPathname(pginfo->GetPlaybackURL(false, true));
76 }
77 else if (!infile.isEmpty())
78 {
79 if (!QFileInfo(infile).isReadable())
80 {
81 LOG(VB_GENERAL, LOG_ERR,
82 QString("Cannot read this file '%1'").arg(infile));
84 }
85 pginfo = new ProgramInfo(
86 infile, ""/*plot*/, ""/*title*/, ""/*sortTitle*/, ""/*subtitle*/,
87 ""/*sortSubtitle*/, ""/*director*/, 0/*season*/, 0/*episode*/,
88 ""/*inetref*/, 120min/*length_in_minutes*/, 1895/*year*/, ""/*id*/);
89 }
90 else
91 {
92 LOG(VB_GENERAL, LOG_ERR, "Cannot locate recording to preview");
94 }
95
96 auto *previewgen = new PreviewGenerator(pginfo, QString(),
98
99 if (previewFrameNumber >= 0)
100 previewgen->SetPreviewTimeAsFrameNumber(previewFrameNumber);
101
102 if (previewSeconds >= 0s)
103 previewgen->SetPreviewTimeAsSeconds(previewSeconds);
104
105 previewgen->SetOutputSize(previewSize);
106 previewgen->SetOutputFilename(outfile);
107 bool ok = previewgen->RunReal();
108 previewgen->deleteLater();
109
110 delete pginfo;
111
113}
114
115int main(int argc, char **argv)
116{
118 if (!cmdline.Parse(argc, argv))
119 {
122 }
123
124 if (cmdline.toBool("showhelp"))
125 {
127 return GENERIC_EXIT_OK;
128 }
129
130 if (cmdline.toBool("showversion"))
131 {
133 return GENERIC_EXIT_OK;
134 }
135
136#ifndef Q_OS_WINDOWS
137#if HAVE_CLOSE_RANGE
138 close_range(UNUSED_FILENO, sysconf(_SC_OPEN_MAX) - 1, 0);
139#else
140 for (long i = UNUSED_FILENO; i < sysconf(_SC_OPEN_MAX) - 1; ++i)
141 close(i);
142#endif
143 QCoreApplication a(argc, argv);
144#else
145 // MINGW application needs a window to receive messages
146 // such as socket notifications :[
147 QApplication a(argc, argv);
148#endif
149 QCoreApplication::setApplicationName(MYTH_APPNAME_MYTHPREVIEWGEN);
150
151 int retval = cmdline.ConfigureLogging();
152 if (retval != GENERIC_EXIT_OK)
153 return retval;
154
155 if ((!cmdline.toBool("chanid") || !cmdline.toBool("starttime")) &&
156 !cmdline.toBool("inputfile"))
157 {
158 std::cerr << "--generate-preview must be accompanied by either\n"
159 << "\nboth --chanid and --starttime parameters,\n"
160 << "\nor the --infile parameter.\n";
162 }
163
165
166 // Don't listen to console input
167 close(0);
168
169 if (signal(SIGPIPE, SIG_IGN) == SIG_ERR)
170 LOG(VB_GENERAL, LOG_WARNING, LOC + "Unable to ignore SIGPIPE");
171
172 MythContext context {MYTH_BINARY_VERSION};
173 if (!context.Init(false))
174 {
175 LOG(VB_GENERAL, LOG_ERR, "Failed to init MythContext.");
177 }
178
179 int ret = preview_helper(
180 cmdline.toUInt("chanid"), cmdline.toDateTime("starttime"),
181 cmdline.toLongLong("frame"), std::chrono::seconds(cmdline.toLongLong("seconds")),
182 cmdline.toSize("size"),
183 cmdline.toString("inputfile"), cmdline.toString("outputfile"));
184 return ret;
185}
186
187/* vim: set expandtab tabstop=4 shiftwidth=4: */
bool toBool(const QString &key) const
Returns stored QVariant as a boolean.
virtual bool Parse(int argc, const char *const *argv)
Loop through argv and populate arguments with values.
QSize toSize(const QString &key) const
Returns stored QVariant as a QSize value, falling to default if not provided.
int ConfigureLogging(const QString &mask="general", bool progress=false)
Read in logging options and initialize the logging interface.
QString toString(const QString &key) const
Returns stored QVariant as a QString, falling to default if not provided.
long long toLongLong(const QString &key) const
Returns stored QVariant as a long integer, falling to default if not provided.
static void PrintVersion(void)
Print application version information.
QDateTime toDateTime(const QString &key) const
Returns stored QVariant as a QDateTime, falling to default if not provided.
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.
Startup context for MythTV.
Definition: mythcontext.h:20
This class creates a preview image of a recording.
Holds information on recordings and videos.
Definition: programinfo.h:74
uint GetChanID(void) const
This is the unique key used in the database to locate tuning information.
Definition: programinfo.h:380
static bool QueryKeyFromPathname(const QString &pathname, uint &chanid, QDateTime &recstartts)
QString GetPlaybackURL(bool checkMaster=false, bool forceCheckLocal=false)
Returns filename or URL to be used to play back this recording.
void SetPathname(const QString &pn)
#define SIGPIPE
Definition: compat.h:80
unsigned int uint
Definition: compat.h:60
#define close
Definition: compat.h:28
@ GENERIC_EXIT_NO_MYTHCONTEXT
No MythContext available.
Definition: exitcodes.h:16
@ GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:13
@ GENERIC_EXIT_INVALID_CMDLINE
Command line parse error.
Definition: exitcodes.h:18
@ GENERIC_EXIT_NOT_OK
Exited with error.
Definition: exitcodes.h:14
static constexpr const char * MYTH_APPNAME_MYTHPREVIEWGEN
Definition: mythappname.h:11
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
#define LOC
int main(int argc, char **argv)
int preview_helper(uint chanid, QDateTime starttime, long long previewFrameNumber, std::chrono::seconds previewSeconds, const QSize previewSize, const QString &infile, const QString &outfile)
static constexpr long UNUSED_FILENO
@ ISODate
Default UTC.
Definition: mythdate.h:18
MythCommFlagCommandLineParser cmdline