vdr-plugin-softhddevice-drm-gles 1.6.4-d0291bb
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
29 int c0, int c1, int c2, int c3, int c4)
30 : cOsdMenu(title, c0, c1, c2, c3, c4),
31 m_pDevice(device)
32{
33 pSoftHdMenu = this;
34 m_playlist.clear();
35
36 if (cSoftHdControl::Control() && cSoftHdControl::Control()->Player()->GetFirstPlaylistEntry()) {
37 LOGDEBUG2(L_MEDIA, "mediaplayer: %s: pointer to cSoftHdControl exist.", __FUNCTION__);
38 PlayListMenu(); // Test if PL!!!
39 } else {
40 MainMenu();
41 }
42}
43
48
56static inline cOsdItem *SeparatorName(const char *label)
57{
58 return new cOsdItem(cString::sprintf("%s:", label), osUnknown, false);
59}
60
68static inline cOsdItem *SeparatorSpace(void)
69{
70 return new cOsdItem(" ", osUnknown, false);
71}
72
77{
78 int current;
79
80 current = Current(); // get current menu item index
81 Clear(); // clear the menu
82
83 // pip
84 if (m_pDevice->UsePip()) {
85 Add(SeparatorName("PIP"));
86 Add(new cOsdItem(hk(tr(" Toggle")), osUser1));
87 Add(new cOsdItem(hk(tr(" Channel +")), osUser2));
88 Add(new cOsdItem(hk(tr(" Channel -")), osUser3));
89 Add(new cOsdItem(hk(tr(" Swap channels")), osUser4));
90 Add(new cOsdItem(hk(tr(" Swap position")), osUser5));
91 Add(new cOsdItem(hk(tr(" Switch to pip channel")), osUser6));
92 }
93
95
96 // detach
97 Add(SeparatorName("Detach"));
98 Add(new cOsdItem(hk(tr(" Detach device")), osUser7));
99
101
102 // mediaplayer
103 Add(SeparatorName("Mediaplayer"));
104 Add(new cOsdItem(hk(tr(" play file / make play list")), osUser8));
105 Add(new cOsdItem(hk(tr(" select play list")), osUser9));
106
107 SetCurrent(Get(current)); // restore selected menu entry
108 Display();
109}
110
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}
Playlist Entry.
Definition mediaplayer.h:34
Media Player Control.
static cSoftHdControl * Control()
Output Device Implementation.
void PipChannelSwap(bool)
void PipSwapPosition(void)
bool UsePip(void)
void Detach(void)
Detach the device.
void PipToggle(void)
void PipChannelChange(int)
void Attach(void)
Attach the device again.
void MainMenu(void)
Create main menu.
void PlayListMenu(void)
Create mediaplayer playlist menu.
std::string m_lastItem
Definition softhdmenu.h:68
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.
std::string m_playlist
Definition softhdmenu.h:69
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...
HotkeyState m_hotkeyState
Definition softhdmenu.h:57
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.
void HandleHotKey(int)
Handle a key code which was compose by hotkey handling in ProcessKey()
cSoftHdDevice * m_pDevice
Definition softhdmenu.h:55
void SelectPlaylistMenu(void)
Create mediaplayer select playlist menu.
std::string m_path
Definition softhdmenu.h:67
static cOsdItem * SeparatorName(const char *label)
Create a seperator item.
Hotkeys
Hotkeys.
static cOsdItem * SeparatorSpace(void)
Create a seperator item.
@ PIPCHANNELSWAP
@ PIPCHANNELDOWN
@ DETACHKEYBASE
@ PIPPOSITIONSWAP
@ PIPCHANNELSWITCHBACK
@ DETACHDEVICE
@ ATTACHDEVICE
@ PIPTOGGLEONOFF
@ PIPCHANNELUP
@ PIPKEYBASE
@ Initial
Definition softhdmenu.h:33
@ Red
Definition softhdmenu.h:35
@ Blue
Definition softhdmenu.h:34
#define LOGDEBUG2
log to LOG_DEBUG and add a prefix
Definition logger.h:47
#define LOGERROR
log to LOG_ERR
Definition logger.h:39
@ L_MEDIA
mediaplayer logs
Definition logger.h:64
static cSoftHdMenu * pSoftHdMenu
Main Menu Instance.
Definition softhdmenu.h:47
Logger Header File.
Mediaplayer Header File.
int code
Definition openglosd.h:33
Output Device Header File.
Plugin Main Menu Header File.