Я пытаюсь создать собственный музыкальный проигрыватель / библиотеку в qt / c ++.
Я уже сканировал папку для музыкальных файлов, читал теги музыкального файла с помощью taglib , создавал структуру Track
из файла и помещал Track
в * 1005. * треков. Вот код, который у меня есть:
Это сканирует папку:
void LibraryScanner::scanFolder (std::string scanFolder) {
if (filesystem::exists (scanFolder) && filesystem::is_directory (scanFolder))
{
filesystem::recursive_directory_iterator recursiveIterator (scanFolder);
for (const auto& entry : filesystem::recursive_directory_iterator (scanFolder)) {
std::wstring path = entry.path().wstring ();
if (hasEnding (path, L".flac") || hasEnding (path, L".wav") || hasEnding (path, L".alac") || hasEnding (path, L".mp3") || hasEnding (path, L".m4a") || hasEnding (path, L".wma") || hasEnding (path, L".opus") || hasEnding (path, L".ogg") || hasEnding (path, L".aiff")) { ///TODO: ignore capital letters
scanFile (path);
}
}
}
}
каждый аудиофайл затем обрабатывается методом scanFile:
void LibraryScanner::scanFile (const std::wstring filePath)
{
Track track = Track ();
TagLib::FileRef f (filePath.c_str());
if(!f.isNull()){
track.filePath = filePath.c_str ();
track.Title = f.tag()->title().toWString();
track.Artists = f.tag()->artist().toWString();
tracks.push_back (track);
}else {
std::wcout << "File is null." << '\n';
}
}
Каждый трек помещается в этот вектор:
std::vector<Track> tracks;
и вот структура Track
:
#pragma once
#include<string>
struct Track{
std::wstring filePath, Title, Artists;
};
Итак, теперь я хочу, чтобы мой музыкальный проигрыватель работал примерно так:
музыкальный проигрыватель
рода
Существует список исполнителей, отсортированных по алфавиту (левая сторона рисунка), и у каждого исполнителя есть разные дорожки (справа), которые также отсортированы по альбомам.
Следует также отметить, что в каждом треке может быть несколько исполнителей, поэтому 2 исполнителя могут использовать одни и те же треки.
Но также я могу сортировать не только по исполнителю, но и по альбому или другим тегам (вы можете видеть это на втором рисунке). И переключение между сортировкой по исполнителю / альбому происходит мгновенно в этой программе.
Так как мне реализовать что-то подобное, что тоже очень эффективно, в моей собственной программе?
Я думал о предварительной сортировке всего во время сканирования. Поэтому после того, как я поместил каждый Track
в vector
дорожек, я создаю vector
или Set
исполнителей, и каждый исполнитель содержит дорожки или альбомы. Итак, я создал структуру Artist
следующим образом:
#pragma once
#include <vector>
#include "Track.h"
#include <string>
class Artist
{
public:
Artist (std::wstring artistName);
~Artist ();
std::wstring artistName;
std::vector<Track*> tracks;
};
Поскольку несколько исполнителей могут совместно использовать дорожки, я подумал, что создание вектора дорожек, содержащего только указатели Track
, будет хорошей идеей.
Таким образом, мой предварительно выбранный список исполнителей будет std::vector<Artist> artists;
, и у каждого исполнителя есть свои собственные треки с одинаковым тегом Artist (который я могу отсортировать по альбомам позже).
Затем, если я хочу отсортировать по альбомам, у меня есть еще один вектор, подобный этому: std::vector<Album> albums;
, где каждый Album
содержит свои собственные треки.
И если я хочу переключить режим сортировки, я просто изменяю, какой вектор отображается в виде списка.
У меня вопрос, есть ли более эффективный / эффективный способ сделать все это.
Похоже, что он будет использовать много памяти и займет много времени для сортировки, потому что я в основном сортирую несколько раз после сканирования (для каждого режима сортировки один вектор).
Кроме того, мне нужно проверить, есть ли дубликаты художников. Кроме того, каждый трек / исполнитель / альбом должен иметь собственное изображение обложки, которое я хочу отобразить. Мне нужно проверить их на дубликаты тоже
Так что этот способ будет использовать много ресурсов.
Я был бы очень благодарен, если бы кто-то знал способ, как эффективно сделать это, и, возможно, также имеет несколько примеров кода.
И если кто-нибудь знает более эффективный способ сканирования папок на наличие файлов или того, что я делал в фрагментах кода, которые я разместил, это тоже поможет.
Спасибо!