add collages for playlists
This commit is contained in:
parent
9b92cc20f2
commit
a46c5b0a75
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user