mirror of
https://github.com/SoPat712/allstarr.git
synced 2026-02-09 23:55:10 -05:00
Match Jellyfin response structure exactly based on real API responses
Verified against real Jellyfin responses for tracks, albums, artists, and playlists: - Reordered fields to match Jellyfin's exact field order - Added missing fields: PremiereDate, HasLyrics, Container, ETag, etc. - Fixed MediaType to 'Unknown' for albums/artists (not null) - Fixed UserData.Key format to match Jellyfin patterns - Added ParentLogoItemId, ParentBackdropItemId for proper hierarchy - Fixed Genres/GenreItems to always be arrays (never null) - Added complete MediaStream structure with all Jellyfin fields - Playlists now have MediaType='Audio' to match real playlists - All responses now perfectly mimic real Jellyfin structure
This commit is contained in:
@@ -240,15 +240,44 @@ public class JellyfinResponseBuilder
|
|||||||
|
|
||||||
var item = new Dictionary<string, object?>
|
var item = new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Id"] = song.Id,
|
|
||||||
["Name"] = songTitle,
|
["Name"] = songTitle,
|
||||||
["ServerId"] = "allstarr",
|
["ServerId"] = "allstarr",
|
||||||
["Type"] = "Audio",
|
["Id"] = song.Id,
|
||||||
["MediaType"] = "Audio",
|
["HasLyrics"] = false, // Could be enhanced to check if lyrics exist
|
||||||
|
["Container"] = "flac",
|
||||||
|
["PremiereDate"] = song.Year.HasValue ? $"{song.Year}-01-01T00:00:00.0000000Z" : null,
|
||||||
|
["RunTimeTicks"] = (song.Duration ?? 0) * TimeSpan.TicksPerSecond,
|
||||||
|
["ProductionYear"] = song.Year,
|
||||||
|
["IndexNumber"] = song.Track,
|
||||||
|
["ParentIndexNumber"] = song.DiscNumber ?? 1,
|
||||||
["IsFolder"] = false,
|
["IsFolder"] = false,
|
||||||
["Album"] = song.Album,
|
["Type"] = "Audio",
|
||||||
["AlbumId"] = song.AlbumId ?? song.Id,
|
["ChannelId"] = (object?)null,
|
||||||
["AlbumArtist"] = song.AlbumArtist ?? song.Artist,
|
["Genres"] = !string.IsNullOrEmpty(song.Genre)
|
||||||
|
? new[] { song.Genre }
|
||||||
|
: new string[0],
|
||||||
|
["GenreItems"] = !string.IsNullOrEmpty(song.Genre)
|
||||||
|
? new[]
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["Name"] = song.Genre,
|
||||||
|
["Id"] = $"genre-{song.Genre?.ToLowerInvariant()}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
: new Dictionary<string, object?>[0],
|
||||||
|
["ParentLogoItemId"] = song.AlbumId,
|
||||||
|
["ParentBackdropItemId"] = song.AlbumId,
|
||||||
|
["ParentBackdropImageTags"] = new string[0],
|
||||||
|
["UserData"] = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["PlaybackPositionTicks"] = 0,
|
||||||
|
["PlayCount"] = 0,
|
||||||
|
["IsFavorite"] = false,
|
||||||
|
["Played"] = false,
|
||||||
|
["Key"] = $"Audio-{song.Id}",
|
||||||
|
["ItemId"] = song.Id
|
||||||
|
},
|
||||||
["Artists"] = song.Artists.Count > 0 ? song.Artists.ToArray() : new[] { song.Artist ?? "" },
|
["Artists"] = song.Artists.Count > 0 ? song.Artists.ToArray() : new[] { song.Artist ?? "" },
|
||||||
["ArtistItems"] = song.Artists.Count > 0
|
["ArtistItems"] = song.Artists.Count > 0
|
||||||
? song.Artists.Select((name, index) => new Dictionary<string, object?>
|
? song.Artists.Select((name, index) => new Dictionary<string, object?>
|
||||||
@@ -266,43 +295,31 @@ public class JellyfinResponseBuilder
|
|||||||
["Name"] = song.Artist ?? ""
|
["Name"] = song.Artist ?? ""
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
["IndexNumber"] = song.Track,
|
["Album"] = song.Album,
|
||||||
["ParentIndexNumber"] = song.DiscNumber ?? 1,
|
["AlbumId"] = song.AlbumId ?? song.Id,
|
||||||
["ProductionYear"] = song.Year,
|
["AlbumPrimaryImageTag"] = song.AlbumId ?? song.Id,
|
||||||
["RunTimeTicks"] = (song.Duration ?? 0) * TimeSpan.TicksPerSecond,
|
["AlbumArtist"] = song.AlbumArtist ?? song.Artist,
|
||||||
|
["AlbumArtists"] = new[]
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["Name"] = song.AlbumArtist ?? song.Artist ?? "",
|
||||||
|
["Id"] = song.ArtistId ?? song.Id
|
||||||
|
}
|
||||||
|
},
|
||||||
["ImageTags"] = new Dictionary<string, string>
|
["ImageTags"] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
["Primary"] = song.Id
|
["Primary"] = song.Id
|
||||||
},
|
},
|
||||||
["BackdropImageTags"] = new string[0],
|
["BackdropImageTags"] = new string[0],
|
||||||
|
["ParentLogoImageTag"] = song.AlbumId ?? song.Id,
|
||||||
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
||||||
["LocationType"] = "FileSystem", // External content appears as local files to clients
|
["LocationType"] = "FileSystem",
|
||||||
["Path"] = $"/music/{song.Artist}/{song.Album}/{song.Title}.flac", // Fake path for client compatibility
|
["MediaType"] = "Audio",
|
||||||
["ChannelId"] = (object?)null, // Match Jellyfin structure
|
["NormalizationGain"] = 0.0,
|
||||||
["UserData"] = new Dictionary<string, object>
|
["Path"] = $"/music/{song.Artist}/{song.Album}/{song.Title}.flac",
|
||||||
{
|
|
||||||
["PlaybackPositionTicks"] = 0,
|
|
||||||
["PlayCount"] = 0,
|
|
||||||
["IsFavorite"] = false,
|
|
||||||
["Played"] = false,
|
|
||||||
["Key"] = $"Audio-{song.Id}"
|
|
||||||
},
|
|
||||||
["CanDownload"] = true,
|
["CanDownload"] = true,
|
||||||
["SupportsSync"] = true,
|
["SupportsSync"] = true
|
||||||
// Always include Genres array - use song genre if available, otherwise use a default
|
|
||||||
["Genres"] = !string.IsNullOrEmpty(song.Genre)
|
|
||||||
? new[] { song.Genre }
|
|
||||||
: new string[0], // Empty array instead of null
|
|
||||||
["GenreItems"] = !string.IsNullOrEmpty(song.Genre)
|
|
||||||
? new[]
|
|
||||||
{
|
|
||||||
new Dictionary<string, object?>
|
|
||||||
{
|
|
||||||
["Name"] = song.Genre,
|
|
||||||
["Id"] = $"genre-{song.Genre?.ToLowerInvariant()}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
: new Dictionary<string, object?>[0]
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add provider IDs for external content
|
// Add provider IDs for external content
|
||||||
@@ -319,45 +336,56 @@ public class JellyfinResponseBuilder
|
|||||||
providerIds["ISRC"] = song.Isrc;
|
providerIds["ISRC"] = song.Isrc;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add MediaSources with bitrate for external tracks
|
// Add MediaSources with complete structure matching real Jellyfin
|
||||||
item["MediaSources"] = new[]
|
item["MediaSources"] = new[]
|
||||||
{
|
{
|
||||||
new Dictionary<string, object?>
|
new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
|
["Protocol"] = "File",
|
||||||
["Id"] = song.Id,
|
["Id"] = song.Id,
|
||||||
|
["Path"] = $"/music/{song.Artist}/{song.Album}/{song.Title}.flac",
|
||||||
["Type"] = "Default",
|
["Type"] = "Default",
|
||||||
["Container"] = "flac",
|
["Container"] = "flac",
|
||||||
["Size"] = (song.Duration ?? 180) * 1337 * 128, // Approximate file size
|
["Size"] = (song.Duration ?? 180) * 1337 * 128,
|
||||||
["Bitrate"] = 1337000, // 1337 kbps in bps
|
["Name"] = song.Title,
|
||||||
["Path"] = $"/music/{song.Artist}/{song.Album}/{song.Title}.flac",
|
|
||||||
["Protocol"] = "File",
|
|
||||||
["SupportsDirectStream"] = true,
|
|
||||||
["SupportsTranscoding"] = true,
|
|
||||||
["SupportsDirectPlay"] = true,
|
|
||||||
["IsRemote"] = false,
|
["IsRemote"] = false,
|
||||||
["IsInfiniteStream"] = false,
|
["ETag"] = song.Id, // Use song ID as ETag
|
||||||
["RequiresOpening"] = false,
|
["RunTimeTicks"] = (song.Duration ?? 180) * 10000000L,
|
||||||
["RequiresClosing"] = false,
|
|
||||||
["RequiresLooping"] = false,
|
|
||||||
["SupportsProbing"] = true,
|
|
||||||
["ReadAtNativeFramerate"] = false,
|
["ReadAtNativeFramerate"] = false,
|
||||||
["IgnoreDts"] = false,
|
["IgnoreDts"] = false,
|
||||||
["IgnoreIndex"] = false,
|
["IgnoreIndex"] = false,
|
||||||
["GenPtsInput"] = false,
|
["GenPtsInput"] = false,
|
||||||
|
["SupportsTranscoding"] = true,
|
||||||
|
["SupportsDirectStream"] = true,
|
||||||
|
["SupportsDirectPlay"] = true,
|
||||||
|
["IsInfiniteStream"] = false,
|
||||||
|
["UseMostCompatibleTranscodingProfile"] = false,
|
||||||
|
["RequiresOpening"] = false,
|
||||||
|
["RequiresClosing"] = false,
|
||||||
|
["RequiresLooping"] = false,
|
||||||
|
["SupportsProbing"] = true,
|
||||||
["MediaStreams"] = new[]
|
["MediaStreams"] = new[]
|
||||||
{
|
{
|
||||||
new Dictionary<string, object?>
|
new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Codec"] = "flac",
|
["Codec"] = "flac",
|
||||||
["TimeBase"] = "1/44100",
|
["TimeBase"] = "1/44100",
|
||||||
["DisplayTitle"] = "FLAC - Stereo - Default",
|
["VideoRange"] = "Unknown",
|
||||||
|
["VideoRangeType"] = "Unknown",
|
||||||
|
["AudioSpatialFormat"] = "None",
|
||||||
|
["LocalizedDefault"] = "Default",
|
||||||
|
["LocalizedExternal"] = "External",
|
||||||
|
["DisplayTitle"] = "FLAC - Stereo",
|
||||||
["IsInterlaced"] = false,
|
["IsInterlaced"] = false,
|
||||||
|
["IsAVC"] = false,
|
||||||
["ChannelLayout"] = "stereo",
|
["ChannelLayout"] = "stereo",
|
||||||
["BitRate"] = 1337000,
|
["BitRate"] = 1337000,
|
||||||
|
["BitDepth"] = 16,
|
||||||
["Channels"] = 2,
|
["Channels"] = 2,
|
||||||
["SampleRate"] = 44100,
|
["SampleRate"] = 44100,
|
||||||
["IsDefault"] = true,
|
["IsDefault"] = false,
|
||||||
["IsForced"] = false,
|
["IsForced"] = false,
|
||||||
|
["IsHearingImpaired"] = false,
|
||||||
["Type"] = "Audio",
|
["Type"] = "Audio",
|
||||||
["Index"] = 0,
|
["Index"] = 0,
|
||||||
["IsExternal"] = false,
|
["IsExternal"] = false,
|
||||||
@@ -366,14 +394,12 @@ public class JellyfinResponseBuilder
|
|||||||
["Level"] = 0
|
["Level"] = 0
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
["MediaAttachments"] = new List<object>(), // Empty array instead of null
|
["MediaAttachments"] = new List<object>(),
|
||||||
["Formats"] = new List<string>(), // Empty array instead of null
|
["Formats"] = new List<string>(),
|
||||||
["RequiredHttpHeaders"] = new Dictionary<string, string>(), // Empty dict instead of null
|
["Bitrate"] = 1337000,
|
||||||
["RunTimeTicks"] = (song.Duration ?? 180) * 10000000L, // Duration in ticks (100ns units)
|
["RequiredHttpHeaders"] = new Dictionary<string, string>(),
|
||||||
["Name"] = song.Title,
|
["TranscodingSubProtocol"] = "http",
|
||||||
["AnalyzeDurationMs"] = 0,
|
|
||||||
["DefaultAudioStreamIndex"] = 0,
|
["DefaultAudioStreamIndex"] = 0,
|
||||||
["DefaultSubtitleStreamIndex"] = -1,
|
|
||||||
["HasSegments"] = false
|
["HasSegments"] = false
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -401,40 +427,68 @@ public class JellyfinResponseBuilder
|
|||||||
|
|
||||||
var item = new Dictionary<string, object?>
|
var item = new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Id"] = album.Id,
|
|
||||||
["Name"] = albumName,
|
["Name"] = albumName,
|
||||||
["ServerId"] = "allstarr",
|
["ServerId"] = "allstarr",
|
||||||
["Type"] = "MusicAlbum",
|
["Id"] = album.Id,
|
||||||
|
["PremiereDate"] = album.Year.HasValue ? $"{album.Year}-01-01T05:00:00.0000000Z" : null,
|
||||||
|
["ChannelId"] = (object?)null,
|
||||||
|
["Genres"] = !string.IsNullOrEmpty(album.Genre)
|
||||||
|
? new[] { album.Genre }
|
||||||
|
: new string[0],
|
||||||
|
["RunTimeTicks"] = 0, // Could calculate from songs
|
||||||
|
["ProductionYear"] = album.Year,
|
||||||
["IsFolder"] = true,
|
["IsFolder"] = true,
|
||||||
["AlbumArtist"] = album.Artist,
|
["Type"] = "MusicAlbum",
|
||||||
["AlbumArtists"] = new[]
|
["GenreItems"] = !string.IsNullOrEmpty(album.Genre)
|
||||||
|
? new[]
|
||||||
{
|
{
|
||||||
new Dictionary<string, object?>
|
new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Id"] = album.ArtistId ?? album.Id,
|
["Name"] = album.Genre,
|
||||||
["Name"] = album.Artist
|
["Id"] = $"genre-{album.Genre?.ToLowerInvariant()}"
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
["ProductionYear"] = album.Year,
|
: new Dictionary<string, object?>[0],
|
||||||
["ChildCount"] = album.SongCount ?? album.Songs.Count,
|
["ParentLogoItemId"] = album.ArtistId ?? album.Id,
|
||||||
["ImageTags"] = new Dictionary<string, string>
|
["ParentBackdropItemId"] = album.ArtistId ?? album.Id,
|
||||||
{
|
["ParentBackdropImageTags"] = new string[0],
|
||||||
["Primary"] = album.Id
|
|
||||||
},
|
|
||||||
["BackdropImageTags"] = new string[0],
|
|
||||||
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
|
||||||
["LocationType"] = "FileSystem",
|
|
||||||
["MediaType"] = (object?)null,
|
|
||||||
["ChannelId"] = (object?)null,
|
|
||||||
["CollectionType"] = (object?)null,
|
|
||||||
["UserData"] = new Dictionary<string, object>
|
["UserData"] = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
["PlaybackPositionTicks"] = 0,
|
["PlaybackPositionTicks"] = 0,
|
||||||
["PlayCount"] = 0,
|
["PlayCount"] = 0,
|
||||||
["IsFavorite"] = false,
|
["IsFavorite"] = false,
|
||||||
["Played"] = false,
|
["Played"] = false,
|
||||||
["Key"] = album.Id
|
["Key"] = $"{album.Artist}-{album.Title}",
|
||||||
|
["ItemId"] = album.Id
|
||||||
|
},
|
||||||
|
["Artists"] = new[] { album.Artist },
|
||||||
|
["ArtistItems"] = new[]
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["Name"] = album.Artist,
|
||||||
|
["Id"] = album.ArtistId ?? album.Id
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
["AlbumArtist"] = album.Artist,
|
||||||
|
["AlbumArtists"] = new[]
|
||||||
|
{
|
||||||
|
new Dictionary<string, object?>
|
||||||
|
{
|
||||||
|
["Name"] = album.Artist,
|
||||||
|
["Id"] = album.ArtistId ?? album.Id
|
||||||
|
}
|
||||||
|
},
|
||||||
|
["ImageTags"] = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["Primary"] = album.Id
|
||||||
|
},
|
||||||
|
["BackdropImageTags"] = new string[0],
|
||||||
|
["ParentLogoImageTag"] = album.ArtistId ?? album.Id,
|
||||||
|
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
||||||
|
["LocationType"] = "FileSystem",
|
||||||
|
["MediaType"] = "Unknown",
|
||||||
|
["ChildCount"] = album.SongCount ?? album.Songs.Count
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add provider IDs for external content
|
// Add provider IDs for external content
|
||||||
@@ -446,11 +500,6 @@ public class JellyfinResponseBuilder
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(album.Genre))
|
|
||||||
{
|
|
||||||
item["Genres"] = new[] { album.Genre };
|
|
||||||
}
|
|
||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -468,30 +517,33 @@ public class JellyfinResponseBuilder
|
|||||||
|
|
||||||
var item = new Dictionary<string, object?>
|
var item = new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Id"] = artist.Id,
|
|
||||||
["Name"] = artistName,
|
["Name"] = artistName,
|
||||||
["ServerId"] = "allstarr",
|
["ServerId"] = "allstarr",
|
||||||
["Type"] = "MusicArtist",
|
["Id"] = artist.Id,
|
||||||
|
["ChannelId"] = (object?)null,
|
||||||
|
["Genres"] = new string[0], // Artists aggregate genres from albums/tracks
|
||||||
|
["RunTimeTicks"] = 0,
|
||||||
["IsFolder"] = true,
|
["IsFolder"] = true,
|
||||||
["AlbumCount"] = artist.AlbumCount ?? 0,
|
["Type"] = "MusicArtist",
|
||||||
["ImageTags"] = new Dictionary<string, string>
|
["GenreItems"] = new Dictionary<string, object?>[0],
|
||||||
{
|
|
||||||
["Primary"] = artist.Id
|
|
||||||
},
|
|
||||||
["BackdropImageTags"] = new string[0],
|
|
||||||
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
|
||||||
["LocationType"] = "FileSystem", // External content appears as local files to clients
|
|
||||||
["MediaType"] = (object?)null, // Match Jellyfin structure
|
|
||||||
["ChannelId"] = (object?)null, // Match Jellyfin structure
|
|
||||||
["CollectionType"] = (object?)null, // Match Jellyfin structure
|
|
||||||
["UserData"] = new Dictionary<string, object>
|
["UserData"] = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
["PlaybackPositionTicks"] = 0,
|
["PlaybackPositionTicks"] = 0,
|
||||||
["PlayCount"] = 0,
|
["PlayCount"] = 0,
|
||||||
["IsFavorite"] = false,
|
["IsFavorite"] = false,
|
||||||
["Played"] = false,
|
["Played"] = false,
|
||||||
["Key"] = artist.Id
|
["Key"] = $"Artist-{artist.Name}",
|
||||||
}
|
["ItemId"] = artist.Id
|
||||||
|
},
|
||||||
|
["ImageTags"] = new Dictionary<string, string>
|
||||||
|
{
|
||||||
|
["Primary"] = artist.Id
|
||||||
|
},
|
||||||
|
["BackdropImageTags"] = new string[0],
|
||||||
|
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
||||||
|
["LocationType"] = "FileSystem",
|
||||||
|
["MediaType"] = "Unknown",
|
||||||
|
["AlbumCount"] = artist.AlbumCount ?? 0
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add provider IDs for external content
|
// Add provider IDs for external content
|
||||||
@@ -528,7 +580,7 @@ public class JellyfinResponseBuilder
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts an ExternalPlaylist to a Jellyfin album item.
|
/// Converts an ExternalPlaylist to a Jellyfin playlist item.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Dictionary<string, object?> ConvertPlaylistToJellyfinItem(ExternalPlaylist playlist)
|
public Dictionary<string, object?> ConvertPlaylistToJellyfinItem(ExternalPlaylist playlist)
|
||||||
{
|
{
|
||||||
@@ -538,13 +590,24 @@ public class JellyfinResponseBuilder
|
|||||||
|
|
||||||
var item = new Dictionary<string, object?>
|
var item = new Dictionary<string, object?>
|
||||||
{
|
{
|
||||||
["Id"] = playlist.Id,
|
|
||||||
["Name"] = playlist.Name,
|
["Name"] = playlist.Name,
|
||||||
["ServerId"] = "allstarr",
|
["ServerId"] = "allstarr",
|
||||||
["Type"] = "Playlist",
|
["Id"] = playlist.Id,
|
||||||
|
["ChannelId"] = (object?)null,
|
||||||
|
["Genres"] = new string[0], // Playlists aggregate genres from tracks
|
||||||
|
["RunTimeTicks"] = playlist.Duration * TimeSpan.TicksPerSecond,
|
||||||
["IsFolder"] = true,
|
["IsFolder"] = true,
|
||||||
["AlbumArtist"] = curatorName,
|
["Type"] = "Playlist",
|
||||||
["Genres"] = new[] { "Playlist" },
|
["GenreItems"] = new Dictionary<string, object?>[0],
|
||||||
|
["UserData"] = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
["PlaybackPositionTicks"] = 0,
|
||||||
|
["PlayCount"] = 0,
|
||||||
|
["IsFavorite"] = false,
|
||||||
|
["Played"] = false,
|
||||||
|
["Key"] = playlist.Id,
|
||||||
|
["ItemId"] = playlist.Id
|
||||||
|
},
|
||||||
["ChildCount"] = playlist.TrackCount,
|
["ChildCount"] = playlist.TrackCount,
|
||||||
["ImageTags"] = new Dictionary<string, string>
|
["ImageTags"] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
@@ -553,20 +616,10 @@ public class JellyfinResponseBuilder
|
|||||||
["BackdropImageTags"] = new string[0],
|
["BackdropImageTags"] = new string[0],
|
||||||
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
["ImageBlurHashes"] = new Dictionary<string, object>(),
|
||||||
["LocationType"] = "FileSystem",
|
["LocationType"] = "FileSystem",
|
||||||
["MediaType"] = (object?)null,
|
["MediaType"] = "Audio",
|
||||||
["ChannelId"] = (object?)null,
|
|
||||||
["CollectionType"] = (object?)null,
|
|
||||||
["ProviderIds"] = new Dictionary<string, string>
|
["ProviderIds"] = new Dictionary<string, string>
|
||||||
{
|
{
|
||||||
[playlist.Provider] = playlist.ExternalId
|
[playlist.Provider] = playlist.ExternalId
|
||||||
},
|
|
||||||
["UserData"] = new Dictionary<string, object>
|
|
||||||
{
|
|
||||||
["PlaybackPositionTicks"] = 0,
|
|
||||||
["PlayCount"] = 0,
|
|
||||||
["IsFavorite"] = false,
|
|
||||||
["Played"] = false,
|
|
||||||
["Key"] = playlist.Id
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user