From b8d398a69a19b3ab6870947d19fc1bb033c5d688 Mon Sep 17 00:00:00 2001 From: "[CST] Focus" Date: Sat, 27 Sep 2014 16:19:52 +0400 Subject: [PATCH] gui/moviebrowser.cpp: add support for non-TS/xml files, idea (c) martii --- data/locale/deutsch.locale | 1 + data/locale/english.locale | 1 + src/gui/moviebrowser.cpp | 151 ++++++++++++++++++++++++------------- src/gui/moviebrowser.h | 7 +- src/gui/movieinfo.h | 2 +- src/gui/movieplayer.cpp | 32 +++++--- src/system/locals.h | 1 + src/system/locals_intern.h | 1 + 8 files changed, 127 insertions(+), 69 deletions(-) diff --git a/data/locale/deutsch.locale b/data/locale/deutsch.locale index 5ad096c69..5e70efeb8 100644 --- a/data/locale/deutsch.locale +++ b/data/locale/deutsch.locale @@ -1594,6 +1594,7 @@ moviebrowser.short_size Grösse moviebrowser.short_title Titel moviebrowser.start_head Film starten von Position: moviebrowser.start_record_start Aufnahmestart +moviebrowser.ts_only Nur Aufnahmen zeigen moviebrowser.update_if_dest_empty_only Übernehmen nur wenn Ziel leer moviebrowser.use_dir Verzeichnis verwenden moviebrowser.use_movie_dir Wiedergabeverzeichnis verwenden diff --git a/data/locale/english.locale b/data/locale/english.locale index 737ba251d..306627cbb 100644 --- a/data/locale/english.locale +++ b/data/locale/english.locale @@ -1594,6 +1594,7 @@ moviebrowser.short_size MB moviebrowser.short_title Title moviebrowser.start_head Start movie from: moviebrowser.start_record_start Movie start +moviebrowser.ts_only Show recordings only moviebrowser.update_if_dest_empty_only Copy if destination is empty only moviebrowser.use_dir Use directory moviebrowser.use_movie_dir Use movie directory diff --git a/src/gui/moviebrowser.cpp b/src/gui/moviebrowser.cpp index 86f2df593..a690d1c77 100644 --- a/src/gui/moviebrowser.cpp +++ b/src/gui/moviebrowser.cpp @@ -549,6 +549,7 @@ void CMovieBrowser::initGlobalSettings(void) m_settings.browserRowWidth[4] = m_defaultRowWidth[m_settings.browserRowItem[4]]; //30; m_settings.browserRowWidth[5] = m_defaultRowWidth[m_settings.browserRowItem[5]]; //30; + m_settings.ts_only = 1; m_settings.ytmode = cYTFeedParser::MOST_POPULAR; m_settings.ytorderby = cYTFeedParser::ORDERBY_PUBLISHED; m_settings.ytresults = 10; @@ -668,6 +669,7 @@ bool CMovieBrowser::loadSettings(MB_SETTINGS* settings) settings->lastRecordMaxItems = configfile.getInt32("mb_lastRecordMaxItems", NUMBER_OF_MOVIES_LAST); settings->browser_serie_mode = configfile.getInt32("mb_browser_serie_mode", 0); settings->serie_auto_create = configfile.getInt32("mb_serie_auto_create", 0); + settings->ts_only = configfile.getInt32("mb_ts_only", 1); settings->sorting.item = (MB_INFO_ITEM)configfile.getInt32("mb_sorting_item", MB_INFO_RECORDDATE); settings->sorting.direction = (MB_DIRECTION)configfile.getInt32("mb_sorting_direction", MB_DIRECTION_UP); @@ -730,6 +732,7 @@ bool CMovieBrowser::saveSettings(MB_SETTINGS* settings) configfile.setInt32("mb_lastRecordMaxItems", settings->lastRecordMaxItems); configfile.setInt32("mb_browser_serie_mode", settings->browser_serie_mode); configfile.setInt32("mb_serie_auto_create", settings->serie_auto_create); + configfile.setInt32("mb_ts_only", settings->ts_only); configfile.setInt32("mb_gui", settings->gui); @@ -935,6 +938,8 @@ int CMovieBrowser::exec(const char* path) refreshTitle(); refreshFoot(); refreshLCD(); + if (m_settings.gui == MB_GUI_FILTER) + m_settings.gui = MB_GUI_MOVIE_INFO; onSetGUIWindow(m_settings.gui); bool loop = true; @@ -1180,12 +1185,17 @@ bool CMovieBrowser::getSelectedFiles(CFileList &flist, P_MI_MOVIE_LIST &mlist) return (!flist.empty()); } -std::string CMovieBrowser::getScreenshotName(std::string movie) +std::string CMovieBrowser::getScreenshotName(std::string movie, bool is_dir) { std::string ext; std::string ret; + size_t found; + + if (is_dir) + found = movie.size(); + else + found = movie.find_last_of("."); - size_t found = movie.find_last_of("."); if (found == string::npos) return ""; @@ -1193,7 +1203,7 @@ std::string CMovieBrowser::getScreenshotName(std::string movie) while (it < PicExts.end()) { ret = movie; ext = *it; - ret.replace(found, ext.length(), ext); + ret.replace(found, ret.length() - found, ext); ++it; if (!access(ret, F_OK)) return ret; @@ -1215,7 +1225,7 @@ void CMovieBrowser::refreshMovieInfo(void) if (show_mode == MB_SHOW_YT) { fname = m_movieSelectionHandler->tfile; } else { - fname = getScreenshotName(m_movieSelectionHandler->file.Name); + fname = getScreenshotName(m_movieSelectionHandler->file.Name, S_ISDIR(m_movieSelectionHandler->file.Mode)); if ((fname.empty()) && (m_movieSelectionHandler->file.Name.length() > 18)) { std::string cover = m_movieSelectionHandler->file.Name; cover.replace((cover.length()-18),15,""); //covername without yyyymmdd_hhmmss @@ -1269,7 +1279,7 @@ void CMovieBrowser::refreshMovieInfo(void) newHeader = false; } - if (logo_ok) { + if (m_settings.gui == MB_GUI_MOVIE_INFO && logo_ok) { lx = m_cBoxFrameInfo.iX+m_cBoxFrameInfo.iWidth - flogo_w -14; ly = m_cBoxFrameInfo.iY - 1 + (m_cBoxFrameInfo.iHeight-flogo_h)/2; g_PicViewer->DisplayImage(fname, lx+2, ly+1, flogo_w, flogo_h, CFrameBuffer::TM_NONE); @@ -1822,7 +1832,7 @@ bool CMovieBrowser::onButtonPressMainFrame(neutrino_msg_t msg) } else if (msg == CRCInput::RC_favorites) { if (m_movieSelectionHandler != NULL) { if (ShowMsg(LOCALE_MESSAGEBOX_INFO, "Remove screenshot ?", CMessageBox::mbrNo, CMessageBox:: mbYes | CMessageBox::mbNo) == CMessageBox::mbrYes) { - std::string fname = getScreenshotName(m_movieSelectionHandler->file.Name); + std::string fname = getScreenshotName(m_movieSelectionHandler->file.Name, S_ISDIR(m_movieSelectionHandler->file.Mode)); if (fname != "") unlink(fname.c_str()); refresh(); @@ -2055,7 +2065,7 @@ void CMovieBrowser::onDeleteFile(MI_MOVIE_INFO& movieSelectionHandler, bool skip hintBox->paint(); delFile(movieSelectionHandler.file); - std::string fname = getScreenshotName(movieSelectionHandler.file.Name); + std::string fname = getScreenshotName(movieSelectionHandler.file.Name, S_ISDIR(m_movieSelectionHandler->file.Mode)); if (!fname.empty()) unlink(fname.c_str()); @@ -2299,6 +2309,53 @@ void CMovieBrowser::loadAllTsFileNamesFromStorage(void) TRACE("[mb] Dir%d, Files:%d\n", (int)m_dirNames.size(), (int)m_vMovieInfo.size()); } +static const char * const ext_list[] = +{ + "avi", "mkv", "mpg", "mpeg", "m2ts", "mp4", "mov", "flv", "iso" +}; + +static int ext_list_size = sizeof(ext_list) / sizeof (char *); + +bool CMovieBrowser::supportedExtension(CFile &file) +{ + std::string::size_type idx = file.getFileName().rfind('.'); + + if (idx == std::string::npos) + return false; + + std::string ext = file.getFileName().substr(idx+1); + bool result = (ext == "ts"); + if (!result && !m_settings.ts_only) { + for (int i = 0; i < ext_list_size; i++) { + if (ext == ext_list[i]) { + result = true; + break; + } + } + } + return result; +} + +bool CMovieBrowser::addFile(CFile &file, int dirItNr) +{ + if (!S_ISDIR(file.Mode) && !supportedExtension(file)) { + //TRACE("[mb] not supported file: '%s'\n", file.Name.c_str()); + return false; + } + + MI_MOVIE_INFO movieInfo; + + movieInfo.file = file; + if(!m_movieInfo.loadMovieInfo(&movieInfo)) { + movieInfo.epgChannel = string(g_Locale->getText(LOCALE_MOVIEPLAYER_HEAD)); + movieInfo.epgTitle = file.getFileName(); + } + movieInfo.dirItNr = dirItNr; + //TRACE("addFile dir [%s] : [%s]\n", m_dirNames[movieInfo.dirItNr].c_str(), movieInfo.file.Name.c_str()); + m_vMovieInfo.push_back(movieInfo); + return true; +} + /************************************************************************ Note: this function is used recursive, do not add any return within the body due to the recursive counter ************************************************************************/ @@ -2308,7 +2365,6 @@ bool CMovieBrowser::loadTsFileNamesFromDir(const std::string & dirname) static int recursive_counter = 0; // recursive counter to be used to avoid hanging bool result = false; - int file_found_in_dir = false; if (recursive_counter > 10) { @@ -2317,8 +2373,7 @@ bool CMovieBrowser::loadTsFileNamesFromDir(const std::string & dirname) } /* check if directory was already searched once */ - int size = m_dirNames.size(); - for (int i = 0; i < size; i++) + for (int i = 0; i < (int) m_dirNames.size(); i++) { if (strcmp(m_dirNames[i].c_str(),dirname.c_str()) == 0) { @@ -2327,51 +2382,33 @@ bool CMovieBrowser::loadTsFileNamesFromDir(const std::string & dirname) return (false); } } + /* FIXME hack to fix movie dir path on recursive scan. + dirs without files but with subdirs with files will be shown in path filter */ + m_dirNames.push_back(dirname); + int dirItNr = m_dirNames.size() - 1; + /* !!!!!! no return statement within the body after here !!!!*/ recursive_counter++; CFileList flist; if (readDir(dirname, &flist) == true) { - MI_MOVIE_INFO movieInfo; for (unsigned int i = 0; i < flist.size(); i++) { - if (S_ISDIR(flist[i].Mode)) - { - flist[i].Name += '/'; - //TRACE("[mb] Dir: '%s'\n",movieInfo.file.Name.c_str()); - loadTsFileNamesFromDir(flist[i].Name); - } - else - { - int test=flist[i].getFileName().find(".ts",flist[i].getFileName().length()-3); - if (test == -1) - { - //TRACE("[mb] other file: '%s'\n",movieInfo.file.Name.c_str()); - } - else - { - movieInfo.clear(); - movieInfo.file.Name = flist[i].Name; - if (m_movieInfo.loadMovieInfo(&movieInfo)) { //FIXME atm we show only ts+xml (records) here - movieInfo.file.Mode = flist[i].Mode; - movieInfo.file.Size = flist[i].Size; - movieInfo.file.Time = flist[i].Time; - if (file_found_in_dir == false) - { - // first file in directory found, add directory to list - m_dirNames.push_back(dirname); - file_found_in_dir = true; - //TRACE("[mb] new dir: :%s\n",dirname); - } - movieInfo.dirItNr = m_dirNames.size()-1; - m_vMovieInfo.push_back(movieInfo); - } - } + if (S_ISDIR(flist[i].Mode)) { + if (m_settings.ts_only || !CFileBrowser::checkBD(flist[i])) { + flist[i].Name += '/'; + result |= loadTsFileNamesFromDir(flist[i].Name); + } else + result |= addFile(flist[i], dirItNr); + } else { + result |= addFile(flist[i], dirItNr); } } - result = true; + //result = true; } + if (!result) + m_dirNames.pop_back(); recursive_counter--; return (result); @@ -2742,7 +2779,7 @@ int CMovieBrowser::showMovieInfoMenu(MI_MOVIE_INFO* movie_info) return res; } -bool CMovieBrowser::showMenu(MI_MOVIE_INFO* /*movie_info*/) +bool CMovieBrowser::showMenu(MI_MOVIE_INFO* /* movie_info */, bool calledExternally) { /* first clear screen */ framebuffer->paintBackground(); @@ -2830,6 +2867,9 @@ bool CMovieBrowser::showMenu(MI_MOVIE_INFO* /*movie_info*/) optionsMenu.addItem(GenericMenuSeparatorLine); optionsMenu.addItem(new CMenuOptionChooser(LOCALE_MOVIEBROWSER_HIDE_SERIES, (int*)(&m_settings.browser_serie_mode), MESSAGEBOX_YES_NO_OPTIONS, MESSAGEBOX_YES_NO_OPTIONS_COUNT, true)); optionsMenu.addItem(new CMenuOptionChooser(LOCALE_MOVIEBROWSER_SERIE_AUTO_CREATE, (int*)(&m_settings.serie_auto_create), MESSAGEBOX_YES_NO_OPTIONS, MESSAGEBOX_YES_NO_OPTIONS_COUNT, true)); + int ts_only = m_settings.ts_only; + optionsMenu.addItem( new CMenuOptionChooser(LOCALE_MOVIEBROWSER_TS_ONLY, (int*)(&m_settings.ts_only), MESSAGEBOX_YES_NO_OPTIONS, MESSAGEBOX_YES_NO_OPTIONS_COUNT, true )); + //optionsMenu.addItem(GenericMenuSeparator); /********************************************************************/ @@ -2870,16 +2910,19 @@ bool CMovieBrowser::showMenu(MI_MOVIE_INFO* /*movie_info*/) m_settings.browserRowWidth[i] = 1; } - if (dirMenu.isChanged()) - loadMovies(); + if (!calledExternally) { + if (ts_only != m_settings.ts_only || dirMenu.isChanged()) + loadMovies(); - updateSerienames(); - refreshBrowserList(); - refreshLastPlayList(); - refreshLastRecordList(); - refreshFilterList(); - refreshMovieInfo(); - refresh(); + updateSerienames(); + refreshBrowserList(); + refreshLastPlayList(); + refreshLastRecordList(); + refreshFilterList(); + refreshMovieInfo(); + refresh(); + } else + saveSettings(&m_settings); for (i = 0; i < MB_MAX_DIRS; i++) delete notifier[i]; diff --git a/src/gui/moviebrowser.h b/src/gui/moviebrowser.h index 4c327de7f..bddfca3fc 100644 --- a/src/gui/moviebrowser.h +++ b/src/gui/moviebrowser.h @@ -209,6 +209,7 @@ typedef struct int reload; int remount; + int ts_only; int browser_serie_mode; int serie_auto_create; @@ -334,7 +335,7 @@ class CMovieBrowser : public CMenuTarget int movieInfoUpdateAllIfDestEmptyOnly; std::vector PicExts; - std::string getScreenshotName(std::string movie); + std::string getScreenshotName(std::string movie, bool is_dir = false); int menu_ret; @@ -429,7 +430,7 @@ class CMovieBrowser : public CMenuTarget void getStorageInfo(void); // P3 ///// Menu //////////////////////////////////// - bool showMenu(MI_MOVIE_INFO* movie_info); // P2 + bool showMenu(MI_MOVIE_INFO* movie_info, bool calledExternally = false); // P2 int showMovieInfoMenu(MI_MOVIE_INFO* movie_info); // P2 int showStartPosSelectionMenu(void); // P2 @@ -458,6 +459,8 @@ class CMovieBrowser : public CMenuTarget neutrino_locale_t getFeedLocale(void); void clearListLines(); void clearSelection(); + bool supportedExtension(CFile &file); + bool addFile(CFile &file, int dirItNr); }; // Class to show Moviebrowser Information, to be used by menu diff --git a/src/gui/movieinfo.h b/src/gui/movieinfo.h index 00168a231..4901dd0de 100644 --- a/src/gui/movieinfo.h +++ b/src/gui/movieinfo.h @@ -156,7 +156,7 @@ class MI_MOVIE_INFO std::string serieName; // user defines series name time_t dateOfLastPlay; // last play date of movie in seconds since 1970 - char dirItNr; // handle for quick directory path access only, this is not saved in xml, might be used by the owner of the movie info struct + int dirItNr; // handle for quick directory path access only, this is not saved in xml, might be used by the owner of the movie info struct int genreMajor; // see showEPG class for more info, usually filled by EPG char genreMinor; // genreMinor not used so far int length; // movie length in minutes, usually filled by EPG diff --git a/src/gui/movieplayer.cpp b/src/gui/movieplayer.cpp index ff63b168f..9c4f60353 100644 --- a/src/gui/movieplayer.cpp +++ b/src/gui/movieplayer.cpp @@ -341,6 +341,13 @@ void CMoviePlayerGui::fillPids() if (p_movie_info == NULL) return; + vpid = p_movie_info->epgVideoPid; + vtype = p_movie_info->VideoType; + /* FIXME: better way to detect TS recording */ + if (!vpid) { + is_file_player = true; + return; + } numpida = 0; currentapid = 0; if (!p_movie_info->audioPids.empty()) { currentapid = p_movie_info->audioPids[0].epgAudioPid; @@ -355,8 +362,6 @@ void CMoviePlayerGui::fillPids() currentac3 = p_movie_info->audioPids[i].atype; } } - vpid = p_movie_info->epgVideoPid; - vtype = p_movie_info->VideoType; } void CMoviePlayerGui::Cleanup() @@ -432,6 +437,7 @@ bool CMoviePlayerGui::prepareFile(CFile *file) numpida = 0; currentapid = 0; currentspid = -1; numsubs = 0; + autoshot_done = 0; file_name = file->Name; if (isMovieBrowser) { if (filelist_it != filelist.end()) { @@ -444,10 +450,10 @@ bool CMoviePlayerGui::prepareFile(CFile *file) } fillPids(); } + if (file->getType() == CFile::FILE_ISO) + ret = mountIso(file); else if (file->getType() == CFile::FILE_PLAYLIST) parsePlaylist(file); - else if (file->getType() == CFile::FILE_ISO) - ret = mountIso(file); if (ret) makeFilename(); @@ -747,7 +753,7 @@ bool CMoviePlayerGui::PlayFileStart(void) } printf("******************* Timeshift %d, position %d, seek to %d seconds\n", timeshift, position, startposition/1000); } - if (!is_file_player && startposition >= 0)//FIXME no jump for file at start yet + if (/* !is_file_player && */ startposition >= 0)//FIXME no jump for file at start yet playback->SetPosition(startposition, true); /* playback->Start() starts paused */ @@ -1014,7 +1020,7 @@ void CMoviePlayerGui::PlayFileLoop(void) ClearQueue(); g_RCInput->postMsg(msg, data); } else if (msg == CRCInput::RC_timeout || msg == NeutrinoMessages::EVT_TIMER) { - if (playstate == CMoviePlayerGui::PLAY && (position >= 300000 || (duration<300000 && (position>(duration /2))))) + if (playstate == CMoviePlayerGui::PLAY && (position >= 300000 || (duration < 300000 && (position > (duration /2))))) makeScreenShot(true); } else if (msg == CRCInput::RC_favorites) { makeScreenShot(false, true); @@ -1036,7 +1042,7 @@ void CMoviePlayerGui::PlayFileLoop(void) printf("CMoviePlayerGui::PlayFile: exit, isMovieBrowser %d p_movie_info %x\n", isMovieBrowser, (int) p_movie_info); playstate = CMoviePlayerGui::STOPPED; handleMovieBrowser((neutrino_msg_t) g_settings.mpkey_stop, position); - if ((duration - position) > 600000) + if (position >= 300000 || (duration < 300000 && (position > (duration /2)))) makeScreenShot(true); if (at_eof && filelist.size() > 0) { @@ -1955,11 +1961,8 @@ bool CMoviePlayerGui::mountIso(CFile *file) void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover) { - if (autoshot) { - if (autoshot_done || !g_settings.auto_cover) - return; - autoshot_done = true; - } + if (autoshot && (autoshot_done || !g_settings.auto_cover)) + return; bool cover = autoshot || g_settings.screenshot_cover || forcover; char ending[(sizeof(int)*2) + 6] = ".jpg"; @@ -1967,6 +1970,9 @@ void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover) snprintf(ending, sizeof(ending) - 1, "_%x.jpg", position); std::string fname = file_name; + if (p_movie_info) + fname = p_movie_info->file.Name; + std::string::size_type pos = fname.find_last_of('.'); if (pos != std::string::npos) { fname.replace(pos, fname.length(), ending); @@ -1975,6 +1981,7 @@ void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover) if (autoshot && !access(fname.c_str(), F_OK)) { printf("CMoviePlayerGui::makeScreenShot: cover [%s] already exist..\n", fname.c_str()); + autoshot_done = true; return; } @@ -1987,6 +1994,7 @@ void CMoviePlayerGui::makeScreenShot(bool autoshot, bool forcover) CScreenShot * sc = new CScreenShot(fname); if (cover) { + sc->EnableOSD(false); sc->EnableVideo(true); } if (autoshot || forcover) { diff --git a/src/system/locals.h b/src/system/locals.h index 67c5c3e16..4c462cbfe 100644 --- a/src/system/locals.h +++ b/src/system/locals.h @@ -1621,6 +1621,7 @@ typedef enum LOCALE_MOVIEBROWSER_SHORT_TITLE, LOCALE_MOVIEBROWSER_START_HEAD, LOCALE_MOVIEBROWSER_START_RECORD_START, + LOCALE_MOVIEBROWSER_TS_ONLY, LOCALE_MOVIEBROWSER_UPDATE_IF_DEST_EMPTY_ONLY, LOCALE_MOVIEBROWSER_USE_DIR, LOCALE_MOVIEBROWSER_USE_MOVIE_DIR, diff --git a/src/system/locals_intern.h b/src/system/locals_intern.h index a3fa7320a..e319b50a7 100644 --- a/src/system/locals_intern.h +++ b/src/system/locals_intern.h @@ -1621,6 +1621,7 @@ const char * locale_real_names[] = "moviebrowser.short_title", "moviebrowser.start_head", "moviebrowser.start_record_start", + "moviebrowser.ts_only", "moviebrowser.update_if_dest_empty_only", "moviebrowser.use_dir", "moviebrowser.use_movie_dir",