Skip to main content
Glama
audio-analysis.test.js8.37 kB
const PlexMCPServer = require('../../index.js'); describe('Audio Analysis Features', () => { let server; beforeEach(() => { server = new PlexMCPServer({ axios: require('axios').create() }); }); describe('calculateAudioQuality', () => { it('should calculate quality for high-end FLAC', () => { const media = { bitrate: 1411, audioCodec: 'flac', audioChannels: 2, dynamicRange: 20 }; const quality = server.calculateAudioQuality(media); expect(quality.score).toBe(85); // 30 + 25 + 10 + 20 expect(quality.rating).toBe('Excellent'); expect(quality.factors).toContain('High bitrate'); expect(quality.factors).toContain('Lossless codec'); expect(quality.factors).toContain('Excellent dynamic range'); }); it('should calculate quality for standard MP3', () => { const media = { bitrate: 320, audioCodec: 'mp3', audioChannels: 2 }; const quality = server.calculateAudioQuality(media); expect(quality.score).toBe(30); // 10 + 10 + 10 expect(quality.rating).toBe('Poor'); expect(quality.factors).toContain('Decent bitrate'); expect(quality.factors).toContain('Standard codec'); expect(quality.factors).toContain('Stereo'); }); it('should calculate quality for surround sound', () => { const media = { bitrate: 1500, audioCodec: 'truehd', audioChannels: 8 }; const quality = server.calculateAudioQuality(media); expect(quality.score).toBe(70); // 30 + 25 + 15 expect(quality.rating).toBe('Good'); expect(quality.factors).toContain('Surround sound'); }); it('should handle null media input', () => { const quality = server.calculateAudioQuality(null); expect(quality).toBeNull(); }); }); describe('BPM estimation from genre', () => { it('should estimate BPM for electronic genres', () => { expect(server.estimateBPMFromGenre('Drum and Bass')).toBe(170); expect(server.estimateBPMFromGenre('Techno')).toBe(130); expect(server.estimateBPMFromGenre('House')).toBe(125); }); it('should estimate BPM for traditional genres', () => { expect(server.estimateBPMFromGenre('Pop')).toBe(120); expect(server.estimateBPMFromGenre('Hip Hop')).toBe(95); expect(server.estimateBPMFromGenre('Folk')).toBe(80); expect(server.estimateBPMFromGenre('Ballad')).toBe(70); }); it('should return null for unknown genres', () => { expect(server.estimateBPMFromGenre('Unknown Genre')).toBeNull(); expect(server.estimateBPMFromGenre(null)).toBeNull(); }); }); describe('Mood estimation from genre', () => { it('should classify energetic genres', () => { expect(server.estimateMoodFromGenre('Dance')).toBe('energetic'); expect(server.estimateMoodFromGenre('Electronic')).toBe('energetic'); expect(server.estimateMoodFromGenre('Pop')).toBe('energetic'); }); it('should classify calm genres', () => { expect(server.estimateMoodFromGenre('Ambient')).toBe('calm'); expect(server.estimateMoodFromGenre('Classical')).toBe('calm'); expect(server.estimateMoodFromGenre('Folk')).toBe('calm'); }); it('should classify aggressive genres', () => { expect(server.estimateMoodFromGenre('Rock')).toBe('aggressive'); expect(server.estimateMoodFromGenre('Metal')).toBe('aggressive'); }); it('should classify melancholic genres', () => { expect(server.estimateMoodFromGenre('Jazz')).toBe('melancholic'); expect(server.estimateMoodFromGenre('Blues')).toBe('melancholic'); }); it('should return null for unknown genres', () => { expect(server.estimateMoodFromGenre('Unknown')).toBeNull(); expect(server.estimateMoodFromGenre(null)).toBeNull(); }); }); describe('Acoustic ratio estimation from genre', () => { it('should classify highly acoustic genres', () => { expect(server.estimateAcousticRatioFromGenre('Acoustic')).toBe(0.9); expect(server.estimateAcousticRatioFromGenre('Folk')).toBe(0.9); expect(server.estimateAcousticRatioFromGenre('Country')).toBe(0.9); }); it('should classify mostly acoustic genres', () => { expect(server.estimateAcousticRatioFromGenre('Classical')).toBe(0.8); expect(server.estimateAcousticRatioFromGenre('Jazz')).toBe(0.8); }); it('should classify mixed genres', () => { expect(server.estimateAcousticRatioFromGenre('Rock')).toBe(0.5); expect(server.estimateAcousticRatioFromGenre('Pop')).toBe(0.5); }); it('should classify electronic genres', () => { expect(server.estimateAcousticRatioFromGenre('Electronic')).toBe(0.1); expect(server.estimateAcousticRatioFromGenre('Synth')).toBe(0.1); expect(server.estimateAcousticRatioFromGenre('Techno')).toBe(0.1); }); it('should return null for unknown genres', () => { expect(server.estimateAcousticRatioFromGenre('Unknown')).toBeNull(); expect(server.estimateAcousticRatioFromGenre(null)).toBeNull(); }); }); describe('searchByAudioAnalysis', () => { const mockLibraries = [ { key: '1', title: 'Music', type: 'artist' } ]; const mockResponse = { data: { MediaContainer: { Metadata: [ { title: 'Electronic Track', grandparentTitle: 'Artist 1', parentTitle: 'Album 1', genre: 'Electronic Dance' }, { title: 'Acoustic Song', grandparentTitle: 'Artist 2', parentTitle: 'Album 2', genre: 'Folk Acoustic' }, { title: 'Rock Anthem', grandparentTitle: 'Artist 3', parentTitle: 'Album 3', genre: 'Rock' } ] } } }; beforeEach(() => { server.axios = { get: jest.fn().mockResolvedValue(mockResponse) }; server.parseLibraryContent = jest.fn().mockReturnValue(mockResponse.data.MediaContainer.Metadata); server.getHttpsAgent = jest.fn().mockReturnValue(null); }); it('should search for energetic tracks', async() => { const results = await server.searchByAudioAnalysis( 'energetic dance music', mockLibraries, 'http://localhost:32400', 'token123', 10 ); expect(results.length).toBeGreaterThan(0); expect(results[0].reason).toContain('Energetic track'); // The first result could be either electronic (energetic) or rock (aggressive) // depending on array ordering, so we check for results containing energetic tracks const energeticTrack = results.find(r => r.estimatedMood === 'energetic'); expect(energeticTrack).toBeDefined(); }); it('should search for acoustic tracks', async() => { const results = await server.searchByAudioAnalysis( 'acoustic songs', mockLibraries, 'http://localhost:32400', 'token123', 10 ); expect(results.length).toBeGreaterThan(0); const acousticTrack = results.find(r => r.title === 'Acoustic Song'); expect(acousticTrack).toBeDefined(); expect(acousticTrack.reason).toContain('Acoustic track'); expect(acousticTrack.estimatedAcousticRatio).toBe(0.9); }); it('should search for electronic tracks', async() => { const results = await server.searchByAudioAnalysis( 'electronic music', mockLibraries, 'http://localhost:32400', 'token123', 10 ); expect(results.length).toBeGreaterThan(0); const electronicTrack = results.find(r => r.title === 'Electronic Track'); expect(electronicTrack).toBeDefined(); expect(electronicTrack.reason).toContain('Electronic track'); expect(electronicTrack.estimatedAcousticRatio).toBe(0.1); }); it('should handle API errors gracefully', async() => { server.axios.get = jest.fn().mockRejectedValue(new Error('API Error')); const results = await server.searchByAudioAnalysis( 'energetic music', mockLibraries, 'http://localhost:32400', 'token123', 10 ); expect(results).toEqual([]); }); }); });

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/vyb1ng/plex-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server