vdr-plugin-softhddevice-drm-gles 1.6.2
softhdmenu.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
13#include <string>
14
15#include <vdr/interface.h>
16#include <vdr/osdbase.h>
17#include <vdr/plugin.h>
18#include <vdr/videodir.h>
19
20#include "logger.h"
21#include "mediaplayer.h"
22#include "softhddevice.h"
23#include "softhdmenu.h"
24
38 int c0, int c1, int c2, int c3, int c4)
39 : cOsdMenu(title, c0, c1, c2, c3, c4),
40 m_pDevice(device)
41{
42 pSoftHdMenu = this;
43 m_playlist.clear();
44
45 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->GetFirstPlaylistEntry()) {
46 LOGDEBUG2(L_MEDIA, "mediaplayer: %s: pointer to cSoftHdControl exist.", __FUNCTION__);
47 PlayListMenu(); // Test if PL!!!
48 } else {
49 MainMenu();
50 }
51}
52
57
63static inline cOsdItem *SeparatorName(const char *label)
64{
65 return new cOsdItem(cString::sprintf("%s:", label), osUnknown, false);
66}
67
73static inline cOsdItem *SeparatorSpace(void)
74{
75 return new cOsdItem(" ", osUnknown, false);
76}
77
82{
83 int current;
84
85 current = Current(); // get current menu item index
86 Clear(); // clear the menu
87
88 // pip
89 if (m_pDevice->UsePip()) {
90 Add(SeparatorName("PIP"));
91 Add(new cOsdItem(hk(tr(" Toggle")), osUser1));
92 Add(new cOsdItem(hk(tr(" Channel +")), osUser2));
93 Add(new cOsdItem(hk(tr(" Channel -")), osUser3));
94 Add(new cOsdItem(hk(tr(" Swap channels")), osUser4));
95 Add(new cOsdItem(hk(tr(" Swap position")), osUser5));
96 Add(new cOsdItem(hk(tr(" Switch to pip channel")), osUser6));
97 }
98
100
101 // detach
102 Add(SeparatorName("Detach"));
103 Add(new cOsdItem(hk(tr(" Detach device")), osUser7));
104
106
107 // mediaplayer
108 Add(SeparatorName("Mediaplayer"));
109 Add(new cOsdItem(hk(tr(" play file / make play list")), osUser8));
110 Add(new cOsdItem(hk(tr(" select play list")), osUser9));
111
112 SetCurrent(Get(current)); // restore selected menu entry
113 Display();
114}
115
128
135 switch (code) {
136 // pip
137 case PIPTOGGLEONOFF:
139 break;
140 case PIPCHANNELUP:
142 break;
143 case PIPCHANNELDOWN:
145 break;
146 case PIPCHANNELSWAP:
148 break;
149 case PIPPOSITIONSWAP:
151 break;
154 break;
155 // detach/ attach
156 case DETACHDEVICE:
157 m_pDevice->Detach();
158 break;
159 case ATTACHDEVICE:
160 m_pDevice->Attach();
161 break;
162 default:
163 break;
164 }
165}
166
173{
174 eOSState state;
175 cOsdItem *item;
176
177 switch (m_hotkeyState) {
179 if (key == kBlue) {
180 if (!m_pDevice->UsePip())
181 return osEnd;
182
184 return osContinue;
185 }
186 if (key == kRed) {
188 return osContinue;
189 }
190 break;
191 case HotkeyState::Blue: // pip
192 if (k0 <= key && key <= k9) {
193 int hotkeyCode = PIPKEYBASE + key - k0;
196 return osEnd;
197 }
199 break;
200 case HotkeyState::Red: // detach/ attach
201 if (k0 <= key && key <= k9) {
202 int hotkeyCode = DETACHKEYBASE + key - k0;
205 return osEnd;
206 }
208 break;
209 }
210
211 item = (cOsdItem *) Get(Current());
212 state = cOsdMenu::ProcessKey(key);
213
214 switch (state) {
215 // pip
216 case osUser1: // toggle pip
218 return osEnd;
219 case osUser2: // pip channel +
221 return osEnd;
222 case osUser3: // pip channel -
224 return osEnd;
225 case osUser4: // pip channel swap
227 return osEnd;
228 case osUser5: // pip position swap
230 return osEnd;
231 case osUser6: // pip switch main stream back to pip stream and close pip
233 return osEnd;
234
235 // detach
236 case osUser7: // detach device
237 m_pDevice->Detach();
238 return osEnd;
239
240 // mediaplayer
241 case osUser8: // play file / make play list
242 m_path = cVideoDirectory::Name();
244 return osContinue;
245 case osUser9: // select play list
246 m_path = cPlugin::ConfigDirectory("softhddevice-drm-gles");
248 return osContinue;
249 default:
250 break;
251 }
252
253 switch (key) {
254 case kOk:
255 if (strcasestr(item->Text(), "[..]")) {
256 std::string newPath = m_path.substr(0 ,m_path.find_last_of("/"));
257
258 if (!m_lastItem.empty())
259 m_lastItem.clear();
260 m_lastItem = m_path.substr(m_path.find_last_of("/") + 1);
261
262 m_path = newPath;
263 FindFileMenu(m_path.c_str(), NULL);
264 break;
265 }
266 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->GetCurrentPlaylistEntry()) {
267 cSoftHdControl::Control()->Player()->SetEntry(Current());
268// PlayListMenu();
269 break;
270 }
271 if (IsValidMediaFile(item->Text())) {
272 PlayMedia(item->Text());
273 return osEnd;
274 } else {
275 std::string newPath = m_path + "/" + item->Text();
276 struct stat sb;
277 if (stat(newPath.c_str(), &sb) == 0 && S_ISDIR(sb.st_mode)) {
278 m_path = newPath;
279 FindFileMenu(newPath.c_str(), NULL);
280 }
281 }
282 break;
283 case kRed:
284 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->GetCurrentPlaylistEntry()) {
285 cSoftHdControl::Control()->Player()->ToggleRandomPlay();
286 PlayListMenu();
287 break;
288 }
289 if (m_playlist.empty()) {
290 if (IsValidMediaFile(item->Text())) {
291 PlayMedia(item->Text());
292 return osEnd;
293 }
294 } else {
295 m_path = cPlugin::ConfigDirectory("softhddevice-drm-gles");
296 PlayMedia(m_playlist.c_str());
297 return osEnd;
298 }
299 break;
300 case kGreen:
302 cSoftHdControl::Control()->Player()->JumpSec(-60);
303 } else {
304 MakePlayList(item->Text(), "w");
305 Interface->Confirm(tr("New Playlist"), 1, true);
306 if (!m_lastItem.empty())
307 m_lastItem.clear();
308 m_lastItem = item->Text();
309 FindFileMenu(m_path.c_str(), NULL);
310 }
311 break;
312 case kYellow:
314 cSoftHdControl::Control()->Player()->JumpSec(60);
315 } else {
316 MakePlayList(item->Text(), "a");
317 Interface->Confirm(tr("Added to Playlist"), 1, true);
318 }
319 break;
320 case kBlue:
321 state = osStopReplay;
322 break;
323 case kPlay:
324 if (IsValidMediaFile(item->Text())) {
325 PlayMedia(item->Text());
326 return osEnd;
327 }
328 break;
329 case kNext:
331 cSoftHdControl::Control()->Player()->Stop();
332 break;
333 default:
334 break;
335 }
336
337 return state;
338}
339
340/*****************************************************************************
341 * Mediaplayer sub menus
342 ****************************************************************************/
343
348{
349 cPlaylistEntry *entry = cSoftHdControl::Control()->Player()->GetFirstPlaylistEntry();
350 Clear();
351 while (1) {
352 std::string p_string = entry->OsdItemString();
353 Add(new cOsdItem(p_string.c_str()), (entry == cSoftHdControl::Control()->Player()->GetCurrentPlaylistEntry()));
354
355 if (!entry->GetNextEntry())
356 break;
357
358 entry = entry->GetNextEntry();
359 }
360 SetHelp(cSoftHdControl::Control()->Player()->IsRandomPlayActive() ? "Random Play" : " No Random Play",
361 "Jump -1 min", "Jump +1 min", "End player");
362 Display();
363}
364
369{
370 struct dirent **dirList;
371 int n, i;
372
373 if ((n = scandir(cPlugin::ConfigDirectory("softhddevice-drm-gles"), &dirList, NULL, alphasort)) == -1) {
374 LOGERROR("mediaplayer: %s: searching PL in %s failed (%d): %m", __FUNCTION__,
375 cPlugin::ConfigDirectory("softhddevice-drm-gles"), errno);
376 return;
377 }
378
379 Clear();
380 for (i = 0; i < n; i++) {
381 if (dirList[i]->d_name[0] != '.' && (strcasestr(dirList[i]->d_name, ".M3U"))) {
382 Add(new cOsdItem(dirList[i]->d_name));
383 }
384 }
385 SetHelp("Play PL", NULL, NULL, NULL);
386 Display();
387}
388
396{
397 struct dirent **dirList;
398 int n, i;
399 const char * sp;
400
401 if (!searchPath.size())
402 sp = "/";
403 else
404 sp = searchPath.c_str();
405
406 if (!playlist) {
407 Clear();
408 if (searchPath.size())
409 Add(new cOsdItem("[..]"));
410 }
411
412 if ((n = scandir(sp, &dirList, NULL, alphasort)) == -1) {
413 LOGERROR("mediaplayer: %s: scanning directory %s failed (%d): %m", __FUNCTION__, sp, errno);
414 } else {
415 struct stat fileAttributs;
416 for (i = 0; i < n; i++) {
417 std::string str = searchPath + "/" + dirList[i]->d_name;
418 if (stat(str.c_str(), &fileAttributs) == -1) {
419 LOGERROR("mediaplayer: %s: stat on %s failed (%d): %m", __FUNCTION__, str.c_str(), errno);
420 } else {
421 if (S_ISDIR(fileAttributs.st_mode) && dirList[i]->d_name[0] != '.') {
422 if (playlist) {
423 FindFileMenu(str.c_str(), playlist);
424 } else {
425 Add(new cOsdItem(dirList[i]->d_name),
426 !m_lastItem.compare(0, m_lastItem.length(), dirList[i]->d_name));
427 }
428 }
429 }
430 }
431 for (i = 0; i < n; i++) {
432 std::string str = searchPath + "/" + dirList[i]->d_name;
433 if (stat(str.c_str(), &fileAttributs) == -1) {
434 LOGERROR("mediaplayer: %s: stat on %s failed (%d): %m", __FUNCTION__, str.c_str(), errno);
435 } else {
436 if (S_ISREG(fileAttributs.st_mode) && dirList[i]->d_name[0] != '.') {
437 if (playlist) {
439 fprintf(playlist, "%s/%s\n", searchPath.c_str(),
440 dirList[i]->d_name);
441 } else {
442 Add(new cOsdItem(dirList[i]->d_name));
443 }
444 }
445 }
446 }
447 }
448
449 if (!playlist) {
450 SetHelp( m_playlist.empty() ? "Play File" : "Play PL", "New PL", "Add to PL", NULL);
451// SetHelp(Control->Player->Running ? NULL : "Set new PL",
452// Control->Player->Running ? "Play Menu" : "Select PL");
453 Display();
454 }
455}
456
463void cSoftHdMenu::MakePlayList(const char * target, const char * mode)
464{
465 if (m_playlist.empty())
466 m_playlist = "/default.m3u";
467
468 std::string plPath = cPlugin::ConfigDirectory("softhddevice-drm-gles");
469 plPath.append(m_playlist.c_str());
470 FILE *playlist = fopen(plPath.c_str(), mode);
471
472 if (!playlist)
473 return;
474
476 fprintf(playlist, "%s/%s\n", m_path.c_str(), target);
477 } else {
478 std::string str = m_path + "/" + target;
479 FindFileMenu(str.c_str(), playlist);
480 }
481
483}
484
490void cSoftHdMenu::PlayMedia(const char *name)
491{
492 std::string aim = m_path + "/" + name;
494 cControl::Launch(new cSoftHdControl(aim.c_str(), m_pDevice));
495 } else {
496 LOGERROR("mediaplayer: %s: can't start %s", __FUNCTION__, aim.c_str());
497 }
498}
499
506bool cSoftHdMenu::IsValidMediaFile(const char *name)
507{
508 if (strcasestr(name, ".MP3") ||
509 strcasestr(name, ".MP4") ||
510 strcasestr(name, ".MKV") ||
511 strcasestr(name, ".MPG") ||
512 strcasestr(name, ".AVI") ||
513 strcasestr(name, ".M2TS") ||
514 strcasestr(name, ".MPEG") ||
515 strcasestr(name, ".M3U") ||
516 strcasestr(name, ".TS")) {
517
518 return true;
519 }
520
521 return false;
522}
523
Playlist Entry.
Definition mediaplayer.h:33
Media Player Control.
static cSoftHdControl * Control()
Output Device Implementation.
bool UsePip(void)
std::string m_lastItem
Definition softhdmenu.h:61
std::string m_playlist
Definition softhdmenu.h:62
HotkeyState m_hotkeyState
Definition softhdmenu.h:50
cSoftHdDevice * m_pDevice
Definition softhdmenu.h:48
std::string m_path
Definition softhdmenu.h:60
void PipChannelSwap(bool)
void PipSwapPosition(void)
void Detach(void)
Detach the device.
void PipToggle(void)
void PipChannelChange(int)
void Attach(void)
Attach the device again.
static cOsdItem * SeparatorName(const char *label)
Create a seperator item.
void MainMenu(void)
Create main menu.
Hotkeys
void PlayListMenu(void)
Create mediaplayer playlist menu.
cSoftHdMenu(const char *, cSoftHdDevice *, int=0, int=0, int=0, int=0, int=0)
Build main or playlist menu.
virtual ~cSoftHdMenu()
virtual eOSState ProcessKey(eKeys)
Handle key event.
void PlayMedia(const char *)
Play media file.
bool IsValidMediaFile(const char *)
Test if it's a media file - at least if it has the right file extension...
void MakePlayList(const char *, const char *)
Make a play list.
void FindFileMenu(std::string, FILE *)
Create mediaplayer sub menu find file or make a play list.
static cOsdItem * SeparatorSpace(void)
Create a seperator item.
void HandleHotKey(int)
Handle a key code which was compose by hotkey handling in ProcessKey()
void SelectPlaylistMenu(void)
Create mediaplayer select playlist menu.
@ PIPCHANNELSWAP
@ PIPCHANNELDOWN
@ DETACHKEYBASE
@ PIPPOSITIONSWAP
@ PIPCHANNELSWITCHBACK
@ DETACHDEVICE
@ ATTACHDEVICE
@ PIPTOGGLEONOFF
@ PIPCHANNELUP
@ PIPKEYBASE
@ Initial
Definition softhdmenu.h:28
@ Red
Definition softhdmenu.h:30
@ Blue
Definition softhdmenu.h:29
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
Definition logger.h:42
#define LOGERROR
log to LOG_ERR
Definition logger.h:34
@ L_MEDIA
mediaplayer logs
Definition logger.h:59
static cSoftHdMenu * pSoftHdMenu
Definition softhdmenu.h:40
Logger Header File.
Mediaplayer Header File.
int code
Definition openglosd.h:33
Output Device Header File.
Plugin Main Menu Header File.