Music player can now handle unicode filenames and m3u8 playlists, issue #261

--HG--
branch : develop
This commit is contained in:
kervala 2016-02-20 19:12:55 +01:00
parent a0f8660d0d
commit 9322fa87b3

View file

@ -196,162 +196,176 @@ public:
InitMouseWithCursor (true); InitMouseWithCursor (true);
Driver->showCursor (true); Driver->showCursor (true);
if (false) //supportUnicode()) bool oggSupported = false;
bool mp3Supported = false;
for(uint i = 0; i < extensions.size(); ++i)
{ {
if (extensions[i] == "ogg")
{
oggSupported = true;
}
else if (extensions[i] == "mp3")
{
mp3Supported = true;
}
} }
else
std::vector<std::string> filters;
// supported formats
filters.push_back("All Supported Files"); // TODO: translate
std::string filter;
if (mp3Supported) filter += "*.mp3;*.mp2;*.mp1;";
if (oggSupported) filter += "*.ogg;";
filter += "*.m3u;*.m3u8";
filters.push_back(filter);
// mp3 format
if (mp3Supported)
{ {
bool oggSupported = false; filters.push_back("MPEG Audio Files (*.mp3;*.mp2;*.mp1)");
bool mp3Supported = false; filters.push_back("*.mp3;*.mp2;*.mp1");
}
for(uint i = 0; i < extensions.size(); ++i) // ogg format
if (oggSupported)
{
filters.push_back("Vorbis Files (*.ogg)");
filters.push_back("*.ogg");
}
// playlist
filters.push_back("Playlist Files (*.m3u;*.m3u8)");
filters.push_back("*.m3u;*.m3u8");
// all files
filters.push_back("All Files (*.*)");
filters.push_back("*.*");
filters.push_back("");
static wchar_t szFilter[1024] = { '\0' };
uint offset = 0;
for(uint i = 0; i < filters.size(); ++i)
{
wcscpy(szFilter + offset, utf8ToWide(filters[i]));
// move offset to string length + 1 for \0
offset += filters[i].length() + 1;
}
// Filename buffer
wchar_t buffer[1024];
buffer[0]=0;
OPENFILENAMEW ofn;
memset (&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = Driver ? Driver->getDisplay():NULL;
ofn.hInstance = HInstance;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 0;
ofn.lpstrFile = buffer;
ofn.nMaxFile = sizeof(buffer);
ofn.lpstrTitle = (wchar_t*)NLMISC::CI18N::get("uiPlaySongs").c_str();
ofn.Flags = OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER;
if (Driver)
Driver->beginDialogMode();
if (GetOpenFileNameW (&ofn))
{
bool useUtf8 = false;
// Skip the directory name
const wchar_t *bufferPtr = buffer;
// Multi filename ?
string path;
if (ofn.nFileOffset>wcslen(buffer))
{ {
if (extensions[i] == "ogg") // Backup the path and point to the next filename
{ path = wideToUtf8(buffer);
oggSupported = true; path += "\\";
} bufferPtr += wcslen(bufferPtr)+1;
else if (extensions[i] == "mp3")
{
mp3Supported = true;
}
} }
std::vector<std::string> filters; // Get selected files and playlists
std::vector<std::string> filenames;
// supported formats std::vector<std::string> playlists;
filters.push_back("All Supported Files"); while (*bufferPtr)
std::string filter;
if (mp3Supported) filter += "*.mp3;*.mp2;*.mp1;";
if (oggSupported) filter += "*.ogg;";
filter += "*.m3u";
filters.push_back(filter);
// mp3 format
if (mp3Supported)
{ {
filters.push_back("MPEG Audio Files (*.mp3;*.mp2;*.mp1)"); // Concat the directory name with the filename
filters.push_back("*.mp3;*.mp2;*.mp1"); std::string ext = toLower(CFile::getExtension(wideToUtf8(bufferPtr)));
} if (ext == "m3u" || ext == "m3u8")
// ogg format
if (oggSupported)
{
filters.push_back("Vorbis Files (*.ogg)");
filters.push_back("*.ogg");
}
// playlist
filters.push_back("Playlist Files (*.m3u)");
filters.push_back("*.m3u");
// all files
filters.push_back("All Files (*.*)");
filters.push_back("*.*");
filters.push_back("");
static char szFilter[1024] = { '\0' };
uint offset = 0;
for(uint i = 0; i < filters.size(); ++i)
{
strcpy(szFilter + offset, filters[i].c_str());
// move offset to string length + 1 for \0
offset += filters[i].length() + 1;
}
// Filename buffer
char buffer[65535];
buffer[0]=0;
OPENFILENAME ofn;
memset (&ofn, 0, sizeof(OPENFILENAME));
ofn.lStructSize = sizeof(OPENFILENAME);
ofn.hwndOwner = Driver ? Driver->getDisplay():NULL;
ofn.hInstance = HInstance;
ofn.lpstrFilter = szFilter;
ofn.nFilterIndex = 0;
ofn.lpstrFile = buffer;
ofn.nMaxFile = sizeof(buffer);
ofn.lpstrTitle = "Play songs";
ofn.Flags = OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER;
if (Driver)
Driver->beginDialogMode();
if (GetOpenFileName (&ofn))
{
// Skip the directory name
const char *bufferPtr = buffer;
// Multi filename ?
string path;
if (ofn.nFileOffset>strlen(buffer))
{ {
// Backup the path and point to the next filename playlists.push_back (path + wideToUtf8(bufferPtr));
path = buffer; }
path += "\\"; else
bufferPtr+=strlen(bufferPtr)+1; {
filenames.push_back (path + wideToUtf8(bufferPtr));
} }
// Get selected files and playlists bufferPtr += wcslen(bufferPtr) + 1;
std::vector<std::string> filenames; }
std::vector<std::string> playlists;
while (*bufferPtr)
{
// Concat the directory name with the filename
if (toLower(CFile::getExtension(bufferPtr)) == "m3u")
playlists.push_back (path+bufferPtr);
else
filenames.push_back (path+bufferPtr);
bufferPtr+=strlen(bufferPtr)+1;
}
// Sort songs by filename // Sort songs by filename
sort (filenames.begin(), filenames.end()); sort (filenames.begin(), filenames.end());
// Add playlist static uint8 utf8Header[] = { 0xefu, 0xbbu, 0xbfu };
uint i;
for (i=0; i<playlists.size(); i++) // Add playlist
uint i;
for (i=0; i<playlists.size(); i++)
{
// Get the path of the playlist
string basePlaylist = CFile::getPath (playlists[i]);
FILE *file = nlfopen (playlists[i], "r");
bool useUtf8 = CFile::getExtension(playlists[i]) == "m3u8";
if (file)
{ {
// Get the path of the playlist char line[512];
string basePlaylist = CFile::getPath (playlists[i]); while (fgets (line, 512, file))
FILE *file = fopen (playlists[i].c_str(), "r");
if (file)
{ {
char line[512]; // Not a comment line
while (fgets (line, 512, file)) string lineStr = trim(std::string(line));
{
// Not a comment line // id a UTF-8 BOM header is present, parse as UTF-8
string lineStr = trim (std::string(line)); if (!useUtf8 && lineStr.length() >= 3 && memcmp(line, utf8Header, 3) == 0)
if (lineStr[0] != '#') useUtf8 = true;
filenames.push_back (basePlaylist+lineStr);
} if (!useUtf8) lineStr = ucstring(line).toUtf8();
fclose (file);
if (lineStr[0] != '#')
filenames.push_back (CPath::makePathAbsolute(lineStr, basePlaylist));
} }
fclose (file);
} }
// Build the songs array
std::vector<CMusicPlayer::CSongs> songs;
for (i=0; i<filenames.size(); i++)
{
CMusicPlayer::CSongs song;
song.Filename = filenames[i];
SoundMngr->getMixer()->getSongTitle(filenames[i], song.Title);
songs.push_back (song);
}
MusicPlayer.playSongs(songs);
} }
if (Driver) // Build the songs array
Driver->endDialogMode(); std::vector<CMusicPlayer::CSongs> songs;
for (i=0; i<filenames.size(); i++)
{
CMusicPlayer::CSongs song;
song.Filename = filenames[i];
SoundMngr->getMixer()->getSongTitle(filenames[i], song.Title);
songs.push_back (song);
}
MusicPlayer.playSongs(songs);
} }
if (Driver)
Driver->endDialogMode();
// Restore mouse // Restore mouse
InitMouseWithCursor (wasHardware); InitMouseWithCursor (wasHardware);
Driver->showCursor (wasHardware); Driver->showCursor (wasHardware);