From fee68b156a44418d8378e38cef40c747c320d7f6 Mon Sep 17 00:00:00 2001 From: Maniac Date: Mon, 6 Jul 2015 14:33:31 +0200 Subject: optical discs are now started using key red --- HISTORY | 3 + Makefile | 12 +++- README | 1 + filebrowser.c | 202 +++++++++++++++++++++++++++++++++++++++++++++------------- filebrowser.h | 6 +- mpv.c | 4 +- player.c | 19 ++---- playmenu.c | 92 -------------------------- playmenu.h | 25 -------- po/de_DE.po | 32 +++++----- 10 files changed, 200 insertions(+), 196 deletions(-) delete mode 100644 playmenu.c delete mode 100644 playmenu.h diff --git a/HISTORY b/HISTORY index a9d59aa..7d1ae7f 100644 --- a/HISTORY +++ b/HISTORY @@ -2,6 +2,9 @@ - added argument to override the main menu text - during playback show an option menu if the main menu entry is selected or key blue is pressed +- optical discs are now handled using the red key, the type (audio, dvd, br) + is detected automatically +- removed the first menu since it's now obsolete 2015-06-29: vdr-mpv-0.0.4 - start playback even when audio or video fails, this should give a better diff --git a/Makefile b/Makefile index 9ab30e1..3896dcb 100644 --- a/Makefile +++ b/Makefile @@ -15,11 +15,21 @@ PLUGIN = mpv # support refresh rate switching XRANDR ?= $(shell pkg-config --exists xrandr && echo 1) LIBMPV ?= $(shell pkg-config --exists mpv && echo 1) +LIBCDIO ?= $(shell pkg-config --exists libcdio && echo 1) +LIBMOUNT ?= $(shell pkg-config --exists mount && echo 1) ifneq ($(LIBMPV),1) $(error libmpv missing) endif +ifeq ($(LIBCDIO),1) +ifeq ($(LIBMOUNT),1) +CONFIG += -DUSE_DISC +LIBS += $(shell pkg-config --libs libcdio) +LIBS += $(shell pkg-config --libs mount) +endif +endif + ifeq ($(XRANDR),1) CONFIG += -DUSE_XRANDR LIBS += $(shell pkg-config --libs xrandr) @@ -74,7 +84,7 @@ DEFINES += -DPLUGIN_NAME_I18N='"$(PLUGIN)"' -D_GNU_SOURCE $(CONFIG) \ ### The object files (add further files here): -OBJS = $(PLUGIN).o config.o control.o filebrowser.o menu_options.o osd.o player.o playmenu.o setup.o status.o +OBJS = $(PLUGIN).o config.o control.o filebrowser.o menu_options.o osd.o player.o setup.o status.o ### The main target: diff --git a/README b/README index 97db120..50876ee 100644 --- a/README +++ b/README @@ -27,6 +27,7 @@ Requirements - VDR version >= 2.2.0 (earlier versions may work, but are untested) - libmpv >= 0.8.0 (earlier versions may work, but are untested) - xrandr (only needed for modeline switching) +- libcdio (only needed for optical disc playback) Installation ------------ diff --git a/filebrowser.c b/filebrowser.c index c187b40..287e7a6 100644 --- a/filebrowser.c +++ b/filebrowser.c @@ -2,6 +2,12 @@ #include #include +#ifdef USE_DISC +#include +#include +#include +#endif + #include "filebrowser.h" #include "mpv_service.h" @@ -12,10 +18,11 @@ using std::sort; string cMpvFilebrowser::currentDir = ""; string cMpvFilebrowser::currentItem = ""; -cMpvFilebrowser::cMpvFilebrowser(string RootDir) +cMpvFilebrowser::cMpvFilebrowser(string RootDir, string DiscDevice) :cOsdMenu("Filebrowser") { rootDir = RootDir; + discDevice = DiscDevice; if (currentDir == "") currentDir = rootDir; ShowDirectory(currentDir); @@ -61,7 +68,11 @@ void cMpvFilebrowser::ShowDirectory(string Path) if (rootDir != Path) MenuTitle += " (" + Path.substr(rootDir.size() + 1, string::npos) + ")"; SetTitle(MenuTitle.c_str()); +#ifdef USE_DISC + SetHelp("Disc", NULL, "Shuffle", NULL); +#else SetHelp(NULL, NULL, "Shuffle", NULL); +#endif Display(); } @@ -75,54 +86,66 @@ void cMpvFilebrowser::AddItem(string Path, string Text, bool IsDir) eOSState cMpvFilebrowser::ProcessKey(eKeys Key) { - //TODO since we get more and more Keys we should use switch again - if (Key == kOk) + string newPath = ""; + cMpvFilebrowserMenuItem *item; + eOSState State; + switch (Key) { - cMpvFilebrowserMenuItem *item = (cMpvFilebrowserMenuItem *) Get(Current()); - string newPath = item->Path() + "/" + item->Text(); - if (item->IsDirectory()) - { - currentDir = newPath; - currentItem = ""; - ShowDirectory(newPath); + case kOk: + item = (cMpvFilebrowserMenuItem *) Get(Current()); + newPath = item->Path() + "/" + item->Text(); + if (item->IsDirectory()) + { + currentDir = newPath; + currentItem = ""; + ShowDirectory(newPath); + return osContinue; + } + else + { + currentItem = item->Text(); + PlayFile(newPath); + return osEnd; + } + break; + + case kBack: + // we reached our root, so don't go back further and let VDR handle this (close submenu) + if (currentDir == rootDir) + return cOsdMenu::ProcessKey(Key); + currentItem = currentDir.substr(currentDir.find_last_of("/")+1, string::npos); + currentDir = currentDir.substr(0,currentDir.find_last_of("/")); + ShowDirectory(currentDir); return osContinue; - } - else - { + + case kLeft: + case kRight: + case kUp: + case kDown: + // first let VDR handle those keys or we get the previous item + State = cOsdMenu::ProcessKey(Key); + item = (cMpvFilebrowserMenuItem *) Get(Current()); currentItem = item->Text(); - PlayFile(newPath); - return osEnd; - } - } - else if (Key == kBack) - { - // we reached our root, so don't go back further and let VDR handle this (close submenu) - if (currentDir == rootDir) - return cOsdMenu::ProcessKey(Key); - currentItem = currentDir.substr(currentDir.find_last_of("/")+1, string::npos); - currentDir = currentDir.substr(0,currentDir.find_last_of("/")); - ShowDirectory(currentDir); - return osContinue; - } - else if (Key == kLeft || Key == kRight || Key == kUp || Key == kDown) - { - // first let VDR handle those keys or we get the previous item - eOSState State = cOsdMenu::ProcessKey(Key); - cMpvFilebrowserMenuItem *item = (cMpvFilebrowserMenuItem *) Get(Current()); - currentItem = item->Text(); return State; - } - else if (Key == kYellow) - { - cMpvFilebrowserMenuItem *item = (cMpvFilebrowserMenuItem *) Get(Current()); - string newPath = item->Path() + "/" + item->Text(); - if (!item->IsDirectory()) - { - currentItem = item->Text(); - PlayFile(newPath, true); - return osEnd; - } - return osContinue; + + case kRed: + if (PlayDisc()) + return osEnd; + break; + + case kYellow: + item = (cMpvFilebrowserMenuItem *) Get(Current()); + newPath = item->Path() + "/" + item->Text(); + if (!item->IsDirectory()) + { + currentItem = item->Text(); + PlayFile(newPath, true); + return osEnd; + } + return osContinue; + + default: + break; } return cOsdMenu::ProcessKey(Key); @@ -152,6 +175,95 @@ bool cMpvFilebrowser::PlayFile(string Filename, bool Shuffle) return false; } +// returns true if play is started, false otherwise +bool cMpvFilebrowser::PlayDisc() +{ +#ifdef USE_DISC + CdIo_t *hCdio = cdio_open(discDevice.c_str(), DRIVER_DEVICE); + discmode_t DiscMode = cdio_get_discmode(hCdio); + cdio_destroy(hCdio); + switch (DiscMode) + { + case CDIO_DISC_MODE_CD_DA: + PlayFile("cdda://"); + break; + + case CDIO_DISC_MODE_DVD_ROM: + case CDIO_DISC_MODE_DVD_RAM: + case CDIO_DISC_MODE_DVD_R: + case CDIO_DISC_MODE_DVD_RW: + case CDIO_DISC_MODE_HD_DVD_ROM: + case CDIO_DISC_MODE_HD_DVD_RAM: + case CDIO_DISC_MODE_HD_DVD_R: + case CDIO_DISC_MODE_DVD_PR: + case CDIO_DISC_MODE_DVD_PRW: + case CDIO_DISC_MODE_DVD_PRW_DL: + case CDIO_DISC_MODE_DVD_PR_DL: + case CDIO_DISC_MODE_DVD_OTHER: + if (!Mount(discDevice)) + break; + struct stat DirInfo; + if (stat("tmp/mpv_mount/VIDEO_TS", &DirInfo) == 0) + { + Unmount(); + return PlayFile("dvd://"); + } + else if (stat("tmp/mpv_mount/BDMV", &DirInfo) == 0) + { + Unmount(); + return PlayFile("bd://"); + } + Unmount(); + break; + + case CDIO_DISC_MODE_CD_XA: + case CDIO_DISC_MODE_CD_MIXED: + case CDIO_DISC_MODE_NO_INFO: + case CDIO_DISC_MODE_ERROR: + case CDIO_DISC_MODE_CD_I: + default: + break; + } +#endif +return false; +} + +bool cMpvFilebrowser::Mount(string Path) +{ +#ifdef USE_DISC + Unmount(); + string MountPoint = "/tmp/mpv_mount"; + if (mkdir(MountPoint.c_str(), S_IRWXU)) + { + dsyslog("[mpv] create mount point failed"); + return false; + } + + struct libmnt_context *hMount = mnt_new_context(); + mnt_context_set_source(hMount, Path.c_str()); + mnt_context_set_target(hMount, MountPoint.c_str()); + mnt_context_set_mflags(hMount, MS_RDONLY); + + int res = mnt_context_mount(hMount); + mnt_free_context(hMount); + if (res == 0) + return true; +#endif + return false; +} + +bool cMpvFilebrowser::Unmount() +{ +#ifdef USE_DISC + string MountPoint = "/tmp/mpv_mount"; + int res = umount(MountPoint.c_str()); + rmdir(MountPoint.c_str()); + if (res == 0) + return true; +#endif + return false; +} + cMpvFilebrowserMenuItem::cMpvFilebrowserMenuItem(string Path, string Item, bool IsDir) { isDir = IsDir; diff --git a/filebrowser.h b/filebrowser.h index 4eb3555..b1bc9c7 100644 --- a/filebrowser.h +++ b/filebrowser.h @@ -10,15 +10,19 @@ class cMpvFilebrowser:public cOsdMenu { private: string rootDir; + string discDevice; static string currentDir; static string currentItem; void ShowDirectory(string Path); void AddItem(string Path, string Text, bool IsDir); bool PlayFile(string Filename, bool Shuffle=false); + bool PlayDisc(); + bool Mount(string Path); + bool Unmount(); public: - cMpvFilebrowser(string RootDir); + cMpvFilebrowser(string RootDir, string DiscDevice); virtual eOSState ProcessKey(eKeys Key); static string CurrentDir() { return currentDir; } }; diff --git a/mpv.c b/mpv.c index ffd8afd..101d2ed 100644 --- a/mpv.c +++ b/mpv.c @@ -13,8 +13,8 @@ #define CREATE_CONFIG 1 #include "config.h" #include "control.h" +#include "filebrowser.h" #include "setup.h" -#include "playmenu.h" #include "player.h" #include "menu_options.h" #include "mpv_service.h" @@ -68,7 +68,7 @@ cOsdObject *cMpvPlugin::MainMenuAction(void) { if (cMpvPlayer::PlayerIsRunning()) return new cMpvMenuOptions(cMpvPlayer::Player()); - return new cPlayMenu("MPV"); + return new cMpvFilebrowser(MpvPluginConfig->BrowserRoot, MpvPluginConfig->DiscDevice); } bool cMpvPlugin::Service(const char *id, void *data) diff --git a/player.c b/player.c index 92cc48a..f317aaa 100644 --- a/player.c +++ b/player.c @@ -62,7 +62,7 @@ void *cMpvPlayer::ObserverThread(void *handle) while (Player->PlayerIsRunning()) { - mpv_event *event = mpv_wait_event(Player->hMpv, 5); + mpv_event *event = mpv_wait_event(Player->hMpv, 10000); switch (event->event_id) { case MPV_EVENT_SHUTDOWN : @@ -87,18 +87,11 @@ void *cMpvPlayer::ObserverThread(void *handle) #endif break; - case MPV_EVENT_NONE : - if (!Player->IsPaused()) - { - // no event since 5 secons and not paused -> player died - Player->running = 0; - } - break; - case MPV_EVENT_TRACKS_CHANGED : Player->HandleTracksChange(); break; + case MPV_EVENT_NONE : case MPV_EVENT_END_FILE : case MPV_EVENT_PAUSE : case MPV_EVENT_UNPAUSE : @@ -204,7 +197,7 @@ void cMpvPlayer::PlayerStart() check_error(mpv_set_option_string(hMpv, "hwdec", MpvPluginConfig->HwDec.c_str())); check_error(mpv_set_option_string(hMpv, "ao", MpvPluginConfig->AudioOut.c_str())); check_error(mpv_set_option_string(hMpv, "hwdec-codecs", MpvPluginConfig->HwDec.c_str())); - check_error(mpv_set_option_string(hMpv, "slang", MpvPluginConfig->Languages.c_str())); // this can break br menu display + check_error(mpv_set_option_string(hMpv, "slang", MpvPluginConfig->Languages.c_str())); check_error(mpv_set_option_string(hMpv, "alang", MpvPluginConfig->Languages.c_str())); check_error(mpv_set_option_string(hMpv, "cache", "no")); // video stutters if enabled check_error(mpv_set_option_string(hMpv, "fullscreen", "yes")); @@ -212,6 +205,7 @@ void cMpvPlayer::PlayerStart() check_error(mpv_set_option_string(hMpv, "ontop", "yes")); check_error(mpv_set_option_string(hMpv, "cursor-autohide", "always")); check_error(mpv_set_option_string(hMpv, "stop-playback-on-init-failure", "no")); + check_error(mpv_set_option_string(hMpv, "idle", "once")); check_error(mpv_set_option(hMpv, "osd-level", MPV_FORMAT_INT64, &osdlevel)); if (MpvPluginConfig->UsePassthrough) @@ -232,10 +226,7 @@ void cMpvPlayer::PlayerStart() } if (PlayShuffle && IsPlaylist(PlayFilename)) - { - dsyslog("use shuffle\n"); check_error(mpv_set_option_string(hMpv, "shuffle", "yes")); - } #ifdef DEBUG mpv_request_log_messages(hMpv, "info"); @@ -246,7 +237,7 @@ void cMpvPlayer::PlayerStart() if (mpv_initialize(hMpv) < 0) { esyslog("[mpv] failed to initialize\n"); - cControl::Shutdown(); + return; } running = 1; diff --git a/playmenu.c b/playmenu.c deleted file mode 100644 index 2943e94..0000000 --- a/playmenu.c +++ /dev/null @@ -1,92 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// /// -/// This file is part of the VDR mpv plugin and licensed under AGPLv3 /// -/// /// -/// See the README file for copyright information /// -/// /// -////////////////////////////////////////////////////////////////////////////// - -#include "playmenu.h" -#include "config.h" -#include "mpv_service.h" -#include "filebrowser.h" - -////////////////////////////////////////////////////////////////////////////// -// cOsdMenu -////////////////////////////////////////////////////////////////////////////// - -cPlayMenu::cPlayMenu(const char *title, int c0, int c1, int c2, int c3, int c4) -:cOsdMenu(title, c0, c1, c2, c3, c4) -{ - SetHasHotkeys(); - - Add(new cOsdItem(hk(tr("Browse")), osUser1)); - Add(new cOsdItem(hk(tr("Play optical disc")), osUser2)); - Add(new cOsdItem("")); - Add(new cOsdItem("")); - Add(new cOsdItem(hk(tr("Play audio CD")), osUser5)); - Add(new cOsdItem(hk(tr("Play video DVD")), osUser6)); - - if (cMpvFilebrowser::CurrentDir() != "") - { - AddSubMenu(new cMpvFilebrowser(MpvPluginConfig->BrowserRoot.c_str())); - } -} - -cPlayMenu::~cPlayMenu() -{ -} - -/** -** Handle play plugin menu key event. -** -** @param key key event -*/ -eOSState cPlayMenu::ProcessKey(eKeys key) -{ - eOSState state; - - // call standard function - state = cOsdMenu::ProcessKey(key); - - switch (state) - { - case osUser1: - AddSubMenu(new cMpvFilebrowser(MpvPluginConfig->BrowserRoot.c_str())); - return osContinue; // restart with OSD browser - - case osUser2: - Skins.Message(mtStatus, - tr("Function not working yet, use 3 or 4")); - return osContinue; - - case osUser5: // play audio cdrom - PlayFile("cdda://"); - return osEnd; - - case osUser6: // play dvd - PlayFile("dvdnav://menu"); - return osEnd; - - default: - break; - } - return state; -} - -int cPlayMenu::PlayFile(const char *Filename) -{ - cPlugin *p; - p = cPluginManager::GetPlugin("mpv"); - if (p) - { - Mpv_StartPlayService_v1_0_t r; - r.Filename = (char *)Filename; - - return p->Service("Mpv-StartPlayService_v1_0", &r); - } - - return false; -} - - diff --git a/playmenu.h b/playmenu.h deleted file mode 100644 index 4844585..0000000 --- a/playmenu.h +++ /dev/null @@ -1,25 +0,0 @@ -////////////////////////////////////////////////////////////////////////////// -/// /// -/// This file is part of the VDR mpv plugin and licensed under AGPLv3 /// -/// /// -/// See the README file for copyright information /// -/// /// -////////////////////////////////////////////////////////////////////////////// - -#ifndef __MPV_BROWSER_H -#define __MPV_BROWSER_H - -#include - -class cPlayMenu:public cOsdMenu -{ - private: - public: - cPlayMenu(const char *, int = 0, int = 0, int = 0, int = 0, int = 0); - virtual ~ cPlayMenu(); - virtual eOSState ProcessKey(eKeys); - int PlayFile(const char *Filename); -}; - -#endif - diff --git a/po/de_DE.po b/po/de_DE.po index 9fdd83b..0e5e796 100644 --- a/po/de_DE.po +++ b/po/de_DE.po @@ -7,7 +7,7 @@ msgid "" msgstr "" "Project-Id-Version: vdr-mpv 0.0.3\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-07-04 09:14+0200\n" +"POT-Creation-Date: 2015-07-05 23:36+0200\n" "PO-Revision-Date: 2015-06-29 22:14+0200\n" "Last-Translator: Maniac\n" "Language-Team: Maniac\n" @@ -32,21 +32,6 @@ msgstr "Kapitel" msgid "mpv player plugin" msgstr "" -msgid "Browse" -msgstr "Durchsuchen" - -msgid "Play optical disc" -msgstr "CD/DVD/Bluray abspielen" - -msgid "Play audio CD" -msgstr "Audio CD" - -msgid "Play video DVD" -msgstr "DVD" - -msgid "Function not working yet, use 3 or 4" -msgstr "Funktion noch nicht eingebaut, bitte 3 oder 4 verwenden" - msgid "Hide main menu entry" msgstr "Hauptmenüeintrag verstecken" @@ -67,3 +52,18 @@ msgstr "Steuere die Playlist wenn keine Kapitel vorhanden" msgid "Show media title instead of filename" msgstr "Media Titel anstatt des Dateinamen anzeigen" + +#~ msgid "Browse" +#~ msgstr "Durchsuchen" + +#~ msgid "Play optical disc" +#~ msgstr "CD/DVD/Bluray abspielen" + +#~ msgid "Play audio CD" +#~ msgstr "Audio CD" + +#~ msgid "Play video DVD" +#~ msgstr "DVD" + +#~ msgid "Function not working yet, use 3 or 4" +#~ msgstr "Funktion noch nicht eingebaut, bitte 3 oder 4 verwenden" -- cgit v1.2.3