MythTV master
videoplayercommand.cpp
Go to the documentation of this file.
1// Qt
2#include <QDir>
3
4// MythTV
13
14// MythFrontend
15#include "videoplayercommand.h"
16
17namespace
18{
19 QString ShellEscape(const QString &src)
20 {
21 return QString(src)
22 .replace("\"", "\\\"")
23 .replace("`", "\\`")
24 .replace("\\$", "\\$");
25 }
26
27 QString ExpandPlayCommand(const QString &command, const QString &filename)
28 {
29 // If handler contains %d, substitute default player command
30 // This would be used to add additional switches to the default without
31 // needing to retype the whole default command. But, if the
32 // command and the default command both contain %s, drop the %s from
33 // the default since the new command already has it
34 //
35 // example: default: mplayer -fs %s
36 // custom : %d -ao alsa9:spdif %s
37 // result : mplayer -fs -ao alsa9:spdif %s
38 QString tmp = command;
39 if (tmp.contains("%d"))
40 {
41 QString default_handler =
42 gCoreContext->GetSetting("VideoDefaultPlayer");
43 if (tmp.contains("%s") && default_handler.contains("%s"))
44 default_handler = default_handler.replace("%s", "");
45 tmp.replace("%d", default_handler);
46 }
47
48 QString arg = QString("\"%1\"").arg(ShellEscape(filename));
49
50 if (tmp.contains("%s"))
51 return tmp.replace("%s", arg);
52
53 return QString("%1 %2").arg(tmp, arg);
54 }
55}
56
58
60{
61 protected:
62 VideoPlayProc() = default;
64
65 public:
66 virtual ~VideoPlayProc() = default;
67 VideoPlayProc(const VideoPlayProc&) = default;
68
69 // returns true if item played
70 virtual bool Play() const = 0;
71
72 virtual QString GetCommandDisplayName() const = 0;
73
74 virtual VideoPlayProc *Clone() const = 0;
75};
76
78
80{
81 private:
82 VideoPlayHandleMedia(QString handler, QString mrl,
83 QString plot, QString title, QString subtitle,
84 QString director, int season, int episode, QString inetref,
85 std::chrono::minutes length, QString year, QString id) :
86 m_handler(std::move(handler)), m_mrl(std::move(mrl)),
87 m_plot(std::move(plot)), m_title(std::move(title)),
88 m_subtitle(std::move(subtitle)),
89 m_director(std::move(director)), m_season(season),
90 m_episode(episode), m_inetref(std::move(inetref)),
91 m_length(length), m_year(std::move(year)),
92 m_id(std::move(id))
93 {
94 }
95
96 public:
97 static VideoPlayHandleMedia *Create(const QString &handler,
98 const QString &mrl, const QString &plot, const QString &title,
99 const QString &subtitle, const QString &director,
100 int season, int episode, const QString &inetref,
101 std::chrono::minutes length, const QString &year, const QString &id)
102 {
103 return new VideoPlayHandleMedia(handler, mrl, plot, title, subtitle,
104 director, season, episode, inetref, length, year, id);
105 }
106
107 bool Play() const override // VideoPlayProc
108 {
112 }
113
114 QString GetCommandDisplayName() const override // VideoPlayProc
115 {
116 return m_handler;
117 }
118
119 VideoPlayHandleMedia *Clone() const override // VideoPlayProc
120 {
121 return new VideoPlayHandleMedia(*this);
122 }
123
124 private:
125 QString m_handler;
126 QString m_mrl;
127 QString m_plot;
128 QString m_title;
129 QString m_subtitle;
130 QString m_director;
133 QString m_inetref;
134 std::chrono::minutes m_length;
135 QString m_year;
136 QString m_id;
137};
138
140
142{
143 private:
144 VideoPlayMythSystem(QString disp_command,
145 QString play_command) :
146 m_displayCommand(std::move(disp_command)), m_playCommand(std::move(play_command))
147 {
148 }
149
150 public:
151 static VideoPlayMythSystem *Create(const QString &command,
152 const QString &filename)
153 {
154 return new VideoPlayMythSystem(command,
155 ExpandPlayCommand(command, filename));
156 }
157
158 bool Play() const override // VideoPlayProc
159 {
161
162 return true;
163 }
164
165 QString GetCommandDisplayName() const override // VideoPlayProc
166 {
167 return m_displayCommand;
168 }
169
170 VideoPlayMythSystem *Clone() const override // VideoPlayProc
171 {
172 return new VideoPlayMythSystem(*this);
173 }
174
175 private:
178};
179
181
183{
184 public:
186
188 {
189 auto playerclone = [](auto *player) { return player->Clone(); };
190 std::transform(other.m_playerProcs.cbegin(), other.m_playerProcs.cend(),
191 std::back_inserter(m_playerProcs), playerclone);
192 }
193
195
197 {
199 }
200
201 void AltPlayerFor(const VideoMetadata *item)
202 {
203 if (item)
204 {
205 QString play_command =
206 gCoreContext->GetSetting("mythvideo.VideoAlternatePlayer");
207 QString filename;
208
209 if (item->IsHostSet())
210 {
212 item->GetFilename());
213 }
214 else
215 {
216 filename = item->GetFilename();
217 }
218
219 if (!play_command.isEmpty())
220 {
221 AddPlayer(play_command, filename, item->GetPlot(),
222 item->GetTitle(), item->GetSubtitle(),
223 item->GetDirector(), item->GetSeason(),
224 item->GetEpisode(), item->GetInetRef(),
225 item->GetLength(), QString::number(item->GetYear()),
226 QString::number(item->GetID()));
227 }
228 else
229 {
230 PlayerFor(filename, item);
231 }
232 }
233 }
234
235 void PlayerFor(const VideoMetadata *item)
236 {
237 if (item)
238 {
239 const QString& play_command = item->GetPlayCommand();
240 QString filename;
241
242 if (item->IsHostSet())
243 {
245 item->GetFilename());
246 }
247 else
248 {
249 filename = item->GetFilename();
250 }
251
252 if (!play_command.isEmpty())
253 {
254 AddPlayer(play_command, filename, item->GetPlot(),
255 item->GetTitle(), item->GetSubtitle(),
256 item->GetDirector(), item->GetSeason(),
257 item->GetEpisode(), item->GetInetRef(),
258 item->GetLength(), QString::number(item->GetYear()),
259 QString::number(item->GetID()));
260 }
261 else
262 {
263 PlayerFor(filename, item);
264 }
265 }
266 }
267
268 void PlayerFor(const QString &filename, const VideoMetadata *extraData = nullptr)
269 {
270 QString extension = filename.section(".", -1, -1);
271 QDir dir_test(QString("%1/VIDEO_TS").arg(filename));
272 if (dir_test.exists())
273 extension = "VIDEO_TS";
274 QDir bd_dir_test(QString("%1/BDMV").arg(filename));
275 if (bd_dir_test.exists())
276 extension = "BDMV";
277
278 QString play_command = gCoreContext->GetSetting("VideoDefaultPlayer");
279
282 auto sameext = [extension](const auto & fa)
283 { return fa.extension.toLower() == extension.toLower() &&
284 !fa.use_default; };
285 auto fa = std::find_if(fa_list.cbegin(), fa_list.cend(), sameext);
286 if (fa != fa_list.cend())
287 play_command = fa->playcommand;
288
289 if (play_command.trimmed().isEmpty())
290 play_command = "Internal";
291
292 QString plot;
293 QString title = VideoMetadata::FilenameToMeta(filename, 1);
294 QString subtitle = VideoMetadata::FilenameToMeta(filename, 4);
295 QString director;
296 int season = 0;
297 int episode = 0;
298 QString inetref;
299 std::chrono::minutes length = 0min;
300 QString year = QString::number(VIDEO_YEAR_DEFAULT);
301 QString id;
302
303 if (extraData)
304 {
305 plot = extraData->GetPlot();
306 title = extraData->GetTitle();
307 subtitle = extraData->GetSubtitle();
308 director = extraData->GetDirector();
309 season = extraData->GetSeason();
310 episode = extraData->GetEpisode();
311 inetref = extraData->GetInetRef();
312 length = extraData->GetLength();
313 year = QString::number(extraData->GetYear());
314 id = QString::number(extraData->GetID());
315 }
316
317 AddPlayer(play_command, filename, plot, title, subtitle, director,
318 season, episode, inetref, length, year, id);
319 }
320
322 {
323 for (auto & player : m_playerProcs)
324 delete player;
325 m_playerProcs.clear();
326 }
327
328 void Play() const
329 {
330 // Do this until one of the players returns true
331 (void)std::any_of(m_playerProcs.cbegin(), m_playerProcs.cend(),
332 [](auto *player){ return player->Play(); } );
333 }
334
335 QString GetCommandDisplayName() const
336 {
337 if (!m_playerProcs.empty())
338 return m_playerProcs.front()->GetCommandDisplayName();
339 return {};
340 }
341
342 private:
343 void AddPlayer(const QString &player, const QString &filename,
344 const QString &plot, const QString &title, const QString &subtitle,
345 const QString &director, int season, int episode, const QString &inetref,
346 std::chrono::minutes length, const QString &year, const QString &id)
347 {
349 plot, title, subtitle, director, season, episode, inetref,
350 length, year, id));
352 }
353
354 private:
355 using player_list = std::vector<VideoPlayProc *>;
357};
358
360
362{
364 ret.m_d->AltPlayerFor(item);
365 return ret;
366}
367
369{
371 ret.m_d->PlayerFor(item);
372 return ret;
373}
374
376{
378 ret.m_d->PlayerFor(filename);
379 return ret;
380}
381
384{
385}
386
388{
389 delete m_d;
390 m_d = nullptr;
391}
392
394 : m_d(new VideoPlayerCommandPrivate(*other.m_d))
395{
396}
397
399{
400 if (this != &rhs)
401 {
402 delete m_d;
404 }
405 return *this;
406}
407
409{
410 LCD *lcd = LCD::Get();
411
412 if (lcd) {
413 lcd->setFunctionLEDs(FUNC_TV, false);
414 lcd->setFunctionLEDs(FUNC_MOVIE, true);
415 }
418 m_d->Play();
421 GetMythMainWindow()->raise();
422 GetMythMainWindow()->activateWindow();
423 if (lcd)
424 lcd->setFunctionLEDs(FUNC_MOVIE, false);
425}
426
428{
429 return m_d->GetCommandDisplayName();
430}
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:836
const association_list & getList() const
Definition: dbaccess.cpp:811
std::vector< file_association > association_list
Definition: dbaccess.h:154
Definition: lcddevice.h:170
static LCD * Get(void)
Definition: lcddevice.cpp:69
void setFunctionLEDs(enum LCDFunctionSet func, bool on)
Definition: lcddevice.cpp:427
void emitTVPlaybackStopped(void)
QString GetSetting(const QString &key, const QString &defaultval="")
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
bool HandleMedia(const QString &Handler, const QString &Mrl, const QString &Plot="", const QString &Title="", const QString &Subtitle="", const QString &Director="", int Season=0, int Episode=0, const QString &Inetref="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
static QString generate_file_url(const QString &storage_group, const QString &host, const QString &path)
const QString & GetHost() const
bool IsHostSet() const
int GetYear() const
const QString & GetTitle() const
static QString FilenameToMeta(const QString &file_name, int position)
unsigned int GetID() const
std::chrono::minutes GetLength() const
const QString & GetInetRef() const
const QString & GetDirector() const
const QString & GetSubtitle() const
int GetSeason() const
const QString & GetPlayCommand() const
const QString & GetPlot() const
int GetEpisode() const
const QString & GetFilename() const
VideoPlayHandleMedia * Clone() const override
QString GetCommandDisplayName() const override
VideoPlayHandleMedia(QString handler, QString mrl, QString plot, QString title, QString subtitle, QString director, int season, int episode, QString inetref, std::chrono::minutes length, QString year, QString id)
std::chrono::minutes m_length
bool Play() const override
static VideoPlayHandleMedia * Create(const QString &handler, const QString &mrl, const QString &plot, const QString &title, const QString &subtitle, const QString &director, int season, int episode, const QString &inetref, std::chrono::minutes length, const QString &year, const QString &id)
bool Play() const override
VideoPlayMythSystem(QString disp_command, QString play_command)
QString GetCommandDisplayName() const override
VideoPlayMythSystem * Clone() const override
static VideoPlayMythSystem * Create(const QString &command, const QString &filename)
VideoPlayerCommandPrivate & operator=(const VideoPlayerCommandPrivate &rhs)=delete
void AltPlayerFor(const VideoMetadata *item)
VideoPlayerCommandPrivate()=default
VideoPlayerCommandPrivate(const VideoPlayerCommandPrivate &other)
void PlayerFor(const VideoMetadata *item)
std::vector< VideoPlayProc * > player_list
void PlayerFor(const QString &filename, const VideoMetadata *extraData=nullptr)
void AddPlayer(const QString &player, const QString &filename, const QString &plot, const QString &title, const QString &subtitle, const QString &director, int season, int episode, const QString &inetref, std::chrono::minutes length, const QString &year, const QString &id)
static VideoPlayerCommand AltPlayerFor(const VideoMetadata *item)
class VideoPlayerCommandPrivate * m_d
VideoPlayerCommand & operator=(const VideoPlayerCommand &rhs)
static VideoPlayerCommand PlayerFor(const VideoMetadata *item)
QString GetCommandDisplayName() const
Returns the player command suitable for display to the user.
static guint32 * tmp
Definition: goom_core.cpp:26
@ FUNC_TV
Definition: lcddevice.h:164
@ FUNC_MOVIE
Definition: lcddevice.h:161
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythMainWindow * GetMythMainWindow(void)
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
QString ExpandPlayCommand(const QString &command, const QString &filename)
STL namespace.
virtual QString GetCommandDisplayName() const =0
VideoPlayProc()=default
VideoPlayProc & operator=(const VideoPlayProc &)
VideoPlayProc(const VideoPlayProc &)=default
virtual ~VideoPlayProc()=default
virtual VideoPlayProc * Clone() const =0
virtual bool Play() const =0
static constexpr uint16_t VIDEO_YEAR_DEFAULT
Definition: videometadata.h:18