void StPlayList::addToPlayList(StFileNode* theFileNode) { for(size_t aNodeId = 0; aNodeId < theFileNode->size(); ++aNodeId) { StFileNode* aSubFileNode = theFileNode->changeValue(aNodeId); if(aSubFileNode->isFolder()) { addToPlayList(aSubFileNode); } else { addPlayItem(new StPlayItem(aSubFileNode, myDefStParams)); } } }
char* StPlayList::parseM3UIter(char* theIter, StFolder* theFolder, StString& theTitle) { if(*theIter == '\0') { return NULL; } char* aNextLine = nextLine(theIter); if(aNextLine > theIter + 1) { // replace LF or CRLF with '\0' *(aNextLine - 1) = '\0'; char* aTail = aNextLine - 2; if(*(aNextLine - 2) == '\x0D') { *(aNextLine - 2) = '\0'; --aTail; } // skip trailing spaces for(; *aTail == ' ' && aTail >= theIter; --aTail) { *aTail = '\0'; } } if(*theIter == '\0') { return aNextLine; // skip empty lines } if(*theIter != '#') { StString anItemPath = theIter; StFolder* aFolder = theFolder != NULL && StFileNode::isRelativePath(anItemPath) ? theFolder : &myFoldersRoot; StFileNode* aFileNode = new StFileNode(anItemPath, aFolder); aFolder->add(aFileNode); StPlayItem* anItem = new StPlayItem(aFileNode, myDefStParams); anItem->setTitle(theTitle); addPlayItem(anItem); theTitle = ""; } else if(stAreEqual(theIter, "#EXTINF:", 8)) { theIter += 8; for(; *theIter != '\0'; ++theIter) { if(*theIter == ',') { for(; *theIter == ' '; ++theIter) { // skip spaces in the beginning } theTitle = ++theIter; break; } } } return aNextLine; }
void StPlayList::addOneFile(const StString& theFilePath, const StMIME& theFileMIME) { StMutexAuto anAutoLock(myMutex); StFileNode* aFileNode = new StFileNode(theFilePath, &myFoldersRoot); aFileNode->setMIME(theFileMIME); myFoldersRoot.add(aFileNode); addRecentFile(*aFileNode); // append to recent files list addPlayItem(new StPlayItem(aFileNode, myDefStParams)); anAutoLock.unlock(); signals.onPlaylistChange(); }
void StPlayList::open(const StCString& thePath, const StCString& theItem) { StMutexAuto anAutoLock(myMutex); // check if it is recently played playlist bool hasTarget = !theItem.isEmpty(); StString aTarget = hasTarget ? theItem : thePath; if(!hasTarget) { for(size_t anIter = 0; anIter < myRecent.size(); ++anIter) { const StHandle<StRecentItem>& aRecent = myRecent[anIter]; const StHandle<StFileNode>& aFile = aRecent->File; if(aFile->size() != 1) { continue; } if(thePath.isEquals(aFile->getPath())) { hasTarget = true; aTarget = aFile->getValue(0)->getSubPath(); break; } } } clear(); int aSearchDeep = myRecursionDeep; StString aFolderPath; StString aFileName; if(StFolder::isFolder(thePath)) { // add all files from the folder and subfolders aFolderPath = thePath; aSearchDeep = myRecursionDeep; myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list } else if(StFileNode::isFileExists(thePath)) { // search only current folder StFileNode::getFolderAndFile(thePath, aFolderPath, aFileName); aSearchDeep = 1; bool hasSupportedExt = false; StString anExt = StFileNode::getExtension(aFileName); for(size_t anExtId = 0; anExtId < myExtensions.size() && !hasSupportedExt; ++anExtId) { hasSupportedExt = anExt.isEqualsIgnoreCase(myExtensions[anExtId]); } // parse m3u playlist if(anExt.isEqualsIgnoreCase(stCString("m3u"))) { StRawFile aRawFile(thePath); if(aRawFile.readFile()) { StString aTitle; char* anIter = (char* )aRawFile.getBuffer(); if(anIter[0] == '\xEF' && anIter[1] == '\xBB' && anIter[2] == '\xBF') { // skip BOM for UTF8 written by some stupid programs anIter += 3; } while(anIter != NULL) { anIter = parseM3UIter(anIter, aTitle); } myPlsFile = addRecentFile(StFileNode(thePath)); // append to recent files list if(hasTarget) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); return; } } if(!hasSupportedExt) { // file with unsupported extension? StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addPlayItem(new StPlayItem(aFileNode, myDefStParams)); } } else { // not a filesystem element - probably url or invalid path StFileNode* aFileNode = new StFileNode(thePath, &myFoldersRoot); myFoldersRoot.add(aFileNode); addRecentFile(*aFileNode); // append to recent files list addPlayItem(new StPlayItem(aFileNode, myDefStParams)); anAutoLock.unlock(); signals.onPlaylistChange(); return; } StFolder* aSubFolder = new StFolder(aFolderPath, &myFoldersRoot); aSubFolder->init(myExtensions, aSearchDeep); myFoldersRoot.add(aSubFolder); addToPlayList(aSubFolder); myCurrent = myFirst; if(hasTarget || !aFileName.isEmpty()) { // set current item for(StPlayItem* anItem = myFirst; anItem != NULL; anItem = anItem->getNext()) { if(anItem->getPath() == aTarget) { myCurrent = anItem; if(myPlsFile.isNull()) { addRecentFile(*anItem->getFileNode()); // append to recent files list } break; } } } anAutoLock.unlock(); signals.onPlaylistChange(); }