diff --git a/src/routes/subsonic.js b/src/routes/subsonic.js
index 327f741..6f1c407 100644
--- a/src/routes/subsonic.js
+++ b/src/routes/subsonic.js
@@ -98,6 +98,110 @@ router.get('/getMusicFolders.view', authenticateSubsonic, async (req, res) => {
`);
});
+// Get music directory (for browsing by folder structure)
+router.get('/getMusicDirectory.view', authenticateSubsonic, async (req, res) => {
+ try {
+ const { id } = req.query;
+
+ // Root folder - return all artists
+ if (id === '1') {
+ const artists = await all(`
+ SELECT DISTINCT artist
+ FROM tracks
+ ORDER BY artist
+ `);
+
+ let dirXml = '\n';
+
+ artists.forEach(artist => {
+ const artistId = crypto.createHash('md5').update(`artist-${artist.artist}`).digest('hex');
+ dirXml += ` \n`;
+ });
+
+ dirXml += '';
+ return sendSubsonicResponse(res, dirXml);
+ }
+
+ // Artist folder - return albums for this artist
+ const artists = await all(`SELECT DISTINCT artist FROM tracks`);
+ let targetArtist = null;
+
+ for (const artist of artists) {
+ const testId = crypto.createHash('md5').update(`artist-${artist.artist}`).digest('hex');
+ if (testId === id) {
+ targetArtist = artist.artist;
+ break;
+ }
+ }
+
+ if (targetArtist) {
+ const albums = await all(`
+ SELECT DISTINCT album, album_artist, year,
+ (SELECT artwork_path FROM tracks t2 WHERE t2.album = tracks.album AND t2.artist = ? LIMIT 1) as artwork_path,
+ COUNT(*) as track_count
+ FROM tracks
+ WHERE artist = ?
+ GROUP BY album, album_artist
+ ORDER BY year DESC, album
+ `, [targetArtist, targetArtist]);
+
+ let dirXml = `\n`;
+
+ albums.forEach(album => {
+ const albumId = crypto.createHash('md5').update(`album-${album.album}-${album.album_artist}`).digest('hex');
+ const coverArt = album.artwork_path ? albumId : '';
+ dirXml += ` \n`;
+ });
+
+ dirXml += '';
+ return sendSubsonicResponse(res, dirXml);
+ }
+
+ // Album folder - return tracks
+ const allAlbums = await all(`SELECT DISTINCT album, album_artist FROM tracks`);
+ let targetAlbum = null;
+ let targetAlbumArtist = null;
+
+ for (const album of allAlbums) {
+ const testId = crypto.createHash('md5').update(`album-${album.album}-${album.album_artist}`).digest('hex');
+ if (testId === id) {
+ targetAlbum = album.album;
+ targetAlbumArtist = album.album_artist;
+ break;
+ }
+ }
+
+ if (targetAlbum) {
+ const tracks = await all(`
+ SELECT * FROM tracks
+ WHERE album = ? AND album_artist = ?
+ ORDER BY disc_number, track_number, title
+ `, [targetAlbum, targetAlbumArtist]);
+
+ if (tracks.length === 0) {
+ return sendSubsonicError(res, 70, 'Album not found');
+ }
+
+ const firstTrack = tracks[0];
+ let dirXml = `\n`;
+
+ tracks.forEach(track => {
+ dirXml += buildSongXml(track, req);
+ });
+
+ dirXml += '';
+ return sendSubsonicResponse(res, dirXml);
+ }
+
+ sendSubsonicError(res, 70, 'Directory not found');
+ } catch (error) {
+ console.error('Error in getMusicDirectory:', error);
+ sendSubsonicError(res, 0, error.message);
+ }
+});
+
// Get indexes (artists)
router.get('/getIndexes.view', authenticateSubsonic, async (req, res) => {
try {