mirror of
https://github.com/antebudimir/feishin.git
synced 2025-12-31 18:13:31 +00:00
add bit depth, sample rate
This commit is contained in:
parent
8b141d652c
commit
4b4df28641
8 changed files with 65 additions and 16 deletions
|
|
@ -36,6 +36,7 @@
|
||||||
"ascending": "ascending",
|
"ascending": "ascending",
|
||||||
"backward": "backward",
|
"backward": "backward",
|
||||||
"biography": "biography",
|
"biography": "biography",
|
||||||
|
"bitDepth": "bit depth",
|
||||||
"bitrate": "bitrate",
|
"bitrate": "bitrate",
|
||||||
"bpm": "bpm",
|
"bpm": "bpm",
|
||||||
"cancel": "cancel",
|
"cancel": "cancel",
|
||||||
|
|
@ -99,6 +100,7 @@
|
||||||
"resetToDefault": "reset to default",
|
"resetToDefault": "reset to default",
|
||||||
"restartRequired": "restart required",
|
"restartRequired": "restart required",
|
||||||
"right": "right",
|
"right": "right",
|
||||||
|
"sampleRate": "sample rate",
|
||||||
"save": "save",
|
"save": "save",
|
||||||
"saveAndReplace": "save and replace",
|
"saveAndReplace": "save and replace",
|
||||||
"saveAs": "save as",
|
"saveAs": "save as",
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,8 @@ const SongPropertyMapping: ItemDetailRow<Song>[] = [
|
||||||
{ label: 'filter.isCompilation', render: (song) => BoolField(song.compilation || false) },
|
{ label: 'filter.isCompilation', render: (song) => BoolField(song.compilation || false) },
|
||||||
{ key: 'container', label: 'common.codec' },
|
{ key: 'container', label: 'common.codec' },
|
||||||
{ key: 'bitRate', label: 'common.bitrate', render: (song) => `${song.bitRate} kbps` },
|
{ key: 'bitRate', label: 'common.bitrate', render: (song) => `${song.bitRate} kbps` },
|
||||||
|
{ key: 'sampleRate', label: 'common.sampleRate' },
|
||||||
|
{ key: 'bitDepth', label: 'common.bitDepth' },
|
||||||
{ key: 'channels', label: 'common.channel_other' },
|
{ key: 'channels', label: 'common.channel_other' },
|
||||||
{ key: 'size', label: 'common.size', render: (song) => formatSizeString(song.size) },
|
{ key: 'size', label: 'common.size', render: (song) => formatSizeString(song.size) },
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -170,6 +170,47 @@ const normalizeSong = (
|
||||||
deviceId: string,
|
deviceId: string,
|
||||||
imageSize?: number,
|
imageSize?: number,
|
||||||
): Song => {
|
): Song => {
|
||||||
|
let bitRate = 0;
|
||||||
|
let channels: null | number = null;
|
||||||
|
let container: null | string = null;
|
||||||
|
let path: null | string = null;
|
||||||
|
let sampleRate: null | number = null;
|
||||||
|
let size = 0;
|
||||||
|
let streamUrl = '';
|
||||||
|
|
||||||
|
if (item.MediaSources?.length) {
|
||||||
|
const source = item.MediaSources[0];
|
||||||
|
|
||||||
|
container = source.Container;
|
||||||
|
path = source.Path;
|
||||||
|
size = source.Size;
|
||||||
|
|
||||||
|
streamUrl = getStreamUrl({
|
||||||
|
container: container,
|
||||||
|
deviceId,
|
||||||
|
eTag: source.ETag,
|
||||||
|
id: item.Id,
|
||||||
|
mediaSourceId: source.Id,
|
||||||
|
server,
|
||||||
|
});
|
||||||
|
|
||||||
|
if ((source.MediaStreams?.length || 0) > 0) {
|
||||||
|
for (const stream of source.MediaStreams) {
|
||||||
|
if (stream.Type === 'Audio') {
|
||||||
|
bitRate =
|
||||||
|
stream.BitRate !== undefined
|
||||||
|
? Number(Math.trunc(stream.BitRate / 1000))
|
||||||
|
: 0;
|
||||||
|
channels = stream.Channels || null;
|
||||||
|
sampleRate = stream.SampleRate || null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
console.warn('Jellyfin song retrieved with no media sources', item);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
album: item.Album,
|
album: item.Album,
|
||||||
albumArtists: item.AlbumArtists?.map((entry) => ({
|
albumArtists: item.AlbumArtists?.map((entry) => ({
|
||||||
|
|
@ -184,14 +225,13 @@ const normalizeSong = (
|
||||||
imageUrl: null,
|
imageUrl: null,
|
||||||
name: entry.Name,
|
name: entry.Name,
|
||||||
})),
|
})),
|
||||||
bitRate:
|
bitDepth: null,
|
||||||
item.MediaSources?.[0].Bitrate &&
|
bitRate,
|
||||||
Number(Math.trunc(item.MediaSources[0].Bitrate / 1000)),
|
|
||||||
bpm: null,
|
bpm: null,
|
||||||
channels: null,
|
channels,
|
||||||
comment: null,
|
comment: null,
|
||||||
compilation: null,
|
compilation: null,
|
||||||
container: (item.MediaSources && item.MediaSources[0]?.Container) || null,
|
container,
|
||||||
createdAt: item.DateCreated,
|
createdAt: item.DateCreated,
|
||||||
discNumber: (item.ParentIndexNumber && item.ParentIndexNumber) || 1,
|
discNumber: (item.ParentIndexNumber && item.ParentIndexNumber) || 1,
|
||||||
discSubtitle: null,
|
discSubtitle: null,
|
||||||
|
|
@ -220,7 +260,7 @@ const normalizeSong = (
|
||||||
lyrics: null,
|
lyrics: null,
|
||||||
name: item.Name,
|
name: item.Name,
|
||||||
participants: getPeople(item),
|
participants: getPeople(item),
|
||||||
path: (item.MediaSources && item.MediaSources[0]?.Path) || null,
|
path,
|
||||||
peak: null,
|
peak: null,
|
||||||
playCount: (item.UserData && item.UserData.PlayCount) || 0,
|
playCount: (item.UserData && item.UserData.PlayCount) || 0,
|
||||||
playlistItemId: item.PlaylistItemId,
|
playlistItemId: item.PlaylistItemId,
|
||||||
|
|
@ -230,17 +270,11 @@ const normalizeSong = (
|
||||||
? new Date(item.ProductionYear, 0, 1).toISOString()
|
? new Date(item.ProductionYear, 0, 1).toISOString()
|
||||||
: null,
|
: null,
|
||||||
releaseYear: item.ProductionYear ? String(item.ProductionYear) : null,
|
releaseYear: item.ProductionYear ? String(item.ProductionYear) : null,
|
||||||
|
sampleRate,
|
||||||
serverId: server?.id || '',
|
serverId: server?.id || '',
|
||||||
serverType: ServerType.JELLYFIN,
|
serverType: ServerType.JELLYFIN,
|
||||||
size: item.MediaSources && item.MediaSources[0]?.Size,
|
size,
|
||||||
streamUrl: getStreamUrl({
|
streamUrl,
|
||||||
container: item.MediaSources?.[0]?.Container,
|
|
||||||
deviceId,
|
|
||||||
eTag: item.MediaSources?.[0]?.ETag,
|
|
||||||
id: item.Id,
|
|
||||||
mediaSourceId: item.MediaSources?.[0]?.Id,
|
|
||||||
server,
|
|
||||||
}),
|
|
||||||
tags: getTags(item),
|
tags: getTags(item),
|
||||||
trackNumber: item.IndexNumber,
|
trackNumber: item.IndexNumber,
|
||||||
uniqueId: nanoid(),
|
uniqueId: nanoid(),
|
||||||
|
|
|
||||||
|
|
@ -148,6 +148,7 @@ const normalizeSong = (
|
||||||
albumId: item.albumId,
|
albumId: item.albumId,
|
||||||
...getArtists(item),
|
...getArtists(item),
|
||||||
artistName: item.artist,
|
artistName: item.artist,
|
||||||
|
bitDepth: item.bitDepth || null,
|
||||||
bitRate: item.bitRate,
|
bitRate: item.bitRate,
|
||||||
bpm: item.bpm ? item.bpm : null,
|
bpm: item.bpm ? item.bpm : null,
|
||||||
channels: item.channels ? item.channels : null,
|
channels: item.channels ? item.channels : null,
|
||||||
|
|
@ -189,6 +190,7 @@ const normalizeSong = (
|
||||||
: new Date(Date.UTC(item.year, 0, 1))
|
: new Date(Date.UTC(item.year, 0, 1))
|
||||||
).toISOString(),
|
).toISOString(),
|
||||||
releaseYear: String(item.year),
|
releaseYear: String(item.year),
|
||||||
|
sampleRate: item.sampleRate || null,
|
||||||
serverId: server?.id || 'unknown',
|
serverId: server?.id || 'unknown',
|
||||||
serverType: ServerType.NAVIDROME,
|
serverType: ServerType.NAVIDROME,
|
||||||
size: item.size,
|
size: item.size,
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ const song = z.object({
|
||||||
albumId: z.string(),
|
albumId: z.string(),
|
||||||
artist: z.string(),
|
artist: z.string(),
|
||||||
artistId: z.string(),
|
artistId: z.string(),
|
||||||
|
bitDepth: z.number().optional(),
|
||||||
bitRate: z.number(),
|
bitRate: z.number(),
|
||||||
bookmarkPosition: z.number(),
|
bookmarkPosition: z.number(),
|
||||||
bpm: z.number().optional(),
|
bpm: z.number().optional(),
|
||||||
|
|
@ -226,6 +227,7 @@ const song = z.object({
|
||||||
rgAlbumPeak: z.number().optional(),
|
rgAlbumPeak: z.number().optional(),
|
||||||
rgTrackGain: z.number().optional(),
|
rgTrackGain: z.number().optional(),
|
||||||
rgTrackPeak: z.number().optional(),
|
rgTrackPeak: z.number().optional(),
|
||||||
|
sampleRate: z.number(),
|
||||||
size: z.number(),
|
size: z.number(),
|
||||||
smallImageUrl: z.string().optional(),
|
smallImageUrl: z.string().optional(),
|
||||||
sortAlbumArtistName: z.string(),
|
sortAlbumArtistName: z.string(),
|
||||||
|
|
|
||||||
|
|
@ -135,9 +135,10 @@ const normalizeSong = (
|
||||||
albumId: item.albumId?.toString() || '',
|
albumId: item.albumId?.toString() || '',
|
||||||
artistName: item.artist || '',
|
artistName: item.artist || '',
|
||||||
artists: getArtistList(item.artists, item.artistId, item.artist),
|
artists: getArtistList(item.artists, item.artistId, item.artist),
|
||||||
|
bitDepth: item.bitDepth || null,
|
||||||
bitRate: item.bitRate || 0,
|
bitRate: item.bitRate || 0,
|
||||||
bpm: item.bpm || null,
|
bpm: item.bpm || null,
|
||||||
channels: null,
|
channels: item.channelCount || null,
|
||||||
comment: null,
|
comment: null,
|
||||||
compilation: null,
|
compilation: null,
|
||||||
container: item.contentType,
|
container: item.contentType,
|
||||||
|
|
@ -172,6 +173,7 @@ const normalizeSong = (
|
||||||
playCount: item?.playCount || 0,
|
playCount: item?.playCount || 0,
|
||||||
releaseDate: null,
|
releaseDate: null,
|
||||||
releaseYear: item.year ? String(item.year) : null,
|
releaseYear: item.year ? String(item.year) : null,
|
||||||
|
sampleRate: item.samplingRate || null,
|
||||||
serverId: server?.id || 'unknown',
|
serverId: server?.id || 'unknown',
|
||||||
serverType: ServerType.SUBSONIC,
|
serverType: ServerType.SUBSONIC,
|
||||||
size: item.size,
|
size: item.size,
|
||||||
|
|
|
||||||
|
|
@ -85,8 +85,10 @@ const song = z.object({
|
||||||
artistId: id.optional(),
|
artistId: id.optional(),
|
||||||
artists: z.array(simpleArtist),
|
artists: z.array(simpleArtist),
|
||||||
averageRating: z.number().optional(),
|
averageRating: z.number().optional(),
|
||||||
|
bitDepth: z.number().optional(),
|
||||||
bitRate: z.number().optional(),
|
bitRate: z.number().optional(),
|
||||||
bpm: z.number().optional(),
|
bpm: z.number().optional(),
|
||||||
|
channelCount: z.number().optional(),
|
||||||
contentType: z.string(),
|
contentType: z.string(),
|
||||||
contributors: z.array(contributor).optional(),
|
contributors: z.array(contributor).optional(),
|
||||||
coverArt: z.string().optional(),
|
coverArt: z.string().optional(),
|
||||||
|
|
@ -103,6 +105,7 @@ const song = z.object({
|
||||||
path: z.string(),
|
path: z.string(),
|
||||||
playCount: z.number().optional(),
|
playCount: z.number().optional(),
|
||||||
replayGain: songGain.optional(),
|
replayGain: songGain.optional(),
|
||||||
|
samplingRate: z.number().optional(),
|
||||||
size: z.number(),
|
size: z.number(),
|
||||||
starred: z.boolean().optional(),
|
starred: z.boolean().optional(),
|
||||||
suffix: z.string(),
|
suffix: z.string(),
|
||||||
|
|
|
||||||
|
|
@ -320,6 +320,7 @@ export type Song = {
|
||||||
albumId: string;
|
albumId: string;
|
||||||
artistName: string;
|
artistName: string;
|
||||||
artists: RelatedArtist[];
|
artists: RelatedArtist[];
|
||||||
|
bitDepth: null | number;
|
||||||
bitRate: number;
|
bitRate: number;
|
||||||
bpm: null | number;
|
bpm: null | number;
|
||||||
channels: null | number;
|
channels: null | number;
|
||||||
|
|
@ -346,6 +347,7 @@ export type Song = {
|
||||||
playlistItemId?: string;
|
playlistItemId?: string;
|
||||||
releaseDate: null | string;
|
releaseDate: null | string;
|
||||||
releaseYear: null | string;
|
releaseYear: null | string;
|
||||||
|
sampleRate: null | number;
|
||||||
serverId: string;
|
serverId: string;
|
||||||
serverType: ServerType;
|
serverType: ServerType;
|
||||||
size: number;
|
size: number;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue