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