|
MythTV
0.26-pre
|
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 }
1.7.6.1