mirror of
https://github.com/Jellify-Music/App.git
synced 2025-12-19 09:39:59 -06:00
Implements proper server negotation for performing transcoding Depending on the user's platform (i.e. iOS, Android) and the desired quality specified in the settings, Jellify will playback a transcoded audio file from Jellyfin This is helpful when the source audio file is not compatible with the user's device (i.e. playing back an ALAC encoded .M4A on Android) or if the user want to stream at a lower quality to save bandwidth This also drives downloads in different qualities, meaning the download quality selector in the Settings is now working properly. When a track is downloaded, it will download at the quality selected by the user, and in a format compatible with the device There is also a toggle in the "Player" Settings for displaying a badge in the player that shows the quality and container of the audio being played
221 lines
5.0 KiB
TypeScript
221 lines
5.0 KiB
TypeScript
import { QueuingType } from '../../src/enums/queuing-type'
|
|
import { findPlayNextIndexStart, findPlayQueueIndexStart } from '../../src/providers/Player/utils'
|
|
|
|
describe('Queue Index Util', () => {
|
|
afterEach(() => {
|
|
jest.clearAllMocks()
|
|
})
|
|
|
|
describe('findPlayNextIndexStart', () => {
|
|
it('should return 0 if the queue is empty', async () => {
|
|
const result = await findPlayNextIndexStart([])
|
|
|
|
expect(result).toBe(0)
|
|
})
|
|
|
|
it('should return the index of the active track + 1', async () => {
|
|
const result = await findPlayNextIndexStart([
|
|
{
|
|
id: '1',
|
|
index: 0,
|
|
url: 'https://example.com',
|
|
item: { Id: '1' },
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
])
|
|
|
|
expect(result).toBe(1)
|
|
})
|
|
|
|
it('should return 0 if the active track is not in the queue', async () => {
|
|
const result = await findPlayNextIndexStart([
|
|
{
|
|
id: '1',
|
|
index: 0,
|
|
url: 'https://example.com',
|
|
item: { Id: '2' },
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
])
|
|
|
|
expect(result).toBe(0)
|
|
})
|
|
})
|
|
|
|
describe('findPlayQueueIndexStart', () => {
|
|
it('should return the index of the first track that is not from selection', async () => {
|
|
const result = await findPlayQueueIndexStart(
|
|
[
|
|
{
|
|
id: '1',
|
|
index: 0,
|
|
url: 'https://example.com',
|
|
item: { Id: '1' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '2',
|
|
index: 1,
|
|
url: 'https://example.com',
|
|
item: { Id: '2' },
|
|
QueuingType: QueuingType.PlayingNext,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '3',
|
|
index: 2,
|
|
url: 'https://example.com',
|
|
item: { Id: '3' },
|
|
QueuingType: QueuingType.DirectlyQueued,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
],
|
|
0,
|
|
)
|
|
|
|
expect(result).toBe(3)
|
|
})
|
|
|
|
it('should return the index of the first track that is not from selection and after other queued tracks', async () => {
|
|
const result = await findPlayQueueIndexStart(
|
|
[
|
|
{
|
|
id: '1',
|
|
index: 0,
|
|
url: 'https://example.com',
|
|
item: { Id: '1' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '2',
|
|
index: 1,
|
|
url: 'https://example.com',
|
|
item: { Id: '2' },
|
|
QueuingType: QueuingType.PlayingNext,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '3',
|
|
index: 2,
|
|
url: 'https://example.com',
|
|
item: { Id: '3' },
|
|
QueuingType: QueuingType.DirectlyQueued,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '4',
|
|
index: 3,
|
|
url: 'https://example.com',
|
|
item: { Id: '4' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '5',
|
|
index: 4,
|
|
url: 'https://example.com',
|
|
item: { Id: '5' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
],
|
|
0,
|
|
)
|
|
|
|
expect(result).toBe(3)
|
|
})
|
|
|
|
it('should add in relation to the active track if shuffled, but respect queue priority', async () => {
|
|
const result = await findPlayQueueIndexStart(
|
|
[
|
|
{
|
|
id: '2',
|
|
index: 0,
|
|
url: 'https://example.com',
|
|
item: { Id: '2' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '1',
|
|
index: 1,
|
|
url: 'https://example.com',
|
|
item: { Id: '1' },
|
|
QueuingType: QueuingType.PlayingNext,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '3',
|
|
index: 2,
|
|
url: 'https://example.com',
|
|
item: { Id: '3' },
|
|
QueuingType: QueuingType.DirectlyQueued,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '5',
|
|
index: 3,
|
|
url: 'https://example.com',
|
|
item: { Id: '5' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '4',
|
|
index: 4,
|
|
url: 'https://example.com',
|
|
item: { Id: '4' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
{
|
|
id: '6',
|
|
index: 5,
|
|
url: 'https://example.com',
|
|
item: { Id: '6' },
|
|
QueuingType: QueuingType.FromSelection,
|
|
duration: 420,
|
|
sessionId: 'TEST_SESSION_ID',
|
|
sourceType: 'stream',
|
|
},
|
|
],
|
|
0,
|
|
)
|
|
|
|
expect(result).toBe(3)
|
|
})
|
|
})
|
|
})
|