nathan@0
|
1 |
/*
|
nathan@0
|
2 |
* MP3/MPlayer plugin to VDR (C++)
|
nathan@0
|
3 |
*
|
nathan@0
|
4 |
* (C) 2001-2007 Stefan Huelswitt <s.huelswitt@gmx.de>
|
nathan@0
|
5 |
*
|
nathan@0
|
6 |
* This code is free software; you can redistribute it and/or
|
nathan@0
|
7 |
* modify it under the terms of the GNU General Public License
|
nathan@0
|
8 |
* as published by the Free Software Foundation; either version 2
|
nathan@0
|
9 |
* of the License, or (at your option) any later version.
|
nathan@0
|
10 |
*
|
nathan@0
|
11 |
* This code is distributed in the hope that it will be useful,
|
nathan@0
|
12 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
nathan@0
|
13 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
nathan@0
|
14 |
* GNU General Public License for more details.
|
nathan@0
|
15 |
*
|
nathan@0
|
16 |
* You should have received a copy of the GNU General Public License
|
nathan@0
|
17 |
* along with this program; if not, write to the Free Software
|
nathan@0
|
18 |
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
nathan@0
|
19 |
* Or, point your browser to http://www.gnu.org/copyleft/gpl.html
|
nathan@0
|
20 |
*/
|
nathan@0
|
21 |
|
nathan@0
|
22 |
#include <getopt.h>
|
nathan@0
|
23 |
#include <malloc.h>
|
nathan@0
|
24 |
#include <stdlib.h>
|
nathan@0
|
25 |
#include <ctype.h>
|
nathan@0
|
26 |
|
nathan@0
|
27 |
#include "common.h"
|
nathan@0
|
28 |
|
nathan@0
|
29 |
#include <vdr/plugin.h>
|
nathan@0
|
30 |
#include <vdr/player.h>
|
nathan@0
|
31 |
#include <vdr/status.h>
|
nathan@0
|
32 |
#include <vdr/font.h>
|
nathan@0
|
33 |
#include <vdr/osdbase.h>
|
nathan@0
|
34 |
#include <vdr/menuitems.h>
|
nathan@0
|
35 |
#ifdef HAVE_BEAUTYPATCH
|
nathan@0
|
36 |
#include <vdr/fontsym.h>
|
nathan@0
|
37 |
#endif
|
nathan@0
|
38 |
#if APIVERSNUM >= 10307
|
nathan@0
|
39 |
#include <vdr/skins.h>
|
nathan@0
|
40 |
#endif
|
nathan@0
|
41 |
#if APIVERSNUM >= 10332
|
nathan@0
|
42 |
#include <vdr/remote.h>
|
nathan@0
|
43 |
#endif
|
nathan@0
|
44 |
|
nathan@0
|
45 |
#if APIVERSNUM > 10307
|
nathan@0
|
46 |
#include <vdr/menu.h>
|
nathan@0
|
47 |
#elif APIVERSNUM == 10307
|
nathan@0
|
48 |
class cMenuText : public cOsdMenu {
|
nathan@0
|
49 |
private:
|
nathan@0
|
50 |
char *text;
|
nathan@0
|
51 |
public:
|
nathan@0
|
52 |
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
|
nathan@0
|
53 |
virtual ~cMenuText();
|
nathan@0
|
54 |
void SetText(const char *Text);
|
nathan@0
|
55 |
virtual void Display(void);
|
nathan@0
|
56 |
virtual eOSState ProcessKey(eKeys Key);
|
nathan@0
|
57 |
};
|
nathan@0
|
58 |
#else
|
nathan@0
|
59 |
class cMenuText : public cOsdMenu {
|
nathan@0
|
60 |
public:
|
nathan@0
|
61 |
cMenuText(const char *Title, const char *Text, eDvbFont Font = fontOsd);
|
nathan@0
|
62 |
virtual eOSState ProcessKey(eKeys Key);
|
nathan@0
|
63 |
};
|
nathan@0
|
64 |
#endif
|
nathan@0
|
65 |
|
nathan@0
|
66 |
#include "setup.h"
|
nathan@0
|
67 |
#include "setup-mplayer.h"
|
nathan@0
|
68 |
#include "menu.h"
|
nathan@0
|
69 |
#include "player-mplayer.h"
|
nathan@0
|
70 |
#include "data.h"
|
nathan@0
|
71 |
#include "data-src.h"
|
nathan@0
|
72 |
#include "i18n.h"
|
nathan@0
|
73 |
#include "version.h"
|
nathan@0
|
74 |
#include "service.h"
|
nathan@0
|
75 |
|
nathan@0
|
76 |
const char *sourcesSub=0;
|
nathan@0
|
77 |
cFileSources MPlaySources;
|
nathan@0
|
78 |
|
nathan@2
|
79 |
static const char *plugin_name=0;
|
nathan@12
|
80 |
const char *i18n_name=0;
|
nathan@2
|
81 |
|
nathan@0
|
82 |
// --- cMenuSetupMPlayer --------------------------------------------------------
|
nathan@0
|
83 |
|
nathan@0
|
84 |
class cMenuSetupMPlayer : public cMenuSetupPage {
|
nathan@0
|
85 |
private:
|
nathan@0
|
86 |
cMPlayerSetup data;
|
nathan@0
|
87 |
const char *res[3];
|
nathan@0
|
88 |
protected:
|
nathan@0
|
89 |
virtual void Store(void);
|
nathan@0
|
90 |
public:
|
nathan@0
|
91 |
cMenuSetupMPlayer(void);
|
nathan@0
|
92 |
};
|
nathan@0
|
93 |
|
nathan@0
|
94 |
cMenuSetupMPlayer::cMenuSetupMPlayer(void)
|
nathan@0
|
95 |
{
|
nathan@0
|
96 |
data=MPlayerSetup;
|
nathan@0
|
97 |
SetSection(tr("MPlayer"));
|
nathan@0
|
98 |
Add(new cMenuEditBoolItem(tr("Setup.MPlayer$Control mode"), &data.SlaveMode, tr("Traditional"), tr("Slave")));
|
nathan@0
|
99 |
#if APIVERSNUM < 10307
|
nathan@0
|
100 |
Add(new cMenuEditIntItem( tr("Setup.MPlayer$OSD position"), &data.OsdPos, 0, 6));
|
nathan@0
|
101 |
#endif
|
nathan@0
|
102 |
res[0]=tr("disabled");
|
nathan@0
|
103 |
res[1]=tr("global only");
|
nathan@0
|
104 |
res[2]=tr("local first");
|
nathan@0
|
105 |
Add(new cMenuEditStraItem(tr("Setup.MPlayer$Resume mode"), &data.ResumeMode, 3, res));
|
nathan@0
|
106 |
Add(new cMenuEditBoolItem(tr("Hide mainmenu entry"), &data.HideMainMenu));
|
nathan@0
|
107 |
for(int i=0; i<10; i++) {
|
nathan@0
|
108 |
char name[32];
|
nathan@0
|
109 |
snprintf(name,sizeof(name),"%s %d",tr("Setup.MPlayer$Slave command key"),i);
|
nathan@0
|
110 |
static const char allowed[] = { "abcdefghijklmnopqrstuvwxyz0123456789!\"§$%&/()=?{}[]\\+*~#',;.:-_<>|@´`^°" };
|
nathan@0
|
111 |
Add(new cMenuEditStrItem(name, data.KeyCmd[i],MAX_KEYCMD,allowed));
|
nathan@0
|
112 |
}
|
nathan@0
|
113 |
}
|
nathan@0
|
114 |
|
nathan@0
|
115 |
void cMenuSetupMPlayer::Store(void)
|
nathan@0
|
116 |
{
|
nathan@0
|
117 |
MPlayerSetup=data;
|
nathan@0
|
118 |
SetupStore("ControlMode", MPlayerSetup.SlaveMode);
|
nathan@0
|
119 |
SetupStore("HideMainMenu",MPlayerSetup.HideMainMenu);
|
nathan@0
|
120 |
SetupStore("ResumeMode", MPlayerSetup.ResumeMode);
|
nathan@0
|
121 |
#if APIVERSNUM < 10307
|
nathan@0
|
122 |
SetupStore("OsdPos", MPlayerSetup.OsdPos);
|
nathan@0
|
123 |
#endif
|
nathan@0
|
124 |
for(int i=0; i<10; i++) {
|
nathan@0
|
125 |
char name[16];
|
nathan@0
|
126 |
snprintf(name,sizeof(name),"KeyCmd%d",i);
|
nathan@0
|
127 |
SetupStore(name,MPlayerSetup.KeyCmd[i]);
|
nathan@0
|
128 |
}
|
nathan@0
|
129 |
}
|
nathan@0
|
130 |
|
nathan@0
|
131 |
// --- cMPlayerControl ---------------------------------------------------------
|
nathan@0
|
132 |
|
nathan@0
|
133 |
class cMPlayerControl : public cControl {
|
nathan@0
|
134 |
private:
|
nathan@0
|
135 |
static cFileObj *file;
|
nathan@0
|
136 |
static bool rewind;
|
nathan@0
|
137 |
cMPlayerPlayer *player;
|
nathan@0
|
138 |
#if APIVERSNUM >= 10307
|
nathan@0
|
139 |
cSkinDisplayReplay *display;
|
nathan@0
|
140 |
#endif
|
nathan@0
|
141 |
bool visible, modeOnly, haveBeauty;
|
nathan@0
|
142 |
time_t timeoutShow;
|
nathan@0
|
143 |
int lastCurrent, lastTotal;
|
nathan@0
|
144 |
char *lastReplayMsg;
|
nathan@0
|
145 |
//
|
nathan@0
|
146 |
bool jumpactive, jumphide, jumpmode;
|
nathan@0
|
147 |
int jumpval;
|
nathan@0
|
148 |
//
|
nathan@0
|
149 |
void Stop(void);
|
nathan@0
|
150 |
void ShowTimed(int Seconds=0);
|
nathan@0
|
151 |
void DisplayAtBottom(const char *s);
|
nathan@0
|
152 |
void ShowProgress(void);
|
nathan@0
|
153 |
void ShowMode(void);
|
nathan@0
|
154 |
void ShowTitle(void);
|
nathan@0
|
155 |
void Jump(void);
|
nathan@0
|
156 |
void JumpProcess(eKeys Key);
|
nathan@0
|
157 |
void JumpDisplay(void);
|
nathan@0
|
158 |
public:
|
nathan@0
|
159 |
cMPlayerControl(void);
|
nathan@0
|
160 |
virtual ~cMPlayerControl();
|
nathan@0
|
161 |
virtual eOSState ProcessKey(eKeys Key);
|
nathan@0
|
162 |
virtual void Show(void) { ShowTimed(); }
|
nathan@0
|
163 |
virtual void Hide(void);
|
nathan@0
|
164 |
static void SetFile(const cFileObj *File, bool Rewind);
|
nathan@0
|
165 |
};
|
nathan@0
|
166 |
|
nathan@0
|
167 |
cFileObj *cMPlayerControl::file=0;
|
nathan@0
|
168 |
bool cMPlayerControl::rewind=false;
|
nathan@0
|
169 |
|
nathan@0
|
170 |
cMPlayerControl::cMPlayerControl(void)
|
nathan@0
|
171 |
:cControl(player=new cMPlayerPlayer(file,rewind))
|
nathan@0
|
172 |
{
|
nathan@0
|
173 |
visible=modeOnly=jumpactive=haveBeauty=false;
|
nathan@0
|
174 |
lastReplayMsg=0;
|
nathan@0
|
175 |
#if APIVERSNUM >= 10307
|
nathan@0
|
176 |
display=0;
|
nathan@0
|
177 |
#else
|
nathan@0
|
178 |
#ifdef HAVE_BEAUTYPATCH
|
nathan@0
|
179 |
#if APIVERSNUM >= 10300
|
nathan@0
|
180 |
const cFont *sym=cFont::GetFont(fontSym);
|
nathan@0
|
181 |
const cFont *osd=cFont::GetFont(fontOsd);
|
nathan@0
|
182 |
const cFont::tCharData *symD=sym->CharData(32);
|
nathan@0
|
183 |
const cFont::tCharData *osdD=osd->CharData(32);
|
nathan@0
|
184 |
#else //APIVERSNUM >= 10300
|
nathan@0
|
185 |
cFont *sym=new cFont(fontSym);
|
nathan@0
|
186 |
cFont *osd=new cFont(fontOsd);
|
nathan@0
|
187 |
const cFont::tCharData *symD=sym->CharData(32);
|
nathan@0
|
188 |
const cFont::tCharData *osdD=osd->CharData(32);
|
nathan@0
|
189 |
delete sym;
|
nathan@0
|
190 |
delete osd;
|
nathan@0
|
191 |
#endif //APIVERSNUM >= 10300
|
nathan@0
|
192 |
if(symD != osdD) haveBeauty=true;
|
nathan@0
|
193 |
d(printf("mplayer: beauty patch %sdetected\n",haveBeauty?"":"NOT "))
|
nathan@0
|
194 |
#endif //HAVE_BEAUTYPATCH
|
nathan@0
|
195 |
#endif //APIVERSNUM >= 10307
|
nathan@0
|
196 |
ShowTitle();
|
nathan@0
|
197 |
}
|
nathan@0
|
198 |
|
nathan@0
|
199 |
cMPlayerControl::~cMPlayerControl()
|
nathan@0
|
200 |
{
|
nathan@0
|
201 |
Stop();
|
nathan@0
|
202 |
#if APIVERSNUM >= 10338
|
nathan@0
|
203 |
cStatus::MsgReplaying(this,0,0,false);
|
nathan@0
|
204 |
#else
|
nathan@0
|
205 |
cStatus::MsgReplaying(this, NULL);
|
nathan@0
|
206 |
#endif
|
nathan@0
|
207 |
free(lastReplayMsg);
|
nathan@0
|
208 |
}
|
nathan@0
|
209 |
|
nathan@0
|
210 |
void cMPlayerControl::SetFile(const cFileObj *File, bool Rewind)
|
nathan@0
|
211 |
{
|
nathan@0
|
212 |
delete file;
|
nathan@0
|
213 |
file=File ? new cFileObj(File) : 0;
|
nathan@0
|
214 |
rewind=Rewind;
|
nathan@0
|
215 |
}
|
nathan@0
|
216 |
|
nathan@0
|
217 |
void cMPlayerControl::Stop(void)
|
nathan@0
|
218 |
{
|
nathan@0
|
219 |
delete player; player=0;
|
nathan@0
|
220 |
}
|
nathan@0
|
221 |
|
nathan@0
|
222 |
void cMPlayerControl::ShowTimed(int Seconds)
|
nathan@0
|
223 |
{
|
nathan@0
|
224 |
if(modeOnly) Hide();
|
nathan@0
|
225 |
if(!visible) {
|
nathan@0
|
226 |
ShowProgress();
|
nathan@0
|
227 |
timeoutShow = Seconds>0 ? time(0)+Seconds : 0;
|
nathan@0
|
228 |
}
|
nathan@0
|
229 |
}
|
nathan@0
|
230 |
|
nathan@0
|
231 |
void cMPlayerControl::Hide(void)
|
nathan@0
|
232 |
{
|
nathan@0
|
233 |
if(visible) {
|
nathan@0
|
234 |
#if APIVERSNUM >= 10307
|
nathan@0
|
235 |
delete display; display=0;
|
nathan@0
|
236 |
#else
|
nathan@0
|
237 |
Interface->Close();
|
nathan@0
|
238 |
#endif
|
nathan@0
|
239 |
visible=modeOnly=false;
|
nathan@0
|
240 |
#if APIVERSNUM >= 10500
|
nathan@0
|
241 |
SetNeedsFastResponse(false);
|
nathan@0
|
242 |
#else
|
nathan@0
|
243 |
needsFastResponse=false;
|
nathan@0
|
244 |
#endif
|
nathan@0
|
245 |
}
|
nathan@0
|
246 |
}
|
nathan@0
|
247 |
|
nathan@0
|
248 |
void cMPlayerControl::DisplayAtBottom(const char *s)
|
nathan@0
|
249 |
{
|
nathan@0
|
250 |
#if APIVERSNUM < 10307
|
nathan@0
|
251 |
const int p=modeOnly ? 0 : 2;
|
nathan@0
|
252 |
if(s) {
|
nathan@0
|
253 |
const int d=max(Width()-cOsd::WidthInCells(s),0) / 2;
|
nathan@0
|
254 |
if(modeOnly) Interface->Fill(0, p, Interface->Width(), 1, clrTransparent);
|
nathan@0
|
255 |
Interface->Write(d, p, s);
|
nathan@0
|
256 |
}
|
nathan@0
|
257 |
else
|
nathan@0
|
258 |
Interface->Fill(12, p, Width() - 22, 1, clrBackground);
|
nathan@0
|
259 |
#endif
|
nathan@0
|
260 |
}
|
nathan@0
|
261 |
|
nathan@0
|
262 |
void cMPlayerControl::ShowTitle(void)
|
nathan@0
|
263 |
{
|
nathan@0
|
264 |
const char *path=0;
|
nathan@0
|
265 |
bool release=true;
|
nathan@0
|
266 |
if(player) path=player->GetCurrentName();
|
nathan@0
|
267 |
if(!path) {
|
nathan@0
|
268 |
path=file->FullPath();
|
nathan@0
|
269 |
release=false;
|
nathan@0
|
270 |
}
|
nathan@0
|
271 |
if(path) {
|
nathan@0
|
272 |
const char *name=rindex(path,'/');
|
nathan@0
|
273 |
if(name) name++; else name=path;
|
nathan@0
|
274 |
if(!lastReplayMsg || strcmp(lastReplayMsg,path)) {
|
nathan@0
|
275 |
#if APIVERSNUM >= 10338
|
nathan@0
|
276 |
cStatus::MsgReplaying(this,name,path,true);
|
nathan@0
|
277 |
#else
|
nathan@0
|
278 |
cStatus::MsgReplaying(this,path);
|
nathan@0
|
279 |
#endif
|
nathan@0
|
280 |
free(lastReplayMsg);
|
nathan@0
|
281 |
lastReplayMsg=strdup(path);
|
nathan@0
|
282 |
}
|
nathan@0
|
283 |
if(visible) {
|
nathan@0
|
284 |
#if APIVERSNUM >= 10307
|
nathan@0
|
285 |
if(display) display->SetTitle(name);
|
nathan@0
|
286 |
#else
|
nathan@0
|
287 |
int n=strlen(name);
|
nathan@0
|
288 |
if(n>Width()) {
|
nathan@0
|
289 |
n=n-Width()+4; if(n<0) n=0;
|
nathan@0
|
290 |
char str[72];
|
nathan@0
|
291 |
snprintf(str,sizeof(str),"... %s",name+n);
|
nathan@0
|
292 |
Interface->Write(0,0,str);
|
nathan@0
|
293 |
}
|
nathan@0
|
294 |
else Interface->Write(0,0,name);
|
nathan@0
|
295 |
#endif
|
nathan@0
|
296 |
}
|
nathan@0
|
297 |
}
|
nathan@0
|
298 |
if(release) free((void *)path);
|
nathan@0
|
299 |
}
|
nathan@0
|
300 |
|
nathan@0
|
301 |
void cMPlayerControl::ShowProgress(void)
|
nathan@0
|
302 |
{
|
nathan@0
|
303 |
int Current, Total;
|
nathan@0
|
304 |
|
nathan@0
|
305 |
if(GetIndex(Current,Total) && Total>0) {
|
nathan@0
|
306 |
bool flush=false;
|
nathan@0
|
307 |
if(!visible) {
|
nathan@0
|
308 |
#if APIVERSNUM >= 10307
|
nathan@0
|
309 |
display=Skins.Current()->DisplayReplay(false);
|
nathan@0
|
310 |
#else
|
nathan@0
|
311 |
Interface->Open(Setup.OSDwidth,-MPlayerSetup.OsdPos-3);
|
nathan@0
|
312 |
Interface->Clear();
|
nathan@0
|
313 |
if(MPlayerSetup.OsdPos>0) Interface->Fill(0,3,Interface->Width(),MPlayerSetup.OsdPos,clrTransparent);
|
nathan@0
|
314 |
#endif
|
nathan@0
|
315 |
visible=true; modeOnly=false;
|
nathan@0
|
316 |
#if APIVERSNUM >= 10500
|
nathan@0
|
317 |
SetNeedsFastResponse(true);
|
nathan@0
|
318 |
#else
|
nathan@0
|
319 |
needsFastResponse=true;
|
nathan@0
|
320 |
#endif
|
nathan@0
|
321 |
lastCurrent=lastTotal=-1;
|
nathan@0
|
322 |
flush=true;
|
nathan@0
|
323 |
}
|
nathan@0
|
324 |
|
nathan@0
|
325 |
if(abs(Current-lastCurrent)>12) {
|
nathan@0
|
326 |
#if APIVERSNUM >= 10307
|
nathan@0
|
327 |
if(Total>0) display->SetProgress(Current, Total);
|
nathan@0
|
328 |
display->SetCurrent(IndexToHMSF(Current));
|
nathan@0
|
329 |
display->SetTotal(IndexToHMSF(Total));
|
nathan@0
|
330 |
bool Play, Forward;
|
nathan@0
|
331 |
int Speed;
|
nathan@0
|
332 |
if(GetReplayMode(Play,Forward,Speed))
|
nathan@0
|
333 |
display->SetMode(Play, Forward, Speed);
|
nathan@0
|
334 |
#else
|
nathan@0
|
335 |
cProgressBar ProgressBar(Width() * cOsd::CellWidth(), cOsd::LineHeight(), Current, Total);
|
nathan@0
|
336 |
Interface->SetBitmap(0, cOsd::LineHeight(), ProgressBar);
|
nathan@0
|
337 |
Interface->Write(0,2,IndexToHMSF(Current));
|
nathan@0
|
338 |
Interface->Write(-7,2,IndexToHMSF(Total));
|
nathan@0
|
339 |
#endif
|
nathan@0
|
340 |
ShowTitle();
|
nathan@0
|
341 |
flush=true;
|
nathan@0
|
342 |
lastCurrent=Current; lastTotal=Total;
|
nathan@0
|
343 |
}
|
nathan@0
|
344 |
if(flush)
|
nathan@0
|
345 |
#if APIVERSNUM >= 10307
|
nathan@0
|
346 |
Skins.Flush();
|
nathan@0
|
347 |
#else
|
nathan@0
|
348 |
Interface->Flush();
|
nathan@0
|
349 |
#endif
|
nathan@0
|
350 |
ShowMode();
|
nathan@0
|
351 |
}
|
nathan@0
|
352 |
}
|
nathan@0
|
353 |
|
nathan@0
|
354 |
#if APIVERSNUM < 10307
|
nathan@0
|
355 |
#ifdef HAVE_BEAUTYPATCH
|
nathan@0
|
356 |
int forwSym[] = { FSYM_FORW,FSYM_FORW1,FSYM_FORW2,FSYM_FORW3 };
|
nathan@0
|
357 |
int backSym[] = { FSYM_BACK,FSYM_BACK1,FSYM_BACK2,FSYM_BACK3 };
|
nathan@0
|
358 |
#endif
|
nathan@0
|
359 |
#endif
|
nathan@0
|
360 |
|
nathan@0
|
361 |
void cMPlayerControl::ShowMode(void)
|
nathan@0
|
362 |
{
|
nathan@0
|
363 |
if(Setup.ShowReplayMode && !jumpactive) {
|
nathan@0
|
364 |
bool Play, Forward;
|
nathan@0
|
365 |
int Speed;
|
nathan@0
|
366 |
if(GetReplayMode(Play, Forward, Speed)) {
|
nathan@0
|
367 |
bool NormalPlay = (Play && Speed == -1);
|
nathan@0
|
368 |
|
nathan@0
|
369 |
if(!visible) {
|
nathan@0
|
370 |
if(NormalPlay) return;
|
nathan@0
|
371 |
#if APIVERSNUM >= 10307
|
nathan@0
|
372 |
display = Skins.Current()->DisplayReplay(true);
|
nathan@0
|
373 |
#else
|
nathan@0
|
374 |
Interface->Open(0,-MPlayerSetup.OsdPos-1);
|
nathan@0
|
375 |
#endif
|
nathan@0
|
376 |
visible=modeOnly=true;
|
nathan@0
|
377 |
}
|
nathan@0
|
378 |
|
nathan@0
|
379 |
if(modeOnly && !timeoutShow && NormalPlay) timeoutShow=time(0)+SELECTHIDE_TIMEOUT;
|
nathan@0
|
380 |
|
nathan@0
|
381 |
#if APIVERSNUM >= 10307
|
nathan@0
|
382 |
display->SetMode(Play, Forward, Speed);
|
nathan@0
|
383 |
#else
|
nathan@0
|
384 |
char buf[16];
|
nathan@0
|
385 |
eDvbFont OldFont;
|
nathan@0
|
386 |
#ifdef HAVE_BEAUTYPATCH
|
nathan@0
|
387 |
if(haveBeauty) {
|
nathan@0
|
388 |
int i=0;
|
nathan@0
|
389 |
if(!(Width()&1)) buf[i++]=' ';
|
nathan@0
|
390 |
buf[i]=FSYM_EMPTY; if(Speed>=0 && !Forward) buf[i]=backSym[Speed];
|
nathan@0
|
391 |
i++;
|
nathan@0
|
392 |
buf[i++]=Play?(Speed==-1?FSYM_PLAY:FSYM_EMPTY):FSYM_PAUSE;
|
nathan@0
|
393 |
buf[i]=FSYM_EMPTY; if(Speed>=0 && Forward) buf[i]=forwSym[Speed];
|
nathan@0
|
394 |
i++;
|
nathan@0
|
395 |
if(!(Width()&1)) buf[i++]=' ';
|
nathan@0
|
396 |
buf[i]=0;
|
nathan@0
|
397 |
OldFont = Interface->SetFont(fontSym);
|
nathan@0
|
398 |
}
|
nathan@0
|
399 |
else {
|
nathan@0
|
400 |
#endif //HAVE_BEAUTYPATCH
|
nathan@0
|
401 |
const char *Mode;
|
nathan@0
|
402 |
if (Speed == -1) Mode = Play ? " > " : " || ";
|
nathan@0
|
403 |
else if (Play) Mode = Forward ? " X>> " : " <<X ";
|
nathan@0
|
404 |
else Mode = Forward ? " X|> " : " <|X ";
|
nathan@0
|
405 |
strn0cpy(buf, Mode, sizeof(buf));
|
nathan@0
|
406 |
char *p = strchr(buf, 'X');
|
nathan@0
|
407 |
if(p) *p = Speed > 0 ? '1' + Speed - 1 : ' ';
|
nathan@0
|
408 |
OldFont = Interface->SetFont(fontFix);
|
nathan@0
|
409 |
#ifdef HAVE_BEAUTYPATCH
|
nathan@0
|
410 |
}
|
nathan@0
|
411 |
#endif //HAVE_BEAUTYPATCH
|
nathan@0
|
412 |
DisplayAtBottom(buf);
|
nathan@0
|
413 |
Interface->SetFont(OldFont);
|
nathan@0
|
414 |
#endif //APIVERSNUM >= 10307
|
nathan@0
|
415 |
}
|
nathan@0
|
416 |
}
|
nathan@0
|
417 |
}
|
nathan@0
|
418 |
|
nathan@0
|
419 |
void cMPlayerControl::JumpDisplay(void)
|
nathan@0
|
420 |
{
|
nathan@0
|
421 |
char buf[64];
|
nathan@2
|
422 |
const char *j=trVDR("Jump: "), u=jumpmode?'%':'m';
|
nathan@0
|
423 |
if(!jumpval) sprintf(buf,"%s- %c", j,u);
|
nathan@0
|
424 |
else sprintf(buf,"%s%d- %c",j,jumpval,u);
|
nathan@0
|
425 |
#if APIVERSNUM >= 10307
|
nathan@0
|
426 |
display->SetJump(buf);
|
nathan@0
|
427 |
#else
|
nathan@0
|
428 |
DisplayAtBottom(buf);
|
nathan@0
|
429 |
#endif
|
nathan@0
|
430 |
}
|
nathan@0
|
431 |
|
nathan@0
|
432 |
void cMPlayerControl::JumpProcess(eKeys Key)
|
nathan@0
|
433 |
{
|
nathan@0
|
434 |
const int n=Key-k0;
|
nathan@0
|
435 |
switch (Key) {
|
nathan@0
|
436 |
case k0 ... k9:
|
nathan@0
|
437 |
{
|
nathan@0
|
438 |
const int max=jumpmode?100:lastTotal;
|
nathan@0
|
439 |
if(jumpval*10+n <= max) jumpval=jumpval*10+n;
|
nathan@0
|
440 |
JumpDisplay();
|
nathan@0
|
441 |
}
|
nathan@0
|
442 |
break;
|
nathan@0
|
443 |
case kBlue:
|
nathan@0
|
444 |
jumpmode=!jumpmode; jumpval=0;
|
nathan@0
|
445 |
DisplayAtBottom(0); JumpDisplay();
|
nathan@0
|
446 |
break;
|
nathan@0
|
447 |
case kPlay:
|
nathan@0
|
448 |
case kUp:
|
nathan@0
|
449 |
player->Goto(jumpval*(jumpmode?1:60),jumpmode,false);
|
nathan@0
|
450 |
jumpactive=false;
|
nathan@0
|
451 |
break;
|
nathan@0
|
452 |
case kFastRew:
|
nathan@0
|
453 |
case kFastFwd:
|
nathan@0
|
454 |
case kLeft:
|
nathan@0
|
455 |
case kRight:
|
nathan@0
|
456 |
if(!jumpmode) {
|
nathan@0
|
457 |
player->SkipSeconds(jumpval*60 * ((Key==kLeft || Key==kFastRew) ? -1:1));
|
nathan@0
|
458 |
jumpactive=false;
|
nathan@0
|
459 |
}
|
nathan@0
|
460 |
break;
|
nathan@0
|
461 |
default:
|
nathan@0
|
462 |
jumpactive=false;
|
nathan@0
|
463 |
break;
|
nathan@0
|
464 |
}
|
nathan@0
|
465 |
|
nathan@0
|
466 |
if(!jumpactive) {
|
nathan@0
|
467 |
if(jumphide) Hide();
|
nathan@0
|
468 |
else
|
nathan@0
|
469 |
#if APIVERSNUM >= 10307
|
nathan@0
|
470 |
display->SetJump(0);
|
nathan@0
|
471 |
#else
|
nathan@0
|
472 |
DisplayAtBottom(0);
|
nathan@0
|
473 |
#endif
|
nathan@0
|
474 |
}
|
nathan@0
|
475 |
}
|
nathan@0
|
476 |
|
nathan@0
|
477 |
void cMPlayerControl::Jump(void)
|
nathan@0
|
478 |
{
|
nathan@0
|
479 |
jumpval=0; jumphide=jumpmode=false;
|
nathan@0
|
480 |
if(!visible) {
|
nathan@0
|
481 |
ShowTimed(); if(!visible) return;
|
nathan@0
|
482 |
jumphide=true;
|
nathan@0
|
483 |
}
|
nathan@0
|
484 |
JumpDisplay();
|
nathan@0
|
485 |
jumpactive=true;
|
nathan@0
|
486 |
}
|
nathan@0
|
487 |
|
nathan@0
|
488 |
eOSState cMPlayerControl::ProcessKey(eKeys Key)
|
nathan@0
|
489 |
{
|
nathan@0
|
490 |
if(!player->Active()) { Hide(); Stop(); return osEnd; }
|
nathan@0
|
491 |
|
nathan@0
|
492 |
if(!player->SlaveMode()) {
|
nathan@0
|
493 |
if(Key==kBlue) { Hide(); Stop(); return osEnd; }
|
nathan@0
|
494 |
}
|
nathan@0
|
495 |
else {
|
nathan@0
|
496 |
if(visible) {
|
nathan@0
|
497 |
if(timeoutShow && time(0)>timeoutShow) {
|
nathan@0
|
498 |
Hide(); ShowMode();
|
nathan@0
|
499 |
timeoutShow = 0;
|
nathan@0
|
500 |
}
|
nathan@0
|
501 |
else {
|
nathan@0
|
502 |
if(modeOnly) ShowMode();
|
nathan@0
|
503 |
else ShowProgress();
|
nathan@0
|
504 |
}
|
nathan@0
|
505 |
}
|
nathan@0
|
506 |
else ShowTitle();
|
nathan@0
|
507 |
|
nathan@0
|
508 |
if(jumpactive && Key != kNone) {
|
nathan@0
|
509 |
JumpProcess(Key);
|
nathan@0
|
510 |
return osContinue;
|
nathan@0
|
511 |
}
|
nathan@0
|
512 |
|
nathan@0
|
513 |
bool DoShowMode = true;
|
nathan@0
|
514 |
switch (Key) {
|
nathan@0
|
515 |
case kPlay:
|
nathan@0
|
516 |
case kUp: player->Play(); break;
|
nathan@0
|
517 |
|
nathan@0
|
518 |
case kPause:
|
nathan@0
|
519 |
case kDown: player->Pause(); break;
|
nathan@0
|
520 |
|
nathan@0
|
521 |
case kFastRew|k_Repeat:
|
nathan@0
|
522 |
case kFastRew:
|
nathan@0
|
523 |
case kLeft|k_Repeat:
|
nathan@0
|
524 |
case kLeft: player->SkipSeconds(-10); break;
|
nathan@0
|
525 |
|
nathan@0
|
526 |
case kFastFwd|k_Repeat:
|
nathan@0
|
527 |
case kFastFwd:
|
nathan@0
|
528 |
case kRight|k_Repeat:
|
nathan@0
|
529 |
case kRight: player->SkipSeconds(10); break;
|
nathan@0
|
530 |
|
nathan@0
|
531 |
case kRed: Jump(); break;
|
nathan@0
|
532 |
|
nathan@0
|
533 |
case kGreen|k_Repeat: // temporary use
|
nathan@0
|
534 |
case kGreen: player->SkipSeconds(-60); break;
|
nathan@0
|
535 |
case kYellow|k_Repeat:
|
nathan@0
|
536 |
case kYellow: player->SkipSeconds(60); break;
|
nathan@0
|
537 |
// case kGreen|k_Repeat: // reserved for future use
|
nathan@0
|
538 |
// case kGreen: player->SkipPrev(); break;
|
nathan@0
|
539 |
// case kYellow|k_Repeat:
|
nathan@0
|
540 |
// case kYellow: player->SkipNext(); break;
|
nathan@0
|
541 |
|
nathan@0
|
542 |
case kBack:
|
nathan@0
|
543 |
#if APIVERSNUM >= 10332
|
nathan@0
|
544 |
Hide();
|
nathan@2
|
545 |
cRemote::CallPlugin(plugin_name);
|
nathan@0
|
546 |
return osBack;
|
nathan@0
|
547 |
#endif
|
nathan@0
|
548 |
case kStop:
|
nathan@0
|
549 |
case kBlue: Hide(); Stop(); return osEnd;
|
nathan@0
|
550 |
|
nathan@0
|
551 |
default:
|
nathan@0
|
552 |
DoShowMode = false;
|
nathan@0
|
553 |
switch(Key) {
|
nathan@0
|
554 |
case kOk: if(visible && !modeOnly) { Hide(); DoShowMode=true; }
|
nathan@0
|
555 |
else ShowTimed();
|
nathan@0
|
556 |
break;
|
nathan@20
|
557 |
#if APIVERSNUM >= 10318
|
nathan@20
|
558 |
case kAudio:
|
nathan@20
|
559 |
player->KeyCmd("switch_audio");
|
nathan@20
|
560 |
break;
|
nathan@20
|
561 |
#endif
|
nathan@0
|
562 |
case k0:
|
nathan@0
|
563 |
case k1:
|
nathan@0
|
564 |
case k2:
|
nathan@0
|
565 |
case k3:
|
nathan@0
|
566 |
case k4:
|
nathan@0
|
567 |
case k5:
|
nathan@0
|
568 |
case k6:
|
nathan@0
|
569 |
case k7:
|
nathan@0
|
570 |
case k8:
|
nathan@0
|
571 |
case k9: {
|
nathan@0
|
572 |
const char *cmd=MPlayerSetup.KeyCmd[Key-k0];
|
nathan@0
|
573 |
if(cmd[0]) player->KeyCmd(cmd);
|
nathan@0
|
574 |
}
|
nathan@0
|
575 |
break;
|
nathan@0
|
576 |
default: break;
|
nathan@0
|
577 |
}
|
nathan@0
|
578 |
break;
|
nathan@0
|
579 |
}
|
nathan@0
|
580 |
|
nathan@0
|
581 |
if(DoShowMode) ShowMode();
|
nathan@0
|
582 |
}
|
nathan@0
|
583 |
return osContinue;
|
nathan@0
|
584 |
}
|
nathan@0
|
585 |
|
nathan@0
|
586 |
// --- cMenuMPlayAid -----------------------------------------------------------
|
nathan@0
|
587 |
|
nathan@0
|
588 |
class cMenuMPlayAid : public cOsdMenu {
|
nathan@0
|
589 |
public:
|
nathan@0
|
590 |
cMenuMPlayAid(void);
|
nathan@0
|
591 |
virtual eOSState ProcessKey(eKeys Key);
|
nathan@0
|
592 |
};
|
nathan@0
|
593 |
|
nathan@0
|
594 |
cMenuMPlayAid::cMenuMPlayAid(void)
|
nathan@0
|
595 |
:cOsdMenu(tr("MPlayer Audio ID"),20)
|
nathan@0
|
596 |
{
|
nathan@0
|
597 |
Add(new cMenuEditIntItem(tr("Audiostream ID"),&MPlayerAid,-1,255));
|
nathan@0
|
598 |
Display();
|
nathan@0
|
599 |
}
|
nathan@0
|
600 |
|
nathan@0
|
601 |
eOSState cMenuMPlayAid::ProcessKey(eKeys Key)
|
nathan@0
|
602 |
{
|
nathan@0
|
603 |
eOSState state=cOsdMenu::ProcessKey(Key);
|
nathan@0
|
604 |
if(state==osUnknown) {
|
nathan@0
|
605 |
switch(Key) {
|
nathan@0
|
606 |
case kOk: state=osBack; break;
|
nathan@0
|
607 |
default: break;
|
nathan@0
|
608 |
}
|
nathan@0
|
609 |
}
|
nathan@0
|
610 |
return state;
|
nathan@0
|
611 |
}
|
nathan@0
|
612 |
|
nathan@0
|
613 |
// --- cMenuMPlayBrowse ---------------------------------------------------------
|
nathan@0
|
614 |
|
nathan@0
|
615 |
class cMenuMPlayBrowse : public cMenuBrowse {
|
nathan@0
|
616 |
private:
|
nathan@0
|
617 |
bool sourcing, aidedit;
|
nathan@0
|
618 |
eOSState Source(bool second);
|
nathan@0
|
619 |
eOSState Summary(void);
|
nathan@0
|
620 |
protected:
|
nathan@0
|
621 |
virtual void SetButtons(void);
|
nathan@0
|
622 |
public:
|
nathan@0
|
623 |
cMenuMPlayBrowse(void);
|
nathan@0
|
624 |
virtual eOSState ProcessKey(eKeys Key);
|
nathan@0
|
625 |
};
|
nathan@0
|
626 |
|
nathan@0
|
627 |
static const char *excl_sum[] = { ".*","*.summary","*.txt","*.nfo",0 };
|
nathan@0
|
628 |
|
nathan@0
|
629 |
cMenuMPlayBrowse::cMenuMPlayBrowse(void)
|
nathan@0
|
630 |
:cMenuBrowse(MPlaySources.GetSource(),false,false,tr("MPlayer browser"),excl_sum)
|
nathan@0
|
631 |
{
|
nathan@0
|
632 |
sourcing=aidedit=false;
|
nathan@0
|
633 |
SetButtons();
|
nathan@0
|
634 |
}
|
nathan@0
|
635 |
|
nathan@0
|
636 |
void cMenuMPlayBrowse::SetButtons(void)
|
nathan@0
|
637 |
{
|
nathan@0
|
638 |
static char blue[12];
|
nathan@0
|
639 |
snprintf(blue,sizeof(blue),MPlayerAid>=0 ? "AID:%d" : "AID:def",MPlayerAid);
|
nathan@2
|
640 |
SetHelp(trVDR(BUTTON"Play"), MPlayerSetup.ResumeMode ? trVDR(BUTTON"Rewind"):0, tr("Source"), blue);
|
nathan@0
|
641 |
Display();
|
nathan@0
|
642 |
}
|
nathan@0
|
643 |
|
nathan@0
|
644 |
eOSState cMenuMPlayBrowse::Source(bool second)
|
nathan@0
|
645 |
{
|
nathan@0
|
646 |
if(HasSubMenu()) return osContinue;
|
nathan@0
|
647 |
|
nathan@0
|
648 |
if(!second) {
|
nathan@0
|
649 |
sourcing=true;
|
nathan@0
|
650 |
return AddSubMenu(new cMenuSource(&MPlaySources,tr("MPlayer source")));
|
nathan@0
|
651 |
}
|
nathan@0
|
652 |
sourcing=false;
|
nathan@0
|
653 |
cFileSource *src=cMenuSource::GetSelected();
|
nathan@0
|
654 |
if(src) {
|
nathan@0
|
655 |
MPlaySources.SetSource(src);
|
nathan@0
|
656 |
SetSource(src);
|
nathan@0
|
657 |
NewDir(0);
|
nathan@0
|
658 |
}
|
nathan@0
|
659 |
return osContinue;
|
nathan@0
|
660 |
}
|
nathan@0
|
661 |
|
nathan@0
|
662 |
eOSState cMenuMPlayBrowse::Summary(void)
|
nathan@0
|
663 |
{
|
nathan@0
|
664 |
cFileObj *item=CurrentItem();
|
nathan@0
|
665 |
if(item && item->Type()==otFile) {
|
nathan@0
|
666 |
static const char *exts[] = { ".summary",".txt",".nfo",0 };
|
nathan@0
|
667 |
for(int i=0; exts[i]; i++) {
|
nathan@0
|
668 |
char buff[4096];
|
nathan@0
|
669 |
strn0cpy(buff,item->FullPath(),sizeof(buff)-20);
|
nathan@0
|
670 |
char *e=&buff[strlen(buff)];
|
nathan@0
|
671 |
strn0cpy(e,exts[i],20);
|
nathan@0
|
672 |
int fd=open(buff,O_RDONLY);
|
nathan@0
|
673 |
*e=0;
|
nathan@0
|
674 |
if(fd<0 && (e=rindex(buff,'.'))) {
|
nathan@0
|
675 |
strn0cpy(e,exts[i],20);
|
nathan@0
|
676 |
fd=open(buff,O_RDONLY);
|
nathan@0
|
677 |
}
|
nathan@0
|
678 |
if(fd>=0) {
|
nathan@0
|
679 |
int r=read(fd,buff,sizeof(buff)-1);
|
nathan@0
|
680 |
close(fd);
|
nathan@0
|
681 |
if(r>0) {
|
nathan@0
|
682 |
buff[r]=0;
|
nathan@0
|
683 |
return AddSubMenu(new cMenuText(tr("Summary"),buff));
|
nathan@0
|
684 |
}
|
nathan@0
|
685 |
}
|
nathan@0
|
686 |
}
|
nathan@0
|
687 |
}
|
nathan@0
|
688 |
return osContinue;
|
nathan@0
|
689 |
}
|
nathan@0
|
690 |
|
nathan@0
|
691 |
eOSState cMenuMPlayBrowse::ProcessKey(eKeys Key)
|
nathan@0
|
692 |
{
|
nathan@0
|
693 |
eOSState state=cOsdMenu::ProcessKey(Key);
|
nathan@0
|
694 |
if(state==osContinue && !HasSubMenu()) {
|
nathan@0
|
695 |
if(sourcing) return Source(true);
|
nathan@0
|
696 |
if(aidedit) { aidedit=false; SetButtons(); }
|
nathan@0
|
697 |
}
|
nathan@0
|
698 |
bool rew=false;
|
nathan@0
|
699 |
if(state==osUnknown) {
|
nathan@0
|
700 |
switch(Key) {
|
nathan@0
|
701 |
case kGreen:
|
nathan@0
|
702 |
{
|
nathan@0
|
703 |
cFileObj *item=CurrentItem();
|
nathan@0
|
704 |
if(item && item->Type()==otFile) {
|
nathan@0
|
705 |
lastselect=new cFileObj(item);
|
nathan@0
|
706 |
state=osBack;
|
nathan@0
|
707 |
rew=true;
|
nathan@0
|
708 |
}
|
nathan@0
|
709 |
else state=osContinue;
|
nathan@0
|
710 |
break;
|
nathan@0
|
711 |
}
|
nathan@0
|
712 |
case kYellow:
|
nathan@0
|
713 |
state=Source(false);
|
nathan@0
|
714 |
break;
|
nathan@0
|
715 |
case kBlue:
|
nathan@0
|
716 |
aidedit=true;
|
nathan@0
|
717 |
state=AddSubMenu(new cMenuMPlayAid);
|
nathan@0
|
718 |
break;
|
nathan@0
|
719 |
case k0:
|
nathan@0
|
720 |
state=Summary();
|
nathan@0
|
721 |
break;
|
nathan@0
|
722 |
default:
|
nathan@0
|
723 |
break;
|
nathan@0
|
724 |
}
|
nathan@0
|
725 |
}
|
nathan@0
|
726 |
if(state==osUnknown) state=cMenuBrowse::ProcessStdKey(Key,state);
|
nathan@0
|
727 |
if(state==osBack && lastselect) {
|
nathan@0
|
728 |
cMPlayerControl::SetFile(lastselect,rew);
|
nathan@0
|
729 |
cControl::Launch(new cMPlayerControl);
|
nathan@0
|
730 |
return osEnd;
|
nathan@0
|
731 |
}
|
nathan@0
|
732 |
return state;
|
nathan@0
|
733 |
}
|
nathan@0
|
734 |
|
nathan@0
|
735 |
// --- cPluginMPlayer ----------------------------------------------------------
|
nathan@0
|
736 |
|
nathan@2
|
737 |
static const char *DESCRIPTION = trNOOP("Media replay via MPlayer");
|
nathan@0
|
738 |
static const char *MAINMENUENTRY = "MPlayer";
|
nathan@0
|
739 |
|
nathan@0
|
740 |
class cPluginMPlayer : public cPlugin {
|
nathan@0
|
741 |
private:
|
nathan@0
|
742 |
#if APIVERSNUM >= 10330
|
nathan@0
|
743 |
bool ExternalPlay(const char *path, bool test);
|
nathan@0
|
744 |
#endif
|
nathan@0
|
745 |
public:
|
nathan@0
|
746 |
cPluginMPlayer(void);
|
nathan@0
|
747 |
virtual ~cPluginMPlayer();
|
nathan@9
|
748 |
virtual const char *Version(void) { return PluginVersion; }
|
nathan@0
|
749 |
virtual const char *Description(void) { return tr(DESCRIPTION); }
|
nathan@0
|
750 |
virtual const char *CommandLineHelp(void);
|
nathan@0
|
751 |
virtual bool ProcessArgs(int argc, char *argv[]);
|
nathan@0
|
752 |
#if APIVERSNUM >= 10131
|
nathan@0
|
753 |
virtual bool Initialize(void);
|
nathan@0
|
754 |
#else
|
nathan@0
|
755 |
virtual bool Start(void);
|
nathan@0
|
756 |
#endif
|
nathan@0
|
757 |
virtual const char *MainMenuEntry(void);
|
nathan@0
|
758 |
virtual cOsdMenu *MainMenuAction(void);
|
nathan@0
|
759 |
virtual cMenuSetupPage *SetupMenu(void);
|
nathan@0
|
760 |
virtual bool SetupParse(const char *Name, const char *Value);
|
nathan@0
|
761 |
#if APIVERSNUM >= 10330
|
nathan@0
|
762 |
virtual bool Service(const char *Id, void *Data);
|
nathan@0
|
763 |
#if APIVERSNUM >= 10331
|
nathan@0
|
764 |
virtual const char **SVDRPHelpPages(void);
|
nathan@0
|
765 |
virtual cString SVDRPCommand(const char *Command, const char *Option, int &ReplyCode);
|
nathan@0
|
766 |
#endif
|
nathan@0
|
767 |
#endif
|
nathan@0
|
768 |
};
|
nathan@0
|
769 |
|
nathan@0
|
770 |
cPluginMPlayer::cPluginMPlayer(void)
|
nathan@0
|
771 |
{
|
nathan@0
|
772 |
// Initialize any member variables here.
|
nathan@0
|
773 |
// DON'T DO ANYTHING ELSE THAT MAY HAVE SIDE EFFECTS, REQUIRE GLOBAL
|
nathan@0
|
774 |
// VDR OBJECTS TO EXIST OR PRODUCE ANY OUTPUT!
|
nathan@0
|
775 |
status=0;
|
nathan@0
|
776 |
}
|
nathan@0
|
777 |
|
nathan@0
|
778 |
cPluginMPlayer::~cPluginMPlayer()
|
nathan@0
|
779 |
{
|
nathan@0
|
780 |
delete status;
|
nathan@0
|
781 |
}
|
nathan@0
|
782 |
|
nathan@0
|
783 |
const char *cPluginMPlayer::CommandLineHelp(void)
|
nathan@0
|
784 |
{
|
nathan@0
|
785 |
static char *help_str=0;
|
nathan@0
|
786 |
|
nathan@0
|
787 |
free(help_str); // for easier orientation, this is column 80|
|
nathan@0
|
788 |
asprintf(&help_str," -m CMD, --mount=CMD use CMD to mount/unmount/eject mp3 sources\n"
|
nathan@0
|
789 |
" (default: %s)\n"
|
nathan@0
|
790 |
" -M CMD, --mplayer=CMD use CMD when calling MPlayer\n"
|
nathan@0
|
791 |
" (default: %s)\n"
|
nathan@0
|
792 |
" -S SUB, --sources=SUB search sources config in SUB subdirectory\n"
|
nathan@0
|
793 |
" (default: %s)\n"
|
nathan@0
|
794 |
" -R DIR, --resume=DIR store global resume file in DIR\n"
|
nathan@0
|
795 |
" (default: %s)\n",
|
nathan@0
|
796 |
mountscript,
|
nathan@0
|
797 |
MPlayerCmd,
|
nathan@0
|
798 |
sourcesSub ? sourcesSub:"none",
|
nathan@0
|
799 |
globalResumeDir ? globalResumeDir:"video dir"
|
nathan@0
|
800 |
);
|
nathan@0
|
801 |
return help_str;
|
nathan@0
|
802 |
}
|
nathan@0
|
803 |
|
nathan@0
|
804 |
bool cPluginMPlayer::ProcessArgs(int argc, char *argv[])
|
nathan@0
|
805 |
{
|
nathan@0
|
806 |
static struct option long_options[] = {
|
nathan@0
|
807 |
{ "mount", required_argument, NULL, 'm' },
|
nathan@0
|
808 |
{ "mplayer", required_argument, NULL, 'M' },
|
nathan@0
|
809 |
{ "sources", required_argument, NULL, 'S' },
|
nathan@0
|
810 |
{ "resume", required_argument, NULL, 'R' },
|
nathan@0
|
811 |
{ NULL }
|
nathan@0
|
812 |
};
|
nathan@0
|
813 |
|
nathan@0
|
814 |
int c, option_index = 0;
|
nathan@0
|
815 |
while((c=getopt_long(argc,argv,"m:M:S:R:",long_options,&option_index))!=-1) {
|
nathan@0
|
816 |
switch (c) {
|
nathan@0
|
817 |
case 'm': mountscript=optarg; break;
|
nathan@0
|
818 |
case 'M': MPlayerCmd=optarg; break;
|
nathan@0
|
819 |
case 'S': sourcesSub=optarg; break;
|
nathan@0
|
820 |
case 'R': globalResumeDir=optarg; break;
|
nathan@0
|
821 |
default: return false;
|
nathan@0
|
822 |
}
|
nathan@0
|
823 |
}
|
nathan@0
|
824 |
return true;
|
nathan@0
|
825 |
}
|
nathan@0
|
826 |
|
nathan@0
|
827 |
#if APIVERSNUM >= 10131
|
nathan@0
|
828 |
bool cPluginMPlayer::Initialize(void)
|
nathan@0
|
829 |
#else
|
nathan@0
|
830 |
bool cPluginMPlayer::Start(void)
|
nathan@0
|
831 |
#endif
|
nathan@0
|
832 |
{
|
nathan@0
|
833 |
if(!CheckVDRVersion(1,1,16,"mplayer")) return false;
|
nathan@2
|
834 |
plugin_name="mplayer";
|
nathan@2
|
835 |
#if APIVERSNUM < 10507
|
nathan@2
|
836 |
i18n_name="mplayer";
|
nathan@2
|
837 |
#else
|
nathan@2
|
838 |
i18n_name="vdr-mplayer";
|
nathan@2
|
839 |
#endif
|
nathan@0
|
840 |
MPlaySources.Load(AddDirectory(ConfigDirectory(sourcesSub),"mplayersources.conf"));
|
nathan@0
|
841 |
if(MPlaySources.Count()<1) {
|
nathan@0
|
842 |
esyslog("ERROR: you must have defined at least one source in mplayersources.conf");
|
nathan@0
|
843 |
fprintf(stderr,"No source(s) defined in mplayersources.conf\n");
|
nathan@0
|
844 |
return false;
|
nathan@0
|
845 |
}
|
nathan@2
|
846 |
#if APIVERSNUM < 10507
|
nathan@0
|
847 |
RegisterI18n(Phrases);
|
nathan@2
|
848 |
#endif
|
nathan@0
|
849 |
if(!(status=new cMPlayerStatus)) return false;
|
nathan@0
|
850 |
return true;
|
nathan@0
|
851 |
}
|
nathan@0
|
852 |
|
nathan@0
|
853 |
const char *cPluginMPlayer::MainMenuEntry(void)
|
nathan@0
|
854 |
{
|
nathan@0
|
855 |
return MPlayerSetup.HideMainMenu ? 0 : tr(MAINMENUENTRY);
|
nathan@0
|
856 |
}
|
nathan@0
|
857 |
|
nathan@0
|
858 |
cOsdMenu *cPluginMPlayer::MainMenuAction(void)
|
nathan@0
|
859 |
{
|
nathan@0
|
860 |
return new cMenuMPlayBrowse;
|
nathan@0
|
861 |
}
|
nathan@0
|
862 |
|
nathan@0
|
863 |
cMenuSetupPage *cPluginMPlayer::SetupMenu(void)
|
nathan@0
|
864 |
{
|
nathan@0
|
865 |
return new cMenuSetupMPlayer;
|
nathan@0
|
866 |
}
|
nathan@0
|
867 |
|
nathan@0
|
868 |
bool cPluginMPlayer::SetupParse(const char *Name, const char *Value)
|
nathan@0
|
869 |
{
|
nathan@0
|
870 |
if( !strcasecmp(Name, "ControlMode")) MPlayerSetup.SlaveMode = atoi(Value);
|
nathan@0
|
871 |
else if (!strcasecmp(Name, "HideMainMenu")) MPlayerSetup.HideMainMenu = atoi(Value);
|
nathan@0
|
872 |
else if (!strcasecmp(Name, "ResumeMode")) MPlayerSetup.ResumeMode = atoi(Value);
|
nathan@0
|
873 |
else if (!strcasecmp(Name, "OsdPos")) MPlayerSetup.OsdPos = atoi(Value);
|
nathan@0
|
874 |
else if (!strncasecmp(Name,"KeyCmd", 6) && strlen(Name)==7 && isdigit(Name[6]))
|
nathan@0
|
875 |
strn0cpy(MPlayerSetup.KeyCmd[Name[6]-'0'],Value,sizeof(MPlayerSetup.KeyCmd[0]));
|
nathan@0
|
876 |
else return false;
|
nathan@0
|
877 |
return true;
|
nathan@0
|
878 |
}
|
nathan@0
|
879 |
|
nathan@0
|
880 |
#if APIVERSNUM >= 10330
|
nathan@0
|
881 |
|
nathan@0
|
882 |
bool cPluginMPlayer::ExternalPlay(const char *path, bool test)
|
nathan@0
|
883 |
{
|
nathan@0
|
884 |
char real[PATH_MAX+1];
|
nathan@0
|
885 |
if(realpath(path,real)) {
|
nathan@0
|
886 |
cFileSource *src=MPlaySources.FindSource(real);
|
nathan@0
|
887 |
if(src) {
|
nathan@0
|
888 |
cFileObj *item=new cFileObj(src,0,0,otFile);
|
nathan@0
|
889 |
if(item) {
|
nathan@0
|
890 |
item->SplitAndSet(real);
|
nathan@0
|
891 |
if(item->GuessType()) {
|
nathan@0
|
892 |
if(item->Exists()) {
|
nathan@0
|
893 |
if(!test) {
|
nathan@0
|
894 |
cMPlayerControl::SetFile(item,true);
|
nathan@0
|
895 |
cControl::Launch(new cMPlayerControl);
|
nathan@0
|
896 |
cControl::Attach();
|
nathan@0
|
897 |
}
|
nathan@0
|
898 |
delete item;
|
nathan@0
|
899 |
return true;
|
nathan@0
|
900 |
}
|
nathan@0
|
901 |
else dsyslog("MPlayer service: cannot play '%s'",path);
|
nathan@0
|
902 |
}
|
nathan@0
|
903 |
else dsyslog("MPlayer service: GuessType() failed for '%s'",path);
|
nathan@0
|
904 |
delete item;
|
nathan@0
|
905 |
}
|
nathan@0
|
906 |
}
|
nathan@0
|
907 |
else dsyslog("MPlayer service: cannot find source for '%s', real '%s'",path,real);
|
nathan@0
|
908 |
}
|
nathan@0
|
909 |
else if(errno!=ENOENT && errno!=ENOTDIR)
|
nathan@0
|
910 |
esyslog("ERROR: realpath: %s: %s",path,strerror(errno));
|
nathan@0
|
911 |
return false;
|
nathan@0
|
912 |
}
|
nathan@0
|
913 |
|
nathan@0
|
914 |
bool cPluginMPlayer::Service(const char *Id, void *Data)
|
nathan@0
|
915 |
{
|
nathan@0
|
916 |
if(!strcasecmp(Id,"MPlayer-Play-v1")) {
|
nathan@0
|
917 |
if(Data) {
|
nathan@0
|
918 |
struct MPlayerServiceData *msd=(struct MPlayerServiceData *)Data;
|
nathan@0
|
919 |
msd->result=ExternalPlay(msd->data.filename,false);
|
nathan@0
|
920 |
}
|
nathan@0
|
921 |
return true;
|
nathan@0
|
922 |
}
|
nathan@0
|
923 |
else if(!strcasecmp(Id,"MPlayer-Test-v1")) {
|
nathan@0
|
924 |
if(Data) {
|
nathan@0
|
925 |
struct MPlayerServiceData *msd=(struct MPlayerServiceData *)Data;
|
nathan@0
|
926 |
msd->result=ExternalPlay(msd->data.filename,true);
|
nathan@0
|
927 |
}
|
nathan@0
|
928 |
return true;
|
nathan@0
|
929 |
}
|
nathan@0
|
930 |
return false;
|
nathan@0
|
931 |
}
|
nathan@0
|
932 |
|
nathan@0
|
933 |
#if APIVERSNUM >= 10331
|
nathan@0
|
934 |
|
nathan@0
|
935 |
const char **cPluginMPlayer::SVDRPHelpPages(void)
|
nathan@0
|
936 |
{
|
nathan@0
|
937 |
static const char *HelpPages[] = {
|
nathan@0
|
938 |
"PLAY <filename>\n"
|
nathan@0
|
939 |
" Triggers playback of file 'filename'.",
|
nathan@0
|
940 |
"TEST <filename>\n"
|
nathan@0
|
941 |
" Tests is playback of file 'filename' is possible.",
|
nathan@0
|
942 |
NULL
|
nathan@0
|
943 |
};
|
nathan@0
|
944 |
return HelpPages;
|
nathan@0
|
945 |
}
|
nathan@0
|
946 |
|
nathan@0
|
947 |
cString cPluginMPlayer::SVDRPCommand(const char *Command, const char *Option, int &ReplyCode)
|
nathan@0
|
948 |
{
|
nathan@0
|
949 |
if(!strcasecmp(Command,"PLAY")) {
|
nathan@0
|
950 |
if(*Option) {
|
nathan@0
|
951 |
if(ExternalPlay(Option,false)) return "Playback triggered";
|
nathan@0
|
952 |
else { ReplyCode=550; return "Playback failed"; }
|
nathan@0
|
953 |
}
|
nathan@0
|
954 |
else { ReplyCode=501; return "Missing filename"; }
|
nathan@0
|
955 |
}
|
nathan@0
|
956 |
else if(!strcasecmp(Command,"TEST")) {
|
nathan@0
|
957 |
if(*Option) {
|
nathan@0
|
958 |
if(ExternalPlay(Option,true)) return "Playback possible";
|
nathan@0
|
959 |
else { ReplyCode=550; return "Playback not possible"; }
|
nathan@0
|
960 |
}
|
nathan@0
|
961 |
else { ReplyCode=501; return "Missing filename"; }
|
nathan@0
|
962 |
}
|
nathan@0
|
963 |
return NULL;
|
nathan@0
|
964 |
}
|
nathan@0
|
965 |
|
nathan@0
|
966 |
#endif // 1.3.31
|
nathan@0
|
967 |
#endif // 1.3.30
|
nathan@0
|
968 |
|
nathan@0
|
969 |
VDRPLUGINCREATOR(cPluginMPlayer); // Don't touch this!
|