vdr-plugin-softhddevice-drm-gles 1.4.0
softhdmenu.cpp
Go to the documentation of this file.
1
21#include <cstdlib>
22#include <sys/stat.h>
23
24#include <string>
25using std::string;
26#include <fstream>
27using std::ifstream;
28#include <sys/stat.h>
29
30#include <vdr/interface.h>
31#include <vdr/player.h>
32#include <vdr/plugin.h>
33#include <vdr/videodir.h>
34
35#include "mediaplayer.h"
36#include "softhdmenu.h"
37#include "softhddevice.h"
38#include "logger.h"
39
40extern "C"
41{
42#include <libavcodec/avcodec.h>
43#include <libavformat/avformat.h>
44
45#include "misc.h"
46}
47
48#include "videostream.h"
49#include "audio.h"
50
51
52/*****************************************************************************
53 * cSoftHdMenu
54 ****************************************************************************/
55
59cSoftHdMenu::cSoftHdMenu(const char *title, cSoftHdDevice *device,
60 int c0, int c1, int c2, int c3, int c4)
61:cOsdMenu(title, c0, c1, c2, c3, c4)
62{
63 pSoftHdMenu = this;
64 m_playlist.clear();
65 m_pDevice = device;
67
68 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->FirstEntry) {
69 LOGDEBUG2(L_MEDIA, "mediaplayer: %s: pointer to cSoftHdControl exist.", __FUNCTION__);
70 PlayListMenu(); // Test if PL!!!
71 } else {
72 MainMenu();
73 }
74}
75
80{
81 pSoftHdMenu = NULL;
82}
83
89static inline cOsdItem *SeparatorName(const char *label)
90{
91 return new cOsdItem(cString::sprintf("%s:", label), osUnknown, false);
92}
93
99static inline cOsdItem *SeparatorSpace(void)
100{
101 return new cOsdItem(" ", osUnknown, false);
102}
103
108{
109 int current;
110
111 current = Current(); // get current menu item index
112 Clear(); // clear the menu
113
114 // pip
115 Add(SeparatorName("PIP"));
116 Add(new cOsdItem(hk(tr(" Toggle")), osUser1));
117 Add(new cOsdItem(hk(tr(" Channel +")), osUser2));
118 Add(new cOsdItem(hk(tr(" Channel -")), osUser3));
119 Add(new cOsdItem(hk(tr(" Swap Channel")), osUser4));
120 Add(new cOsdItem(hk(tr(" Swap Position")), osUser5));
121
122 Add(SeparatorSpace());
123
124 Add(SeparatorName("Mediaplayer"));
125 // mediaplayer
126 Add(new cOsdItem(hk(tr(" play file / make play list")), osUser6));
127 Add(new cOsdItem(hk(tr(" select play list")), osUser7));
128
129 SetCurrent(Get(current)); // restore selected menu entry
130 Display();
131}
132
141
146 switch (code) {
147 case PIPTOGGLEONOFF:
149 break;
150 case PIPCHANNELUP:
152 break;
153 case PIPCHANNELDOWN:
155 break;
156 case PIPCHANNELSWAP:
158 break;
159 case PIPPOSITIONSWAP:
161 break;
162 default:
163 break;
164 }
165}
166
172eOSState cSoftHdMenu::ProcessKey(eKeys key)
173{
174 eOSState state;
175 cOsdItem *item;
176
177 switch (m_hotkeyState) {
179 if (key == kBlue) {
181 return osContinue;
182 }
183 break;
185 if (k0 <= key && key <= k9) {
186 int hotkeyCode = PIPKEYBASE + key - k0;
188 HandleHotKey(hotkeyCode);
189 return osEnd;
190 }
192 break;
193 }
194
195 item = (cOsdItem *) Get(Current());
196 state = cOsdMenu::ProcessKey(key);
197
198 switch (state) {
199 // pip
200 case osUser1: // toggle pip
202 return osEnd;
203 case osUser2: // pip channel +
205 return osEnd;
206 case osUser3: // pip channel -
208 return osEnd;
209 case osUser4: // pip channel swap
211 return osEnd;
212 case osUser5: // pip position swap
214 return osEnd;
215
216 // mediaplayer
217 case osUser6: // play file / make play list
218 m_path = cVideoDirectory::Name();
219 FindFile(m_path, NULL);
220 return osContinue;
221 case osUser7: // select play list
222 m_path = cPlugin::ConfigDirectory("softhddevice-drm-gles");
223 SelectPL();
224 return osContinue;
225 default:
226 break;
227 }
228
229 switch (key) {
230 case kOk:
231 if (strcasestr(item->Text(), "[..]")) {
232 string newPath = m_path.substr(0 ,m_path.find_last_of("/"));
233
234 if (!m_lastItem.empty())
235 m_lastItem.clear();
236 m_lastItem = m_path.substr(m_path.find_last_of("/") + 1);
237
238 m_path = newPath;
239 FindFile(m_path.c_str(), NULL);
240 break;
241 }
242 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->CurrentEntry) {
243 cSoftHdControl::Control()->Player()->SetEntry(Current());
244// PlayListMenu();
245 break;
246 }
247 if (TestMedia(item->Text())) {
248 PlayMedia(item->Text());
249 return osEnd;
250 } else {
251 string newPath = m_path + "/" + item->Text();
252 struct stat sb;
253 if (stat(newPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
254 m_path = newPath;
255 FindFile(newPath.c_str(), NULL);
256 }
257 }
258 break;
259 case kRed:
260 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->CurrentEntry) {
262 PlayListMenu();
263 break;
264 }
265 if (m_playlist.empty()) {
266 if (TestMedia(item->Text())) {
267 PlayMedia(item->Text());
268 return osEnd;
269 }
270 } else {
271 m_path = cPlugin::ConfigDirectory("softhddevice-drm-gles");
272 PlayMedia(m_playlist.c_str());
273 return osEnd;
274 }
275 break;
276 case kGreen:
279 } else {
280 MakePlayList(item->Text(), "w");
281 Interface->Confirm(tr("New Playlist"), 1, true);
282 if (!m_lastItem.empty())
283 m_lastItem.clear();
284 m_lastItem = item->Text();
285 FindFile(m_path.c_str(), NULL);
286 }
287 break;
288 case kYellow:
291 } else {
292 MakePlayList(item->Text(), "a");
293 Interface->Confirm(tr("Added to Playlist"), 1, true);
294 }
295 break;
296 case kBlue:
297 state = osStopReplay;
298 break;
299 case kPlay:
300 if (TestMedia(item->Text())) {
301 PlayMedia(item->Text());
302 return osEnd;
303 }
304 break;
305 case kNext:
308 break;
309 default:
310 break;
311 }
312
313 return state;
314}
315
320{
321 struct PLEntry *entry = cSoftHdControl::Control()->Player()->FirstEntry;
322 Clear();
323 while (1) {
324 string p_string = entry->Folder
325 + " - " + entry->SubFolder
326 + " - " + entry->File;
327 Add(new cOsdItem(p_string.c_str()), (entry == cSoftHdControl::Control()->Player()->CurrentEntry));
328
329 if (entry->NextEntry) {
330 entry = entry->NextEntry;
331 } else {
332 break;
333 }
334 }
335 SetHelp(cSoftHdControl::Control()->Player()->Random ? "Random Play" : " No Random Play",
336 "Jump -1 min", "Jump +1 min", "End player");
337 Display();
338}
339
344{
345 struct dirent **dirList;
346 int n, i;
347
348 if ((n = scandir(cPlugin::ConfigDirectory("softhddevice-drm-gles"), &dirList, NULL, alphasort)) == -1) {
349 LOGERROR("mediaplayer: %s: searching PL in %s failed (%d): %m", __FUNCTION__,
350 cPlugin::ConfigDirectory("softhddevice-drm-gles"), errno);
351 } else {
352 Clear();
353 for (i = 0; i < n; i++) {
354 if (dirList[i]->d_name[0] != '.' && (strcasestr(dirList[i]->d_name, ".M3U"))) {
355 Add(new cOsdItem(dirList[i]->d_name));
356 }
357 }
358 SetHelp("Play PL", NULL, NULL, NULL);
359 Display();
360 }
361}
362
369void cSoftHdMenu::FindFile(string searchPath, FILE *playlist)
370{
371 struct dirent **dirList;
372 int n, i;
373 const char * sp;
374
375 if (!searchPath.size())
376 sp = "/";
377 else sp = searchPath.c_str();
378
379 if (!playlist) {
380 Clear();
381 if (searchPath.size())
382 Add(new cOsdItem("[..]"));
383 }
384
385 if ((n = scandir(sp, &dirList, NULL, alphasort)) == -1) {
386 LOGERROR("mediaplayer: %s: scanning directory %s failed (%d): %m", __FUNCTION__, sp, errno);
387 } else {
388 struct stat fileAttributs;
389 for (i = 0; i < n; i++) {
390 string str = searchPath + "/" + dirList[i]->d_name;
391 if (stat(str.c_str(), &fileAttributs) == -1) {
392 LOGERROR("mediaplayer: %s: stat on %s failed (%d): %m", __FUNCTION__, str.c_str(), errno);
393 } else {
394 if (S_ISDIR(fileAttributs.st_mode) && dirList[i]->d_name[0] != '.') {
395 if (playlist) {
396 FindFile(str.c_str(), playlist);
397 } else {
398 Add(new cOsdItem(dirList[i]->d_name),
399 !m_lastItem.compare(0, m_lastItem.length(), dirList[i]->d_name));
400 }
401 }
402 }
403 }
404 for (i = 0; i < n; i++) {
405 string str = searchPath + "/" + dirList[i]->d_name;
406 if (stat(str.c_str(), &fileAttributs) == -1) {
407 LOGERROR("mediaplayer: %s: stat on %s failed (%d): %m", __FUNCTION__, str.c_str(), errno);
408 } else {
409 if (S_ISREG(fileAttributs.st_mode) && dirList[i]->d_name[0] != '.') {
410 if (playlist) {
411 if (TestMedia(dirList[i]->d_name))
412 fprintf(playlist, "%s/%s\n", searchPath.c_str(),
413 dirList[i]->d_name);
414 } else {
415 Add(new cOsdItem(dirList[i]->d_name));
416 }
417 }
418 }
419 }
420 }
421
422 if (!playlist) {
423 SetHelp( m_playlist.empty() ? "Play File" : "Play PL", "New PL", "Add to PL", NULL);
424// SetHelp(Control->Player->Running ? NULL : "Set new PL",
425// Control->Player->Running ? "Play Menu" : "Select PL");
426 Display();
427 }
428}
429
436void cSoftHdMenu::MakePlayList(const char * target, const char * mode)
437{
438 if (m_playlist.empty())
439 m_playlist = "/default.m3u"; // if (!Playlist) ???
440
441 string plPath = cPlugin::ConfigDirectory("softhddevice-drm-gles");
442 plPath.append(m_playlist.c_str());
443 FILE *playlist = fopen(plPath.c_str(), mode);
444
445 if (playlist != NULL) {
446 if (TestMedia(target)) {
447 fprintf(playlist, "%s/%s\n", m_path.c_str(), target);
448 } else {
449 string str = m_path + "/" + target;
450 FindFile(str.c_str(), playlist);
451 }
452 fclose (playlist);
453 }
454}
455
461void cSoftHdMenu::PlayMedia(const char *name)
462{
463 string aim = m_path + "/" + name;
465 cControl::Launch(new cSoftHdControl(aim.c_str(), m_pDevice));
466 } else {
467 LOGERROR("mediaplayer: %s: can't start %s", __FUNCTION__, aim.c_str());
468 }
469}
470
477int cSoftHdMenu::TestMedia(const char *name)
478{
479 if (strcasestr(name, ".MP3"))
480 return 1;
481 if (strcasestr(name, ".MP4"))
482 return 1;
483 if (strcasestr(name, ".MKV"))
484 return 1;
485 if (strcasestr(name, ".MPG"))
486 return 1;
487 if (strcasestr(name, ".AVI"))
488 return 1;
489 if (strcasestr(name, ".M2TS"))
490 return 1;
491 if (strcasestr(name, ".MPEG"))
492 return 1;
493 if (strcasestr(name, ".M3U"))
494 return 1;
495 if (strcasestr(name, ".TS"))
496 return 1;
497
498 return 0;
499}
Audio and alsa module header file.
static cSoftHdControl * Control()
Definition: mediaplayer.h:88
static cSoftHdPlayer * Player()
Definition: mediaplayer.h:89
void PipSwapPosition(void)
Swap pip between normal and alternative position.
void PipToggle(void)
Toggle picture-in-picture.
void PipChannelSwap(void)
Swap the pip channel with main live channel.
void PipChannelChange(int)
Change the pip channel.
static cSoftHdMenu * pSoftHdMenu
Definition: softhdmenu.h:40
void MainMenu(void)
Create main menu.
Definition: softhdmenu.cpp:107
string m_lastItem
Definition: softhdmenu.h:61
void PlayListMenu(void)
Create playlist menu.
Definition: softhdmenu.cpp:319
cSoftHdMenu(const char *, cSoftHdDevice *, int=0, int=0, int=0, int=0, int=0)
Softhddevice menu constructor.
Definition: softhdmenu.cpp:59
void SelectPL(void)
Create select playlist menu.
Definition: softhdmenu.cpp:343
virtual ~cSoftHdMenu()
Softhddevice menu destructor.
Definition: softhdmenu.cpp:79
string m_path
Definition: softhdmenu.h:60
virtual eOSState ProcessKey(eKeys)
Handle key event.
Definition: softhdmenu.cpp:172
void PlayMedia(const char *)
Play media file.
Definition: softhdmenu.cpp:461
HotkeyState m_hotkeyState
Definition: softhdmenu.h:50
void FindFile(string, FILE *)
Create sub menu find file or make a play list.
Definition: softhdmenu.cpp:369
void MakePlayList(const char *, const char *)
Make a play list.
Definition: softhdmenu.cpp:436
int TestMedia(const char *)
Test if it's a media file.
Definition: softhdmenu.cpp:477
void HandleHotKey(int)
Handle a key code which was compose by hotkey handling in ProcessKey()
Definition: softhdmenu.cpp:145
cSoftHdDevice * m_pDevice
Definition: softhdmenu.h:48
string m_playlist
Definition: softhdmenu.h:62
struct PLEntry * FirstEntry
Definition: mediaplayer.h:55
struct PLEntry * CurrentEntry
Definition: mediaplayer.h:56
void SetEntry(int)
Logger class header file.
#define LOGDEBUG2
Definition: logger.h:50
#define LOGERROR
Definition: logger.h:46
#define L_MEDIA
Definition: logger.h:66
Mediaplayer class header file.
Misc function header file.
int code
Definition: openglosd.h:58
Device class header file.
static cOsdItem * SeparatorName(const char *label)
Create a seperator item.
Definition: softhdmenu.cpp:89
PipHotkey
Definition: softhdmenu.cpp:133
@ PIPCHANNELSWAP
Definition: softhdmenu.cpp:138
@ PIPCHANNELDOWN
Definition: softhdmenu.cpp:137
@ PIPPOSITIONSWAP
Definition: softhdmenu.cpp:139
@ PIPTOGGLEONOFF
Definition: softhdmenu.cpp:135
@ PIPCHANNELUP
Definition: softhdmenu.cpp:136
@ PIPKEYBASE
Definition: softhdmenu.cpp:134
static cOsdItem * SeparatorSpace(void)
Create a seperator item.
Definition: softhdmenu.cpp:99
Softhddevice menu class header file.
@ Initial
Definition: softhdmenu.h:31
@ Blue
Definition: softhdmenu.h:32
string Folder
Definition: mediaplayer.h:29
string File
Definition: mediaplayer.h:28
string SubFolder
Definition: mediaplayer.h:30
struct PLEntry * NextEntry
Definition: mediaplayer.h:31
Videostream class header file.