MythTV  0.26-pre
videoplayercommand.cpp
Go to the documentation of this file.
00001 #include <QDir>
00002 
00003 #include "mythcontext.h"
00004 
00005 #include "mythmainwindow.h"
00006 #include "mythsystem.h"
00007 #include "remoteutil.h"
00008 #include "lcddevice.h"
00009 #include "mythmiscutil.h"
00010 #include "dbaccess.h"
00011 #include "videometadata.h"
00012 #include "videoutils.h"
00013 
00014 #include "videoplayercommand.h"
00015 
00016 namespace
00017 {
00018     QString ShellEscape(const QString &src)
00019     {
00020         return QString(src)
00021                 .replace(QRegExp("\""), "\\\"")
00022                 .replace(QRegExp("`"), "\\`")
00023                 .replace(QRegExp("\\$"), "\\$");
00024     }
00025 
00026     QString ExpandPlayCommand(const QString &command, const QString &filename)
00027     {
00028         // If handler contains %d, substitute default player command
00029         // This would be used to add additional switches to the default without
00030         // needing to retype the whole default command.  But, if the
00031         // command and the default command both contain %s, drop the %s from
00032         // the default since the new command already has it
00033         //
00034         // example: default: mplayer -fs %s
00035         //          custom : %d -ao alsa9:spdif %s
00036         //          result : mplayer -fs -ao alsa9:spdif %s
00037         QString tmp = command;
00038         if (tmp.contains("%d"))
00039         {
00040             QString default_handler =
00041                     gCoreContext->GetSetting("VideoDefaultPlayer");
00042             if (tmp.contains("%s") && default_handler.contains("%s"))
00043                 default_handler = default_handler.replace(QRegExp("%s"), "");
00044             tmp.replace(QRegExp("%d"), default_handler);
00045         }
00046 
00047         QString arg = QString("\"%1\"").arg(ShellEscape(filename));
00048 
00049         if (tmp.contains("%s"))
00050             return tmp.replace(QRegExp("%s"), arg);
00051 
00052         return QString("%1 %2").arg(tmp).arg(arg);
00053     }
00054 }
00055 
00057 
00058 struct VideoPlayProc
00059 {
00060   protected:
00061     VideoPlayProc() {}
00062     VideoPlayProc &operator=(const VideoPlayProc &);
00063 
00064   public:
00065     virtual ~VideoPlayProc() {}
00066 
00067     // returns true if item played
00068     virtual bool Play() const = 0;
00069 
00070     virtual QString GetCommandDisplayName() const = 0;
00071 
00072     virtual VideoPlayProc *Clone() const = 0;
00073 };
00074 
00076 
00077 class VideoPlayHandleMedia : public VideoPlayProc
00078 {
00079   private:
00080     VideoPlayHandleMedia(const QString &handler, const QString &mrl,
00081             const QString &plot, const QString &title, const QString &subtitle,
00082             const QString &director, int season, int episode, const QString &inetref,
00083             int length, const QString &year, const QString &id) :
00084         m_handler(handler), m_mrl(mrl), m_plot(plot), m_title(title),
00085         m_subtitle(subtitle), m_director(director), m_season(season),
00086         m_episode(episode), m_inetref(inetref), m_length(length), m_year(year),
00087         m_id(id)
00088     {
00089     }
00090 
00091   public:
00092     static VideoPlayHandleMedia *Create(const QString &handler,
00093             const QString &mrl, const QString &plot, const QString &title,
00094             const QString &subtitle, const QString &director,
00095             int season, int episode, const QString &inetref,
00096             int length, const QString &year, const QString &id)
00097     {
00098         return new VideoPlayHandleMedia(handler, mrl, plot, title, subtitle,
00099                 director, season, episode, inetref, length, year, id);
00100     }
00101 
00102     bool Play() const
00103     {
00104         return GetMythMainWindow()->HandleMedia(m_handler, m_mrl,
00105                 m_plot, m_title, m_subtitle, m_director, m_season,
00106                 m_episode, m_inetref, m_length, m_year, m_id, true);
00107     }
00108 
00109     QString GetCommandDisplayName() const
00110     {
00111         return m_handler;
00112     }
00113 
00114     VideoPlayHandleMedia *Clone() const
00115     {
00116         return new VideoPlayHandleMedia(*this);
00117     }
00118 
00119   private:
00120     QString m_handler;
00121     QString m_mrl;
00122     QString m_plot;
00123     QString m_title;
00124     QString m_subtitle;
00125     QString m_director;
00126     int m_season;
00127     int m_episode;
00128     QString m_inetref;
00129     int m_length;
00130     QString m_year;
00131     QString m_id;
00132 };
00133 
00135 
00136 class VideoPlayMythSystem : public VideoPlayProc
00137 {
00138   private:
00139     VideoPlayMythSystem(const QString &disp_command,
00140             const QString &play_command) :
00141         m_display_command(disp_command), m_play_command(play_command)
00142     {
00143     }
00144 
00145   public:
00146     static VideoPlayMythSystem *Create(const QString &command,
00147             const QString &filename)
00148     {
00149         return new VideoPlayMythSystem(command,
00150                 ExpandPlayCommand(command, filename));
00151     }
00152 
00153     bool Play() const
00154     {
00155         sendPlaybackStart();
00156         GetMythMainWindow()->PauseIdleTimer(true);
00157         myth_system(m_play_command);
00158         sendPlaybackEnd();
00159         GetMythMainWindow()->PauseIdleTimer(false);
00160 
00161         return true;
00162     }
00163 
00164     QString GetCommandDisplayName() const
00165     {
00166         return m_display_command;
00167     }
00168 
00169     VideoPlayMythSystem *Clone() const
00170     {
00171         return new VideoPlayMythSystem(*this);
00172     }
00173 
00174   private:
00175     QString m_display_command;
00176     QString m_play_command;
00177 };
00178 
00180 
00181 class VideoPlayerCommandPrivate
00182 {
00183   private:
00184     VideoPlayerCommandPrivate &operator=(const VideoPlayerCommandPrivate &rhs);
00185 
00186   public:
00187     VideoPlayerCommandPrivate() {}
00188 
00189     VideoPlayerCommandPrivate(const VideoPlayerCommandPrivate &other)
00190     {
00191         for (player_list::const_iterator p = other.m_player_procs.begin();
00192                 p != other.m_player_procs.end(); ++p)
00193         {
00194             m_player_procs.push_back((*p)->Clone());
00195         }
00196     }
00197 
00198     ~VideoPlayerCommandPrivate()
00199     {
00200         ClearPlayerList();
00201     }
00202 
00203     void AltPlayerFor(const VideoMetadata *item)
00204     {
00205         if (item)
00206         {
00207             QString play_command =
00208                    gCoreContext->GetSetting("mythvideo.VideoAlternatePlayer");
00209             QString filename;
00210 
00211             if (item->IsHostSet())
00212                 filename = generate_file_url("Videos", item->GetHost(),
00213                         item->GetFilename());
00214             else
00215                 filename = item->GetFilename();
00216 
00217             if (play_command.length())
00218             {
00219                 AddPlayer(play_command, filename, item->GetPlot(),
00220                         item->GetTitle(), item->GetSubtitle(),
00221                         item->GetDirector(), item->GetSeason(),
00222                         item->GetEpisode(), item->GetInetRef(),
00223                         item->GetLength(), QString::number(item->GetYear()),
00224                         QString::number(item->GetID()));
00225             }
00226             else
00227             {
00228                 PlayerFor(filename, item);
00229             }
00230         }
00231     }
00232 
00233     void PlayerFor(const VideoMetadata *item)
00234     {
00235         if (item)
00236         {
00237             QString play_command = item->GetPlayCommand();
00238             QString filename;
00239 
00240             if (item->IsHostSet())
00241                 filename = generate_file_url("Videos", item->GetHost(),
00242                         item->GetFilename());
00243             else
00244                 filename = item->GetFilename();
00245 
00246             if (play_command.length())
00247             {
00248                 AddPlayer(play_command, filename, item->GetPlot(),
00249                         item->GetTitle(), item->GetSubtitle(),
00250                         item->GetDirector(), item->GetSeason(),
00251                         item->GetEpisode(), item->GetInetRef(),
00252                         item->GetLength(), QString::number(item->GetYear()),
00253                         QString::number(item->GetID()));
00254             }
00255             else
00256             {
00257                 PlayerFor(filename, item);
00258             }
00259         }
00260     }
00261 
00262     void PlayerFor(const QString &filename, const VideoMetadata *extraData = 0)
00263     {
00264         QString extension = filename.section(".", -1, -1);
00265         QDir dir_test(QString("%1/VIDEO_TS").arg(filename));
00266         if (dir_test.exists())
00267             extension = "VIDEO_TS";
00268         QDir bd_dir_test(QString("%1/BDMV").arg(filename));
00269         if (bd_dir_test.exists())
00270             extension = "BDMV";
00271 
00272         QString play_command = gCoreContext->GetSetting("VideoDefaultPlayer");
00273 
00274         const FileAssociations::association_list fa_list =
00275                 FileAssociations::getFileAssociation().getList();
00276         for (FileAssociations::association_list::const_iterator p =
00277                 fa_list.begin(); p != fa_list.end(); ++p)
00278         {
00279             if (p->extension.toLower() == extension.toLower() &&
00280                     !p->use_default)
00281             {
00282                 play_command = p->playcommand;
00283                 break;
00284             }
00285         }
00286 
00287         if (play_command.trimmed().isEmpty())
00288             play_command = "Internal";
00289 
00290         QString plot;
00291         QString title = VideoMetadata::FilenameToMeta(filename, 1);
00292         QString subtitle = VideoMetadata::FilenameToMeta(filename, 4);
00293         QString director;
00294         int season = 0;
00295         int episode = 0;
00296         QString inetref;
00297         int length = 0;
00298         QString year = QString::number(VIDEO_YEAR_DEFAULT);
00299         QString id;
00300 
00301         if (extraData)
00302         {
00303             plot = extraData->GetPlot();
00304             title = extraData->GetTitle();
00305             subtitle = extraData->GetSubtitle();
00306             director = extraData->GetDirector();
00307             season = extraData->GetSeason();
00308             episode = extraData->GetEpisode();
00309             inetref = extraData->GetInetRef();
00310             length = extraData->GetLength();
00311             year = QString::number(extraData->GetYear());
00312             id = QString::number(extraData->GetID());
00313         }
00314 
00315         AddPlayer(play_command, filename, plot, title, subtitle, director,
00316                                 season, episode, inetref, length, year, id);
00317     }
00318 
00319     void ClearPlayerList()
00320     {
00321         for (player_list::iterator p = m_player_procs.begin();
00322                         p != m_player_procs.end(); ++p)
00323         {
00324             delete *p;
00325         }
00326         m_player_procs.clear();
00327     }
00328 
00329     void Play() const
00330     {
00331         for (player_list::const_iterator p = m_player_procs.begin();
00332                 p != m_player_procs.end(); ++p)
00333         {
00334             if ((*p)->Play()) break;
00335         }
00336     }
00337 
00338     QString GetCommandDisplayName() const
00339     {
00340         if (!m_player_procs.empty())
00341             return m_player_procs.front()->GetCommandDisplayName();
00342         return QString();
00343     }
00344 
00345   private:
00346     void AddPlayer(const QString &player, const QString &filename,
00347             const QString &plot, const QString &title, const QString &subtitle,
00348             const QString &director, int season, int episode, const QString &inetref,
00349             int length, const QString &year, const QString &id)
00350     {
00351         m_player_procs.push_back(VideoPlayHandleMedia::Create(player, filename,
00352                         plot, title, subtitle, director, season, episode, inetref,
00353                         length, year, id));
00354         m_player_procs.push_back(VideoPlayMythSystem::Create(player, filename));
00355     }
00356 
00357   private:
00358     typedef std::vector<VideoPlayProc *> player_list;
00359     player_list m_player_procs;
00360 };
00361 
00363 
00364 VideoPlayerCommand VideoPlayerCommand::AltPlayerFor(const VideoMetadata *item)
00365 {
00366     VideoPlayerCommand ret;
00367     ret.m_d->AltPlayerFor(item);
00368     return ret;
00369 }
00370 
00371 VideoPlayerCommand VideoPlayerCommand::PlayerFor(const VideoMetadata *item)
00372 {
00373     VideoPlayerCommand ret;
00374     ret.m_d->PlayerFor(item);
00375     return ret;
00376 }
00377 
00378 VideoPlayerCommand VideoPlayerCommand::PlayerFor(const QString &filename)
00379 {
00380     VideoPlayerCommand ret;
00381     ret.m_d->PlayerFor(filename);
00382     return ret;
00383 }
00384 
00385 VideoPlayerCommand::VideoPlayerCommand() : m_d(0)
00386 {
00387     m_d = new VideoPlayerCommandPrivate;
00388 }
00389 
00390 VideoPlayerCommand::~VideoPlayerCommand()
00391 {
00392     delete m_d;
00393     m_d = 0;
00394 }
00395 
00396 VideoPlayerCommand::VideoPlayerCommand(const VideoPlayerCommand &other)
00397 {
00398     m_d = new VideoPlayerCommandPrivate(*other.m_d);
00399 }
00400 
00401 VideoPlayerCommand &VideoPlayerCommand::operator=(const VideoPlayerCommand &rhs)
00402 {
00403     if (this != &rhs)
00404     {
00405         delete m_d;
00406         m_d = new VideoPlayerCommandPrivate(*rhs.m_d);
00407     }
00408     return *this;
00409 }
00410 
00411 void VideoPlayerCommand::Play() const
00412 {
00413     LCD *lcd = LCD::Get();
00414 
00415     if (lcd) {
00416         lcd->setFunctionLEDs(FUNC_TV, false);
00417         lcd->setFunctionLEDs(FUNC_MOVIE, true);
00418     }
00419     m_d->Play();
00420     GetMythMainWindow()->raise();
00421     GetMythMainWindow()->activateWindow();
00422     if (GetMythMainWindow()->currentWidget())
00423         GetMythMainWindow()->currentWidget()->setFocus();
00424     if (lcd)
00425         lcd->setFunctionLEDs(FUNC_MOVIE, false);
00426 }
00427 
00428 QString VideoPlayerCommand::GetCommandDisplayName() const
00429 {
00430     return m_d->GetCommandDisplayName();
00431 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends