MythTV  master
videoplayercommand.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QDir>
3 
4 // MythTV
5 #include "libmyth/mythcontext.h"
14 
15 // MythFrontend
16 #include "videoplayercommand.h"
17 
18 namespace
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;
132  int m_season;
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:
178  QString m_playCommand;
179 };
180 
182 
184 {
185  public:
186  VideoPlayerCommandPrivate() = default;
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  {
199  ClearPlayerList();
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  {
212  filename = generate_file_url("Videos", item->GetHost(),
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  QString play_command = item->GetPlayCommand();
241  QString filename;
242 
243  if (item->IsHostSet())
244  {
245  filename = generate_file_url("Videos", item->GetHost(),
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 
281  const FileAssociations::association_list fa_list =
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 {
364  VideoPlayerCommand ret;
365  ret.m_d->AltPlayerFor(item);
366  return ret;
367 }
368 
370 {
371  VideoPlayerCommand ret;
372  ret.m_d->PlayerFor(item);
373  return ret;
374 }
375 
377 {
378  VideoPlayerCommand ret;
379  ret.m_d->PlayerFor(filename);
380  return ret;
381 }
382 
384 {
386 }
387 
389 {
390  delete m_d;
391  m_d = nullptr;
392 }
393 
395 {
396  m_d = new VideoPlayerCommandPrivate(*other.m_d);
397 }
398 
400 {
401  if (this != &rhs)
402  {
403  delete m_d;
404  m_d = new VideoPlayerCommandPrivate(*rhs.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  }
417  gCoreContext->WantingPlayback(nullptr);
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 }
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:24
VideoPlayProc::VideoPlayProc
VideoPlayProc()=default
FUNC_TV
@ FUNC_TV
Definition: lcddevice.h:168
VideoPlayHandleMedia
Definition: videoplayercommand.cpp:80
VideoMetadata::FilenameToMeta
static QString FilenameToMeta(const QString &file_name, int position)
Definition: videometadata.cpp:1141
VideoPlayHandleMedia::m_episode
int m_episode
Definition: videoplayercommand.cpp:133
VideoPlayHandleMedia::GetCommandDisplayName
QString GetCommandDisplayName() const override
Definition: videoplayercommand.cpp:115
videometadata.h
VideoMetadata::GetHost
const QString & GetHost() const
Definition: videometadata.cpp:1836
VideoPlayProc::operator=
VideoPlayProc & operator=(const VideoPlayProc &)
MythCoreContext::emitTVPlaybackStopped
void emitTVPlaybackStopped(void)
Definition: mythcorecontext.h:289
VideoPlayHandleMedia::m_title
QString m_title
Definition: videoplayercommand.cpp:129
VideoPlayProc::GetCommandDisplayName
virtual QString GetCommandDisplayName() const =0
VideoPlayProc::Clone
virtual VideoPlayProc * Clone() const =0
VideoPlayerCommandPrivate::Play
void Play() const
Definition: videoplayercommand.cpp:329
VideoPlayerCommand::Play
void Play() const
Definition: videoplayercommand.cpp:409
VideoPlayHandleMedia::Play
bool Play() const override
Definition: videoplayercommand.cpp:108
VideoPlayerCommandPrivate::ClearPlayerList
void ClearPlayerList()
Definition: videoplayercommand.cpp:322
VideoMetadata::GetPlayCommand
const QString & GetPlayCommand() const
Definition: videometadata.cpp:1796
VideoMetadata::GetSeason
int GetSeason() const
Definition: videometadata.cpp:1706
VideoPlayHandleMedia::m_inetref
QString m_inetref
Definition: videoplayercommand.cpp:134
FileAssociations::getList
const association_list & getList() const
Definition: dbaccess.cpp:806
VideoPlayHandleMedia::m_director
QString m_director
Definition: videoplayercommand.cpp:131
VideoPlayMythSystem::Play
bool Play() const override
Definition: videoplayercommand.cpp:159
VideoPlayerCommandPrivate::~VideoPlayerCommandPrivate
~VideoPlayerCommandPrivate()
Definition: videoplayercommand.cpp:197
myth_system
uint myth_system(const QString &command, uint flags, std::chrono::seconds timeout)
Definition: mythsystemlegacy.cpp:506
remoteutil.h
VideoPlayerCommandPrivate::AltPlayerFor
void AltPlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:202
VideoPlayProc::~VideoPlayProc
virtual ~VideoPlayProc()=default
VideoMetadata::GetDirector
const QString & GetDirector() const
Definition: videometadata.cpp:1636
VideoPlayerCommandPrivate
Definition: videoplayercommand.cpp:183
LCD::Get
static LCD * Get(void)
Definition: lcddevice.cpp:69
VideoPlayMythSystem
Definition: videoplayercommand.cpp:142
VideoMetadata::GetPlot
const QString & GetPlot() const
Definition: videometadata.cpp:1656
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="", std::chrono::minutes LenMins=2h, const QString &Year="1895", const QString &Id="", bool UseBookmarks=false)
Definition: mythmainwindow.cpp:1489
VideoPlayerCommandPrivate::VideoPlayerCommandPrivate
VideoPlayerCommandPrivate(const VideoPlayerCommandPrivate &other)
Definition: videoplayercommand.cpp:188
VideoMetadata::GetSubtitle
const QString & GetSubtitle() const
Definition: videometadata.cpp:1561
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
dbaccess.h
mythsystemlegacy.h
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, std::chrono::minutes length, const QString &year, const QString &id)
Definition: videoplayercommand.cpp:98
VideoPlayerCommandPrivate::PlayerFor
void PlayerFor(const QString &filename, const VideoMetadata *extraData=nullptr)
Definition: videoplayercommand.cpp:269
VideoPlayHandleMedia::m_mrl
QString m_mrl
Definition: videoplayercommand.cpp:127
FUNC_MOVIE
@ FUNC_MOVIE
Definition: lcddevice.h:165
VideoMetadata::GetFilename
const QString & GetFilename() const
Definition: videometadata.cpp:1816
VideoMetadata::GetInetRef
const QString & GetInetRef() const
Definition: videometadata.cpp:1606
VideoPlayHandleMedia::m_season
int m_season
Definition: videoplayercommand.cpp:132
VideoPlayHandleMedia::m_handler
QString m_handler
Definition: videoplayercommand.cpp:126
VideoPlayHandleMedia::VideoPlayHandleMedia
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)
Definition: videoplayercommand.cpp:83
VideoPlayProc
Definition: videoplayercommand.cpp:60
VideoPlayerCommand::m_d
class VideoPlayerCommandPrivate * m_d
Definition: videoplayercommand.h:25
VideoPlayerCommand
Definition: videoplayercommand.h:5
VideoPlayerCommand::VideoPlayerCommand
VideoPlayerCommand()
Definition: videoplayercommand.cpp:383
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:336
VideoPlayerCommandPrivate::m_playerProcs
player_list m_playerProcs
Definition: videoplayercommand.cpp:357
VideoPlayMythSystem::m_displayCommand
QString m_displayCommand
Definition: videoplayercommand.cpp:177
VideoMetadata::GetYear
int GetYear() const
Definition: videometadata.cpp:1586
VideoPlayMythSystem::Create
static VideoPlayMythSystem * Create(const QString &command, const QString &filename)
Definition: videoplayercommand.cpp:152
VideoPlayMythSystem::Clone
VideoPlayMythSystem * Clone() const override
Definition: videoplayercommand.cpp:171
VideoPlayProc::Play
virtual bool Play() const =0
VideoMetadata::GetEpisode
int GetEpisode() const
Definition: videometadata.cpp:1716
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:54
VideoPlayerCommandPrivate::operator=
VideoPlayerCommandPrivate & operator=(const VideoPlayerCommandPrivate &rhs)=delete
VideoPlayerCommandPrivate::PlayerFor
void PlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:236
VideoPlayerCommand::GetCommandDisplayName
QString GetCommandDisplayName() const
Returns the player command suitable for display to the user.
Definition: videoplayercommand.cpp:428
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, std::chrono::minutes length, const QString &year, const QString &id)
Definition: videoplayercommand.cpp:344
VideoPlayerCommandPrivate::player_list
std::vector< VideoPlayProc * > player_list
Definition: videoplayercommand.cpp:356
FileAssociations::getFileAssociation
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:831
VideoPlayHandleMedia::m_plot
QString m_plot
Definition: videoplayercommand.cpp:128
VideoPlayerCommand::AltPlayerFor
static VideoPlayerCommand AltPlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:362
VideoPlayMythSystem::VideoPlayMythSystem
VideoPlayMythSystem(QString disp_command, QString play_command)
Definition: videoplayercommand.cpp:145
mythmiscutil.h
VideoMetadata::IsHostSet
bool IsHostSet() const
Definition: videometadata.cpp:2009
VideoPlayHandleMedia::m_length
std::chrono::minutes m_length
Definition: videoplayercommand.cpp:135
std
Definition: mythchrono.h:23
VideoPlayMythSystem::GetCommandDisplayName
QString GetCommandDisplayName() const override
Definition: videoplayercommand.cpp:166
mythcontext.h
VideoMetadata::GetLength
std::chrono::minutes GetLength() const
Definition: videometadata.cpp:1686
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
VideoPlayHandleMedia::m_subtitle
QString m_subtitle
Definition: videoplayercommand.cpp:130
VideoMetadata::GetID
unsigned int GetID() const
Definition: videometadata.cpp:1736
VIDEO_YEAR_DEFAULT
@ VIDEO_YEAR_DEFAULT
Definition: videometadata.h:18
VideoMetadata::GetTitle
const QString & GetTitle() const
Definition: videometadata.cpp:1546
VideoPlayHandleMedia::m_year
QString m_year
Definition: videoplayercommand.cpp:136
MythCoreContext::WantingPlayback
void WantingPlayback(QObject *sender)
All the objects that have registered using MythCoreContext::RegisterForPlayback but sender will be ca...
Definition: mythcorecontext.cpp:1947
VideoPlayerCommand::PlayerFor
static VideoPlayerCommand PlayerFor(const VideoMetadata *item)
Definition: videoplayercommand.cpp:369
LCD::setFunctionLEDs
void setFunctionLEDs(enum LCDFunctionSet func, bool on)
Definition: lcddevice.cpp:431
lcddevice.h
build_compdb.filename
filename
Definition: build_compdb.py:21
mythmainwindow.h
VideoPlayerCommand::~VideoPlayerCommand
~VideoPlayerCommand()
Definition: videoplayercommand.cpp:388
VideoPlayHandleMedia::Clone
VideoPlayHandleMedia * Clone() const override
Definition: videoplayercommand.cpp:120
videoutils.h
LCD
Definition: lcddevice.h:173
VideoPlayerCommand::operator=
VideoPlayerCommand & operator=(const VideoPlayerCommand &rhs)
Definition: videoplayercommand.cpp:399
MythMainWindow::PauseIdleTimer
void PauseIdleTimer(bool Pause)
Pause the idle timeout timer.
Definition: mythmainwindow.cpp:2146
videoplayercommand.h
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:896
VideoPlayMythSystem::m_playCommand
QString m_playCommand
Definition: videoplayercommand.cpp:178
VideoPlayHandleMedia::m_id
QString m_id
Definition: videoplayercommand.cpp:137