add collages for playlists

This commit is contained in:
Luke Pulverenti 2014-08-11 22:59:51 -04:00
parent 9b92cc20f2
commit a46c5b0a75
4 changed files with 256 additions and 4 deletions

View File

@ -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.Common.Events;
using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Dlna.Server; using MediaBrowser.Dlna.Server;
@ -56,10 +58,24 @@ namespace MediaBrowser.Dlna.Ssdp
public event EventHandler<SsdpMessageEventArgs> MessageReceived; 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)) 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"]); RespondToSearch(args.EndPoint, args.Headers["st"]);
} }
@ -168,7 +184,7 @@ namespace MediaBrowser.Dlna.Ssdp
values["ST"] = d.Type; values["ST"] = d.Type;
values["USN"] = d.USN; values["USN"] = d.USN;
SendDatagram(header, values, endpoint, null); SendDatagram(header, values, endpoint);
if (_config.GetDlnaConfiguration().EnableDebugLogging) if (_config.GetDlnaConfiguration().EnableDebugLogging)
{ {

View File

@ -1,5 +1,6 @@
using MediaBrowser.Common.Net; using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Playlists;
using MediaBrowser.Controller.Providers; using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Providers; using MediaBrowser.Model.Providers;
@ -31,6 +32,22 @@ namespace MediaBrowser.Providers.FolderImages
public Task<IEnumerable<RemoteImageInfo>> GetImages(IHasImages item, CancellationToken cancellationToken) 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; var view = item as UserView;
if (view != null) if (view != null)
@ -111,7 +128,7 @@ namespace MediaBrowser.Providers.FolderImages
public bool Supports(IHasImages item) 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) public Task<HttpResponseInfo> GetImageResponse(string url, CancellationToken cancellationToken)

View File

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

View File

@ -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);
}
}
}
}