Browse Source

add collages for playlists

Luke Pulverenti 11 years ago
parent
commit
a46c5b0a75

+ 19 - 3
MediaBrowser.Dlna/Ssdp/SsdpHandler.cs

@@ -1,4 +1,6 @@
-using MediaBrowser.Common.Configuration;
+using System.Globalization;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Configuration;
 using MediaBrowser.Common.Events;
 using MediaBrowser.Controller.Configuration;
 using MediaBrowser.Dlna.Server;
@@ -56,10 +58,24 @@ namespace MediaBrowser.Dlna.Ssdp
 
         public event EventHandler<SsdpMessageEventArgs> MessageReceived;
 
-        private void OnMessageReceived(SsdpMessageEventArgs args)
+        private async void OnMessageReceived(SsdpMessageEventArgs args)
         {
             if (string.Equals(args.Method, "M-SEARCH", StringComparison.OrdinalIgnoreCase))
             {
+                var mx = args.Headers["mx"];
+                int delaySeconds;
+                if (!string.IsNullOrWhiteSpace(mx) && 
+                    int.TryParse(mx, NumberStyles.Any, CultureInfo.InvariantCulture, out delaySeconds)
+                    && delaySeconds > 0)
+                {
+                    if (_config.GetDlnaConfiguration().EnableDebugLogging)
+                    {
+                        _logger.Debug("Delaying search response by {0} seconds", delaySeconds);
+                    }
+
+                    await Task.Delay(delaySeconds * 1000).ConfigureAwait(false);
+                }
+
                 RespondToSearch(args.EndPoint, args.Headers["st"]);
             }
 
@@ -168,7 +184,7 @@ namespace MediaBrowser.Dlna.Ssdp
                     values["ST"] = d.Type;
                     values["USN"] = d.USN;
 
-                    SendDatagram(header, values, endpoint, null);
+                    SendDatagram(header, values, endpoint);
 
                     if (_config.GetDlnaConfiguration().EnableDebugLogging)
                     {

+ 18 - 1
MediaBrowser.Providers/FolderImages/DefaultImageProvider.cs

@@ -1,5 +1,6 @@
 using MediaBrowser.Common.Net;
 using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Playlists;
 using MediaBrowser.Controller.Providers;
 using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Providers;
@@ -31,6 +32,22 @@ namespace MediaBrowser.Providers.FolderImages
 
         public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken)
         {
+            var playlist = item as Playlist;
+            if (playlist != null)
+            {
+                var url = GetImageUrl(null);
+
+                return Task.FromResult<IEnumerable<RemoteImageInfo>>(new List<RemoteImageInfo>
+                {
+                         new RemoteImageInfo
+                         {
+                              ProviderName = Name,
+                              Url = url,
+                              Type = ImageType.Primary
+                         }
+                 });
+            }
+
             var view = item as UserView;
 
             if (view != null)
@@ -111,7 +128,7 @@ namespace MediaBrowser.Providers.FolderImages
 
         public bool Supports(IHasImages item)
         {
-            return item is UserView || item is ICollectionFolder;
+            return item is UserView || item is ICollectionFolder || item is Playlist;
         }
 
         public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)

+ 1 - 0
MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj

@@ -226,6 +226,7 @@
     <Compile Include="Persistence\SqliteShrinkMemoryTimer.cs" />
     <Compile Include="Persistence\TypeMapper.cs" />
     <Compile Include="Playlists\ManualPlaylistsFolder.cs" />
+    <Compile Include="Playlists\PlaylistImageEnhancer.cs" />
     <Compile Include="Playlists\PlaylistManager.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
     <Compile Include="ScheduledTasks\PeopleValidationTask.cs" />

+ 218 - 0
MediaBrowser.Server.Implementations/Playlists/PlaylistImageEnhancer.cs

@@ -0,0 +1,218 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities.Audio;
+using MediaBrowser.Controller.Entities.TV;
+using MediaBrowser.Controller.Playlists;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.Drawing;
+using MediaBrowser.Model.Entities;
+using MoreLinq;
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Drawing.Drawing2D;
+using System.Drawing.Imaging;
+using System.IO;
+using System.Linq;
+using System.Threading.Tasks;
+
+namespace MediaBrowser.Server.Implementations.Playlists
+{
+    public class PlaylistImageEnhancer : IImageEnhancer
+    {
+        private readonly IFileSystem _fileSystem;
+
+        public PlaylistImageEnhancer(IFileSystem fileSystem)
+        {
+            _fileSystem = fileSystem;
+        }
+
+        public bool Supports(IHasImages item, ImageType imageType)
+        {
+            return imageType == ImageType.Primary && item is Playlist;
+        }
+
+        public MetadataProviderPriority Priority
+        {
+            get { return MetadataProviderPriority.First; }
+        }
+
+        private List<BaseItem> GetItemsWithImages(IHasImages item)
+        {
+            var playlist = (Playlist)item;
+
+            var items = playlist.GetManageableItems()
+                .Select(i =>
+                {
+                    var subItem = i.Item2;
+
+                    var episode = subItem as Episode;
+
+                    if (episode != null)
+                    {
+                        var series = episode.Series;
+                        if (series != null && series.HasImage(ImageType.Primary))
+                        {
+                            return series;
+                        }
+                    }
+
+                    if (subItem.HasImage(ImageType.Primary))
+                    {
+                        return subItem;
+                    }
+
+                    var parent = subItem.Parent;
+
+                    if (parent != null && parent.HasImage(ImageType.Primary))
+                    {
+                        if (parent is MusicAlbum)
+                        {
+                            return parent;
+                        }
+                    }
+
+                    return null;
+                })
+                .Where(i => i != null)
+                .DistinctBy(i => i.Id)
+                .OrderBy(i => Guid.NewGuid())
+                .Take(4)
+                .OrderBy(i => i.Name)
+                .ToList();
+
+            if (items.Count == 0)
+            {
+                return new List<BaseItem>();
+            }
+
+            return items;
+        }
+
+        private const string Version = "3";
+
+        public string GetConfigurationCacheKey(List<BaseItem> items)
+        {
+            return Version + "_" + string.Join(",", items.Select(i => i.Id.ToString("N")).ToArray());
+        }
+
+        public string GetConfigurationCacheKey(IHasImages item, ImageType imageType)
+        {
+            var items = GetItemsWithImages(item);
+
+            return GetConfigurationCacheKey(items);
+        }
+
+        private const int ImageSize = 800;
+
+        public ImageSize GetEnhancedImageSize(IHasImages item, ImageType imageType, int imageIndex, ImageSize originalImageSize)
+        {
+            var items = GetItemsWithImages(item);
+
+            if (items.Count == 0)
+            {
+                return originalImageSize;
+            }
+
+            return new ImageSize
+            {
+                Height = ImageSize,
+                Width = ImageSize
+            };
+        }
+
+        public async Task<Image> EnhanceImageAsync(IHasImages item, Image originalImage, ImageType imageType, int imageIndex)
+        {
+            var items = GetItemsWithImages(item);
+
+            if (items.Count == 0)
+            {
+                return originalImage;
+            }
+
+            var img = await GetCollage(items).ConfigureAwait(false);
+
+            using (originalImage)
+            {
+                return img;
+            }
+        }
+
+        private Task<Image> GetCollage(List<BaseItem> items)
+        {
+            return GetCollage(items.Select(i => i.GetImagePath(ImageType.Primary)).ToList());
+        }
+
+        private async Task<Image> GetCollage(List<string> files)
+        {
+            if (files.Count < 4)
+            {
+                return await GetSingleImage(files).ConfigureAwait(false);
+            }
+
+            const int rows = 2;
+            const int cols = 2;
+
+            const int singleSize = ImageSize / 2;
+            var index = 0;
+
+            var img = new Bitmap(ImageSize, ImageSize, PixelFormat.Format32bppPArgb);
+
+            using (var graphics = Graphics.FromImage(img))
+            {
+                graphics.CompositingQuality = CompositingQuality.HighQuality;
+                graphics.SmoothingMode = SmoothingMode.HighQuality;
+                graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
+                graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
+                graphics.CompositingMode = CompositingMode.SourceCopy;
+
+                for (var row = 0; row < rows; row++)
+                {
+                    for (var col = 0; col < cols; col++)
+                    {
+                        var x = col * singleSize;
+                        var y = row * singleSize;
+
+                        using (var fileStream = _fileSystem.GetFileStream(files[index], FileMode.Open, FileAccess.Read, FileShare.Read, true))
+                        {
+                            using (var memoryStream = new MemoryStream())
+                            {
+                                await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);
+
+                                memoryStream.Position = 0;
+
+                                using (var imgtemp = Image.FromStream(memoryStream, true, false))
+                                {
+                                    graphics.DrawImage(imgtemp, x, y, singleSize, singleSize);
+                                }
+                            }
+                        }
+
+                        index++;
+                    }
+                }
+            }
+
+            return img;
+        }
+
+        private Task<Image> GetSingleImage(List<string> files)
+        {
+            return GetImage(files[0]);
+        }
+
+        private async Task<Image> GetImage(string file)
+        {
+            using (var fileStream = _fileSystem.GetFileStream(file, FileMode.Open, FileAccess.Read, FileShare.Read, true))
+            {
+                var memoryStream = new MemoryStream();
+
+                await fileStream.CopyToAsync(memoryStream).ConfigureAwait(false);
+
+                memoryStream.Position = 0;
+
+                return Image.FromStream(memoryStream, true, false);
+            }
+        }
+    }
+}