Cleanup and Music Artist and Music Album support

Cleaned up some commented out code, but didn't get as much cleanup does
as I'd like because I realised I should really implement music properly
before removing the old code that does music.
Implemened the well known Music/All Music, Music/Artist and Music/Genre
folders as well as the sub items for those folders which are
MusicAlbumItem, MusicArtistItem and MusicItem
This commit is contained in:
ScottRapsey 2013-02-25 17:24:42 +11:00
parent a5df7eb442
commit b21260b1d5
2 changed files with 319 additions and 132 deletions

View File

@ -111,7 +111,14 @@ namespace MediaBrowser.Plugins.Dlna.Model
internal MusicContainer(User user)
: base(user, user.RootFolder, id: "1", parentId: "0", title: "Music")
{
this.AllMusic = new AllMusicContainer(user);
this.Genre = new AllMusicContainer(user);
this.Artist = new MusicArtistContainer(user);
}
internal AllMusicContainer AllMusic { get; private set; }
internal AllMusicContainer Genre { get; private set; }
internal MusicArtistContainer Artist { get; private set; }
protected internal override Platinum.MediaObject MediaObject
{
get { return this.MediaContainer; }
@ -120,7 +127,7 @@ namespace MediaBrowser.Plugins.Dlna.Model
{
get
{
return new List<ModelBase>();
return new List<ModelBase>() {this.AllMusic, this.Genre, this.Artist} ;
}
}
}
@ -130,12 +137,12 @@ namespace MediaBrowser.Plugins.Dlna.Model
: base(user, user.RootFolder, id: "2", parentId: "0", title: "Video")
{
this.AllVideo = new AllVideoContainer(user);
this.Genre = new VideoFoldersContainer(user);
this.Genre = new VideoGenreContainer(user);
this.Actor = new ActorContainer(user);
this.Folders = new VideoFoldersContainer(user);
}
internal AllVideoContainer AllVideo { get; private set; }
internal VideoFoldersContainer Genre { get; private set; }
internal VideoGenreContainer Genre { get; private set; }
internal ActorContainer Actor { get; private set; }
internal VideoFoldersContainer Folders { get; private set; }
@ -148,6 +155,60 @@ namespace MediaBrowser.Plugins.Dlna.Model
}
}
internal class AllMusicContainer : WellKnownContainerBase
{
internal AllMusicContainer(User user)
: base(user, user.RootFolder, id: "4", parentId: "1", title: "All Music")
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.MbFolder.GetRecursiveChildren(User).OfType<MediaBrowser.Controller.Entities.Audio.Audio>().Select(i => new MusicItem(this.User, i, parentId: this.Id));
}
}
}
internal class MusicArtistContainer : WellKnownContainerBase
{
internal MusicArtistContainer(User user)
: base(user, user.RootFolder, id: "6", parentId: "1", title: "Artist")
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.MbFolder.GetRecursiveChildren(this.User)
.OfType<MediaBrowser.Controller.Entities.Audio.MusicArtist>()
.DistinctBy(person => person.Name, StringComparer.OrdinalIgnoreCase)
.OrderBy(person => person.Name)
.Select(i => new MusicArtistItem(this.User, i, parentId: this.Id));
}
}
}
internal class MusicAlbumContainer : WellKnownContainerBase
{
internal MusicAlbumContainer(User user)
: base(user, user.RootFolder, id: "7", parentId: "1", title: "Album")
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.MbFolder.GetRecursiveChildren(this.User)
.OfType<MediaBrowser.Controller.Entities.Audio.MusicAlbum>()
.DistinctBy(album => album.Name, StringComparer.OrdinalIgnoreCase)
.OrderBy(album => album.Name)
.Select(album => new MusicAlbumItem(this.User, album, parentId: this.Id));
}
}
}
internal class AllVideoContainer : WellKnownContainerBase
{
internal AllVideoContainer(User user)
@ -162,6 +223,33 @@ namespace MediaBrowser.Plugins.Dlna.Model
}
}
}
internal class VideoGenreContainer : WellKnownContainerBase
{
internal VideoGenreContainer(User user)
: base(user, user.RootFolder, id: "9", parentId: "2", title: "Genre")
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.MbFolder.GetRecursiveChildren(this.User)
.OfType<Video>()
.SelectMany(video =>
{
if (video.Genres == null)
{
return new string[] { };
}
return video.Genres.Where(genre => !string.IsNullOrWhiteSpace(genre));
})
.DistinctBy(genre => genre, StringComparer.OrdinalIgnoreCase)
.OrderBy(genre => genre)
.Select(genre => new VideoGenreItem(this.User, genre, parentId: this.Id));
}
}
}
internal class ActorContainer : WellKnownContainerBase
{
internal ActorContainer(User user)
@ -297,7 +385,60 @@ namespace MediaBrowser.Plugins.Dlna.Model
get { return System.IO.Path.GetExtension(this.MBItem.Path); }
}
}
internal class VideoGenreItem : ModelBase
{
internal VideoGenreItem(User user, string genre, string parentId)
: base(user, genre.GetMD5().ToString(), parentId)
{
this.Genre = genre;
}
protected internal string Genre { get; private set; }
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.User.RootFolder.GetRecursiveChildren(User)
.OfType<Video>()
.Where(i => i.Genres
.Any(g => string.Equals(g, this.Genre, StringComparison.OrdinalIgnoreCase)))
.Select(i => new VideoItem(this.User, i, parentId: this.Id));
}
}
protected internal override Platinum.MediaObject MediaObject
{
get { return this.MediaContainer; }
}
internal Platinum.MediaContainer MediaContainer
{
get
{
var result = new Platinum.MediaContainer();
result.ObjectID = this.Id;
result.ParentID = this.ParentId;
result.Class = new Platinum.ObjectClass("object.container.genre.videoGenre", "");
result.Title = this.Genre == null ? string.Empty : this.Genre;
result.Description.DescriptionText = this.Genre == null ? string.Empty : this.Genre;
result.Description.LongDescriptionText = this.Genre == null ? string.Empty : this.Genre;
return result;
}
}
protected internal override Platinum.MediaResource MainMediaResource
{
get
{
var result = new Platinum.MediaResource();
return result;
}
}
protected internal override string Extension
{
get { return string.Empty; }
}
}
internal class ActorItem : ModelBase
{
internal ActorItem(User user, PersonInfo item, string parentId)
@ -352,4 +493,126 @@ namespace MediaBrowser.Plugins.Dlna.Model
get { return string.Empty; }
}
}
internal class MusicItem : ModelBaseItem<MediaBrowser.Controller.Entities.Audio.Audio>
{
internal MusicItem(User user, MediaBrowser.Controller.Entities.Audio.Audio mbItem, string parentId)
: base(user, mbItem, parentId)
{
}
protected internal override IEnumerable<ModelBase> Children { get { return new List<ModelBase>(); } }
protected internal override Platinum.MediaObject MediaObject
{
get { return this.MediaItem; }
}
internal Platinum.MediaItem MediaItem
{
get
{
var result = MediaItemHelper.GetMediaItem(this.MBItem);
result.ParentID = this.ParentId;
return result;
}
}
protected internal override Platinum.MediaResource MainMediaResource
{
get
{
return MediaItemHelper.GetMediaResource(this.MBItem);
}
}
protected internal override string Extension
{
get { return System.IO.Path.GetExtension(this.MBItem.Path); }
}
}
internal class MusicArtistItem : ModelBaseItem<MediaBrowser.Controller.Entities.Audio.MusicArtist>
{
internal MusicArtistItem(User user, MediaBrowser.Controller.Entities.Audio.MusicArtist mbItem, string parentId)
: base(user, mbItem, parentId)
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.User.RootFolder.GetRecursiveChildren(this.User)
.OfType<MediaBrowser.Controller.Entities.Audio.Audio>()
.Where(i=> string.Equals(i.Artist, this.MBItem.Name, StringComparison.OrdinalIgnoreCase))
.Select(i=> new MusicItem(this.User, i, this.Id));
}
}
protected internal override Platinum.MediaObject MediaObject
{
get { return this.MediaItem; }
}
internal Platinum.MediaItem MediaItem
{
get
{
var result = MediaItemHelper.GetMediaItem(this.MBItem);
result.ParentID = this.ParentId;
return result;
}
}
protected internal override Platinum.MediaResource MainMediaResource
{
get
{
return MediaItemHelper.GetMediaResource(this.MBItem);
}
}
protected internal override string Extension
{
get { return System.IO.Path.GetExtension(this.MBItem.Path); }
}
}
internal class MusicAlbumItem : ModelBaseItem<MediaBrowser.Controller.Entities.Audio.MusicAlbum>
{
internal MusicAlbumItem(User user, MediaBrowser.Controller.Entities.Audio.MusicAlbum mbItem, string parentId)
: base(user, mbItem, parentId)
{
}
protected internal override IEnumerable<ModelBase> Children
{
get
{
return this.User.RootFolder.GetRecursiveChildren(this.User)
.OfType<MediaBrowser.Controller.Entities.Audio.Audio>()
.Where(i => string.Equals(i.Album, this.MBItem.Name, StringComparison.OrdinalIgnoreCase))
.Select(i => new MusicItem(this.User, i, this.Id));
}
}
protected internal override Platinum.MediaObject MediaObject
{
get { return this.MediaItem; }
}
internal Platinum.MediaItem MediaItem
{
get
{
var result = MediaItemHelper.GetMediaItem(this.MBItem);
result.ParentID = this.ParentId;
return result;
}
}
protected internal override Platinum.MediaResource MainMediaResource
{
get
{
return MediaItemHelper.GetMediaResource(this.MBItem);
}
}
protected internal override string Extension
{
get { return System.IO.Path.GetExtension(this.MBItem.Path); }
}
}
}

View File

@ -255,46 +255,7 @@ namespace MediaBrowser.Plugins.Dlna
//I'm just not sure if those folders listed with object IDs are all well known across clients or if these ones are WMP specific
//if they are device specific but also significant, then that might explain why Plex goes to the trouble of having configurable client device profiles for its DLNA server
//var didl = Platinum.Didl.header;
//IEnumerable<BaseItem> children = null;
//// I need to ask someone on the MB team if there's a better way to do this, it seems like it
////could get pretty expensive to get ALL children all the time
////if it's our only option perhaps we should cache results locally or something similar
//children = this.CurrentUser.RootFolder.GetRecursiveChildren(this.CurrentUser);
////children = children.Filter(Extensions.FilterType.Music | Extensions.FilterType.Video).Page(starting_index, requested_count);
//int itemCount = 0;
//if (children != null)
//{
// foreach (var child in children)
// {
// using (var item = BaseItemToMediaItem(child, context))
// {
// if (item != null)
// {
// string test;
// test = item.ToDidl(filter);
// didl += item.ToDidl(filter);
// itemCount++;
// }
// }
// }
// didl += Platinum.Didl.footer;
// action.SetArgumentValue("Result", didl);
// action.SetArgumentValue("NumberReturned", itemCount.ToString());
// action.SetArgumentValue("TotalMatches", itemCount.ToString());
// // update ID may be wrong here, it should be the one of the container?
// action.SetArgumentValue("UpdateId", "1");
// return NEP_Success;
//XBOX360 Video
//BrowseDirectChildren Entered - Parameters:
//action: { Name:"Browse", Description:" { Name:"Browse", Arguments:[ ] } ",
@ -323,66 +284,48 @@ namespace MediaBrowser.Plugins.Dlna
2013-02-24 22:47:09.0699, Info, App, ProcessFileRequest Entered - Parameters: context: { LocalAddress:{ IP:192.168.1.56, Port:1733 }, RemoteAddress:{ IP:192.168.1.27, Port:9842 }, Request:"http://192.168.1.56:1733/1ce95963-d31a-3052-8cf1-f31e934bd4fe?albumArt=true", Signature:XBox } response:Platinum.HttpResponse
2013-02-24 22:47:24.0908, Info, App, BrowseDirectChildren Entered - Parameters: action: { Name:"Browse", Description:" { Name:"Browse", Arguments:[ ] } ", Arguments:[ ] } object_id:90a8b701-b1ca-325d-e00f-d3f60267584d filter:dc:title,res,res@protection,res@duration,res@bitrate,upnp:genre,upnp:actor,res@microsoft:codec starting_index:0 requested_count:1000 sort_criteria:+upnp:class,+dc:title context: { LocalAddress:{ IP:192.168.1.56, Port:1733 }, RemoteAddress:{ IP:192.168.1.27, Port:44378 }, Request:"http://192.168.1.56:1733/ContentDirectory/944ef00a-1bd9-d8f2-02ab-9a5de207da75/control.xml", Signature:XBox }
*/
var didl = Platinum.Didl.header;
int itemCount = 0;
IEnumerable<Model.ModelBase> children = null;
Model.ModelBase objectIDMatch;
// I need to ask someone on the MB team if there's a better way to do this, it seems like it
//could get pretty expensive to get ALL children all the time
//if it's our only option perhaps we should cache results locally or something similar
Model.ModelBase objectIDMatch = null;
var root = new Model.Root(this.CurrentUser);
if (string.Equals(object_id, "0", StringComparison.OrdinalIgnoreCase))
objectIDMatch = root;
else
objectIDMatch = root.GetChildRecursive(object_id);
if (objectIDMatch == null)
if (objectIDMatch != null)
{
didl += Platinum.Didl.footer;
action.SetArgumentValue("Result", didl);
action.SetArgumentValue("NumberReturned", itemCount.ToString());
action.SetArgumentValue("TotalMatches", itemCount.ToString());
// update ID may be wrong here, it should be the one of the container?
action.SetArgumentValue("UpdateId", "1");
return NEP_Success;
}
children = objectIDMatch.Children;
if (children != null)
{
foreach (var child in children)
var children = objectIDMatch.Children;
if (children != null)
{
using (var item = child.MediaObject)
int itemCount = 0;
var didl = Platinum.Didl.header;
foreach (var child in children)
{
if (item != null)
using (var item = child.MediaObject)
{
AddContextInfo(item, child.MainMediaResource, child.Id, child.Extension, context);
if (item != null)
{
AddContextInfo(item, child.MainMediaResource, child.Id, child.Extension, context);
string test;
test = item.ToDidl(filter);
didl += item.ToDidl(filter);
itemCount++;
string test;
test = item.ToDidl(filter);
didl += item.ToDidl(filter);
itemCount++;
}
}
}
didl += Platinum.Didl.footer;
action.SetArgumentValue("Result", didl);
action.SetArgumentValue("NumberReturned", itemCount.ToString());
action.SetArgumentValue("TotalMatches", itemCount.ToString());
// update ID may be wrong here, it should be the one of the container?
action.SetArgumentValue("UpdateId", "1");
return NEP_Success;
}
didl += Platinum.Didl.footer;
action.SetArgumentValue("Result", didl);
action.SetArgumentValue("NumberReturned", itemCount.ToString());
action.SetArgumentValue("TotalMatches", itemCount.ToString());
// update ID may be wrong here, it should be the one of the container?
action.SetArgumentValue("UpdateId", "1");
return NEP_Success;
}
return NEP_Failure;
}
@ -462,50 +405,6 @@ namespace MediaBrowser.Plugins.Dlna
//this means it wants albums put into containers, I thought Platinum might do this for us, but it doesn't
//var didl = Platinum.Didl.header;
//IEnumerable<BaseItem> children = null;
//// I need to ask someone on the MB team if there's a better way to do this, it seems like it
////could get pretty expensive to get ALL children all the time
////if it's our only option perhaps we should cache results locally or something similar
//children = this.CurrentUser.RootFolder.GetRecursiveChildren(this.CurrentUser);
////children = children.Filter(Extensions.FilterType.Music | Extensions.FilterType.Video).Page(starting_index, requested_count);
////var test = GetFilterFromCriteria(searchCriteria);
//children = children.Where(GetBaseItemMatchFromCriteria(searchCriteria));
//int itemCount = 0;
//if (children != null)
//{
// Platinum.MediaItem item = null;
// foreach (var child in children)
// {
// item = BaseItemToMediaItem(child, context);
// if (item != null)
// {
// item.ParentID = string.Empty;
// didl += item.ToDidl(filter);
// itemCount++;
// }
// }
// didl += Platinum.Didl.footer;
// action.SetArgumentValue("Result", didl);
// action.SetArgumentValue("NumberReturned", itemCount.ToString());
// action.SetArgumentValue("TotalMatches", itemCount.ToString());
// // update ID may be wrong here, it should be the one of the container?
// action.SetArgumentValue("UpdateId", "1");
// return NEP_Success;
//}
//return NEP_Failure;
var didl = Platinum.Didl.header;
int itemCount = 0;
@ -663,6 +562,7 @@ namespace MediaBrowser.Plugins.Dlna
result.AddResource(resource);
}
MediaItemHelper.AddAlbumArtInfoToMediaItem(result, id, Kernel.HttpServerUrlPrefix, ips);
}
}
@ -1004,6 +904,30 @@ namespace MediaBrowser.Plugins.Dlna
return result;
}
internal static Platinum.MediaResource GetMediaResource(MusicArtist item)
{
//there's nothing specific about an music artist item that requires extra Resources
return GetMediaResource((BaseItem)item);
}
internal static Platinum.MediaItem GetMediaItem(MusicArtist item)
{
var result = GetMediaItem((BaseItem)item);
result.Title = item.Name;
return result;
}
internal static Platinum.MediaResource GetMediaResource(MusicAlbum item)
{
//there's nothing specific about an music artist item that requires extra Resources
return GetMediaResource((BaseItem)item);
}
internal static Platinum.MediaItem GetMediaItem(MusicAlbum item)
{
var result = GetMediaItem((BaseItem)item);
result.Title = item.Name;
return result;
}
internal static Platinum.MediaResource GetMediaResource(BaseItem item)
{
var result = new Platinum.MediaResource();