2024-02-03 02:47:23 -05:00
|
|
|
export class Jellyfin {
|
|
|
|
|
static audioPresets = (userId: string) => {
|
|
|
|
|
return {
|
|
|
|
|
MaxStreamingBitrate: '999999999',
|
|
|
|
|
Container: 'opus,webm|opus,mp3,aac,m4a|aac,m4b|aac,flac,webma,webm|webma,wav,ogg',
|
|
|
|
|
TranscodingContainer: 'ts',
|
|
|
|
|
TranscodingProtocol: 'hls',
|
|
|
|
|
AudioCodec: 'aac',
|
|
|
|
|
userId,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-04 01:01:37 -05:00
|
|
|
static songFactory = (song: Jellyfin.Song, connection: Jellyfin.JFConnection): Song => {
|
2024-02-03 02:47:23 -05:00
|
|
|
const { id, service } = connection
|
2024-02-04 01:01:37 -05:00
|
|
|
const thumbnail = song.ImageTags?.Primary
|
|
|
|
|
? new URL(`Items/${song.Id}/Images/Primary`, service.urlOrigin).href
|
|
|
|
|
: song.AlbumPrimaryImageTag
|
|
|
|
|
? new URL(`Items/${song.AlbumId}/Images/Primary`, service.urlOrigin).href
|
|
|
|
|
: undefined
|
2024-02-03 02:47:23 -05:00
|
|
|
|
2024-02-04 01:01:37 -05:00
|
|
|
const artists = song.ArtistItems
|
2024-02-03 02:47:23 -05:00
|
|
|
? Array.from(song.ArtistItems, (artist) => {
|
2024-02-04 01:01:37 -05:00
|
|
|
return { id: artist.Id, name: artist.Name }
|
2024-02-03 02:47:23 -05:00
|
|
|
})
|
2024-02-04 01:01:37 -05:00
|
|
|
: []
|
2024-02-03 02:47:23 -05:00
|
|
|
|
|
|
|
|
const audoSearchParams = new URLSearchParams(this.audioPresets(service.userId))
|
|
|
|
|
const audioSource = new URL(`Audio/${song.Id}/universal?${audoSearchParams.toString()}`, service.urlOrigin).href
|
|
|
|
|
|
2024-02-04 01:01:37 -05:00
|
|
|
return {
|
|
|
|
|
connectionId: id,
|
2024-02-12 16:00:55 -05:00
|
|
|
serviceType: service.type,
|
2024-02-04 01:01:37 -05:00
|
|
|
type: 'song',
|
2024-02-03 02:47:23 -05:00
|
|
|
id: song.Id,
|
|
|
|
|
name: song.Name,
|
|
|
|
|
duration: Math.floor(song.RunTimeTicks / 10000),
|
|
|
|
|
thumbnail,
|
|
|
|
|
artists,
|
|
|
|
|
albumId: song.AlbumId,
|
|
|
|
|
audio: audioSource,
|
|
|
|
|
releaseDate: String(song.ProductionYear),
|
|
|
|
|
}
|
2024-02-04 01:01:37 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static albumFactory = (album: Jellyfin.Album, connection: Jellyfin.JFConnection): Album => {
|
|
|
|
|
const { id, service } = connection
|
|
|
|
|
const thumbnail = album.ImageTags?.Primary ? new URL(`Items/${album.Id}/Images/Primary`, service.urlOrigin).href : undefined
|
|
|
|
|
|
|
|
|
|
const albumArtists = album.AlbumArtists
|
|
|
|
|
? Array.from(album.AlbumArtists, (artist) => {
|
|
|
|
|
return { id: artist.Id, name: artist.Name }
|
|
|
|
|
})
|
|
|
|
|
: []
|
|
|
|
|
|
|
|
|
|
const artists = album.ArtistItems
|
|
|
|
|
? Array.from(album.ArtistItems, (artist) => {
|
|
|
|
|
return { id: artist.Id, name: artist.Name }
|
|
|
|
|
})
|
|
|
|
|
: []
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
connectionId: id,
|
2024-02-12 16:00:55 -05:00
|
|
|
serviceType: service.type,
|
2024-02-04 01:01:37 -05:00
|
|
|
type: 'album',
|
|
|
|
|
id: album.Id,
|
|
|
|
|
name: album.Name,
|
|
|
|
|
duration: Math.floor(album.RunTimeTicks / 10000),
|
|
|
|
|
thumbnail,
|
|
|
|
|
albumArtists,
|
|
|
|
|
artists,
|
|
|
|
|
releaseDate: String(album.ProductionYear),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static playListFactory = (playlist: Jellyfin.Playlist, connection: Jellyfin.JFConnection): Playlist => {
|
|
|
|
|
const { id, service } = connection
|
|
|
|
|
const thumbnail = playlist.ImageTags?.Primary ? new URL(`Items/${playlist.Id}/Images/Primary`, service.urlOrigin).href : undefined
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
connectionId: id,
|
2024-02-12 16:00:55 -05:00
|
|
|
serviceType: service.type,
|
2024-02-04 01:01:37 -05:00
|
|
|
type: 'playlist',
|
|
|
|
|
id: playlist.Id,
|
|
|
|
|
name: playlist.Name,
|
|
|
|
|
duration: Math.floor(playlist.RunTimeTicks / 10000),
|
|
|
|
|
thumbnail,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static artistFactory = (artist: Jellyfin.Artist, connection: Jellyfin.JFConnection): Artist => {
|
|
|
|
|
const { id, service } = connection
|
|
|
|
|
const thumbnail = artist.ImageTags?.Primary ? new URL(`Items/${artist.Id}/Images/Primary`, service.urlOrigin).href : undefined
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
connectionId: id,
|
2024-02-12 16:00:55 -05:00
|
|
|
serviceType: service.type,
|
2024-02-04 01:01:37 -05:00
|
|
|
type: 'artist',
|
|
|
|
|
id: artist.Id,
|
|
|
|
|
name: artist.Name,
|
|
|
|
|
thumbnail,
|
|
|
|
|
}
|
2024-02-03 02:47:23 -05:00
|
|
|
}
|
2024-02-17 00:31:11 -05:00
|
|
|
|
|
|
|
|
static connectionInfo = async (connection: Jellyfin.JFConnection): Promise<ConnectionInfo> => {
|
|
|
|
|
const reqHeaders = new Headers({ Authorization: `MediaBrowser Token="${connection.tokens.accessToken}"` })
|
|
|
|
|
|
|
|
|
|
const userUrl = new URL(`Users/${connection.service.userId}`, connection.service.urlOrigin).href
|
|
|
|
|
const systemUrl = new URL('System/Info', connection.service.urlOrigin).href
|
|
|
|
|
|
|
|
|
|
const userResponse = await fetch(userUrl, { headers: reqHeaders })
|
|
|
|
|
const systemResponse = await fetch(systemUrl, { headers: reqHeaders })
|
|
|
|
|
|
|
|
|
|
const userData: Jellyfin.User = await userResponse.json()
|
|
|
|
|
const systemData: Jellyfin.System = await systemResponse.json()
|
|
|
|
|
|
|
|
|
|
return {
|
|
|
|
|
connectionId: connection.id,
|
|
|
|
|
serviceType: 'jellyfin',
|
|
|
|
|
username: userData.Name,
|
|
|
|
|
serverName: systemData.ServerName,
|
|
|
|
|
}
|
|
|
|
|
}
|
2024-02-03 02:47:23 -05:00
|
|
|
}
|