MythTV master
videoplayercommand.cpp
Go to the documentation of this file.
1// Qt
2#include <QDir>
3
4// MythTV
14
15// MythFrontend
16#include "videoplayercommand.h"
17
18namespace
19{
20 QString ShellEscape(const QString &src)
21 {
22 return QString(src)
23 .replace("\"", "\\\"")
24 .replace("`", "\\`")
25 .replace("\\$", "\\$");
26 }
27
28 QString ExpandPlayCommand(const QString &command, const QString &filename)
29 {
30 // If handler contains %d, substitute default player command
31 // This would be used to add additional switches to the default without
32 // needing to retype the whole default command. But, if the
33 // command and the default command both contain %s, drop the %s from
34 // the default since the new command already has it
35 //
36 // example: default: mplayer -fs %s
37 // custom : %d -ao alsa9:spdif %s
38 // result : mplayer -fs -ao alsa9:spdif %s
39 QString tmp = command;
40 if (tmp.contains("%d"))
41 {
42 QString default_handler =
43 gCoreContext->GetSetting("VideoDefaultPlayer");
44 if (tmp.contains("%s") && default_handler.contains("%s"))
45 default_handler = default_handler.replace("%s", "");
46 tmp.replace("%d", default_handler);
47 }
48
49 QString arg = QString("\"%1\"").arg(ShellEscape(filename));
50
51 if (tmp.contains("%s"))
52 return tmp.replace("%s", arg);
53
54 return QString("%1 %2").arg(tmp, arg);
55 }
56}
57
59
61{
62 protected:
63 VideoPlayProc() = default;
65
66 public:
67 virtual ~VideoPlayProc() = default;
68 VideoPlayProc(const VideoPlayProc&) = default;
69
70 // returns true if item played
71 virtual bool Play() const = 0;
72
73 virtual QString GetCommandDisplayName() const = 0;
74
75 virtual VideoPlayProc *Clone() const = 0;
76};
77
79
81{
82 private:
83 VideoPlayHandleMedia(QString handler, QString mrl,
84 QString plot, QString title, QString subtitle,
85 QString director, int season, int episode, QString inetref,
86 std::chrono::minutes length, QString year, QString id) :
87 m_handler(std::move(handler)), m_mrl(std::move(mrl)),
88 m_plot(std::move(plot)), m_title(std::move(title)),
89 m_subtitle(std::move(subtitle)),
90 m_director(std::move(director)), m_season(season),
91 m_episode(episode), m_inetref(std::move(inetref)),
92 m_length(length), m_year(std::move(year)),
93 m_id(std::move(id))
94 {
95 }
96
97 public:
98 static VideoPlayHandleMedia *Create(const QString &handler,
99 const QString &mrl, const QString &plot, const QString &title,
100 const QString &subtitle, const QString &director,
101 int season, int episode, const QString &inetref,
102 std::chrono::minutes length, const QString &year, const QString &id)
103 {
104 return new VideoPlayHandleMedia(handler, mrl, plot, title, subtitle,
105 director, season, episode, inetref, length, year, id);
106 }
107
108 bool Play() const override // VideoPlayProc
109 {
113 }
114
115 QString GetCommandDisplayName() const override // VideoPlayProc
116 {
117 return m_handler;
118 }
119
120 VideoPlayHandleMedia *Clone() const override // VideoPlayProc
121 {
122 return new VideoPlayHandleMedia(*this);
123 }
124
125 private:
126 QString m_handler;
127 QString m_mrl;
128 QString m_plot;
129 QString m_title;
130 QString m_subtitle;
131 QString m_director;
134 QString m_inetref;
135 std::chrono::minutes m_length;
136 QString m_year;
137 QString m_id;
138};
139
141
143{
144 private:
145 VideoPlayMythSystem(QString disp_command,
146 QString play_command) :
147 m_displayCommand(std::move(disp_command)), m_playCommand(std::move(play_command))
148 {
149 }
150
151 public:
152 static VideoPlayMythSystem *Create(const QString &command,
153 const QString &filename)
154 {
155 return new VideoPlayMythSystem(command,
156 ExpandPlayCommand(command, filename));
157 }
158
159 bool Play() const override // VideoPlayProc
160 {
162
163 return true;
164 }
165
166 QString GetCommandDisplayName() const override // VideoPlayProc
167 {
168 return m_displayCommand;
169 }
170
171 VideoPlayMythSystem *Clone() const override // VideoPlayProc
172 {
173 return new VideoPlayMythSystem(*this);
174 }
175
176 private:
179};
180
182
184{
185 public:
187
189 {
190 auto playerclone = [](auto *player) { return player->Clone(); };
191 std::transform(other.m_playerProcs.cbegin(), other.m_playerProcs.cend(),
192 std::back_inserter(m_playerProcs), playerclone);
193 }
194
196
198 {
200 }
201
202 void AltPlayerFor(const VideoMetadata *item)
203 {
204 if (item)
205 {
206 QString play_command =
207 gCoreContext->GetSetting("mythvideo.VideoAlternatePlayer");
208 QString filename;
209
210 if (item->IsHostSet())
211 {
213 item->GetFilename());
214 }
215 else
216 {
217 filename = item->GetFilename();
218 }
219
220 if (!play_command.isEmpty())
221 {
222 AddPlayer(play_command, filename, item->GetPlot(),
223 item->GetTitle(), item->GetSubtitle(),
224 item->GetDirector(), item->GetSeason(),
225 item->GetEpisode(), item->GetInetRef(),
226 item->GetLength(), QString::number(item->GetYear()),
227 QString::number(item->GetID()));
228 }
229 else
230 {
231 PlayerFor(filename, item);
232 }
233 }
234 }
235
236 void PlayerFor(const VideoMetadata *item)
237 {
238 if (item)
239 {
240 const QString& play_command = item->GetPlayCommand();
241 QString filename;
242
243 if (item->IsHostSet())
244 {
246 item->GetFilename());
247 }
248 else
249 {
250 filename = item->GetFilename();
251 }
252
253 if (!play_command.isEmpty())
254 {
255 AddPlayer(play_command, filename, item->GetPlot(),
256 item->GetTitle(), item->GetSubtitle(),
257 item->GetDirector(), item->GetSeason(),
258 item->GetEpisode(), item->GetInetRef(),
259 item->GetLength(), QString::number(item->GetYear()),
260 QString::number(item->GetID()));
261 }
262 else
263 {
264 PlayerFor(filename, item);
265 }
266 }
267 }
268
269 void PlayerFor(const QString &filename, const VideoMetadata *extraData = nullptr)
270 {
271 QString extension = filename.section(".", -1, -1);
272 QDir dir_test(QString("%1/VIDEO_TS").arg(filename));
273 if (dir_test.exists())
274 extension = "VIDEO_TS";
275 QDir bd_dir_test(QString("%1/BDMV").arg(filename));
276 if (bd_dir_test.exists())
277 extension = "BDMV";
278
279 QString play_command = gCoreContext->GetSetting("VideoDefaultPlayer");
280
283 auto sameext = [extension](const auto & fa)
284 { return fa.extension.toLower() == extension.toLower() &&
285 !fa.use_default; };
286 auto fa = std::find_if(fa_list.cbegin(), fa_list.cend(), sameext);
287 if (fa != fa_list.cend())
288 play_command = fa->playcommand;
289
290 if (play_command.trimmed().isEmpty())
291 play_command = "Internal";
292
293 QString plot;
294 QString title = VideoMetadata::FilenameToMeta(filename, 1);
295 QString subtitle = VideoMetadata::FilenameToMeta(filename, 4);
296 QString director;
297 int season = 0;
298 int episode = 0;
299 QString inetref;
300 std::chrono::minutes length = 0min;
301 QString year = QString::number(VIDEO_YEAR_DEFAULT);
302 QString id;
303
304 if (extraData)
305 {
306 plot = extraData->GetPlot();
307 title = extraData->GetTitle();
308 subtitle = extraData->GetSubtitle();
309 director = extraData->GetDirector();
310 season = extraData->GetSeason();
311 episode = extraData->GetEpisode();
312 inetref = extraData->GetInetRef();
313 length = extraData->GetLength();
314 year = QString::number(extraData->GetYear());
315 id = QString::number(extraData->GetID());
316 }
317
318 AddPlayer(play_command, filename, plot, title, subtitle, director,
319 season, episode, inetref, length, year, id);
320 }
321
323 {
324 for (auto & player : m_playerProcs)
325 delete player;
326 m_playerProcs.clear();
327 }
328
329 void Play() const
330 {
331 // Do this until one of the players returns true
332 (void)std::any_of(m_playerProcs.cbegin(), m_playerProcs.cend(),
333 [](auto *player){ return player->Play(); } );
334 }
335
336 QString GetCommandDisplayName() const
337 {
338 if (!m_playerProcs.empty())
339 return m_playerProcs.front()->GetCommandDisplayName();
340 return {};
341 }
342
343 private:
344 void AddPlayer(const QString &player, const QString &filename,
345 const QString &plot, const QString &title, const QString &subtitle,
346 const QString &director, int season, int episode, const QString &inetref,
347 std::chrono::minutes length, const QString &year, const QString &id)
348 {
350 plot, title, subtitle, director, season, episode, inetref,
351 length, year, id));
353 }
354
355 private:
356 using player_list = std::vector<VideoPlayProc *>;
358};
359
361
363{
365 ret.m_d->AltPlayerFor(item);
366 return ret;
367}
368
370{
372 ret.m_d->PlayerFor(item);
373 return ret;
374}
375
377{
379 ret.m_d->PlayerFor(filename);
380 return ret;
381}
382
385{
386}
387
389{
390 delete m_d;
391 m_d = nullptr;
392}
393
395 : m_d(new VideoPlayerCommandPrivate(*other.m_d))
396{
397}
398
400{
401 if (this != &rhs)
402 {
403 delete m_d;
405 }
406 return *this;
407}
408
410{
411 LCD *lcd = LCD::Get();
412
413 if (lcd) {
414 lcd->setFunctionLEDs(FUNC_TV, false);
415 lcd->setFunctionLEDs(FUNC_MOVIE, true);
416 }
419 m_d->Play();
422 GetMythMainWindow()->raise();
423 GetMythMainWindow()->activateWindow();
424 if (lcd)
425 lcd->setFunctionLEDs(FUNC_MOVIE, false);
426}
427
429{
430 return m_d->GetCommandDisplayName();
431}
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