aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-06 18:52:59 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-02-06 18:52:59 -0500
commit69bba586f53477824cf1bb1fdb81e01aa6d470ac (patch)
treed81ea8dab3ee0e22503825de9448139254706a68
parent14084fdd87932823e9a843244b39b6334ccf128e (diff)
share audio images from same artist/album
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs81
1 files changed, 73 insertions, 8 deletions
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index 20ce952db..e22c94f5a 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -1,5 +1,6 @@
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Drawing;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.MediaInfo;
@@ -7,7 +8,10 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using System;
+using System.Collections.Concurrent;
using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -18,15 +22,19 @@ namespace MediaBrowser.Providers.MediaInfo
/// </summary>
public class AudioImageProvider : IDynamicImageProvider, IHasChangeMonitor
{
+ private readonly ConcurrentDictionary<string, SemaphoreSlim> _locks = new ConcurrentDictionary<string, SemaphoreSlim>();
+
private readonly IIsoManager _isoManager;
private readonly IMediaEncoder _mediaEncoder;
private readonly IServerConfigurationManager _config;
+ private readonly IFileSystem _fileSystem;
- public AudioImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config)
+ public AudioImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config, IFileSystem fileSystem)
{
_isoManager = isoManager;
_mediaEncoder = mediaEncoder;
_config = config;
+ _fileSystem = fileSystem;
}
/// <summary>
@@ -65,21 +73,78 @@ namespace MediaBrowser.Providers.MediaInfo
return Task.FromResult(new DynamicImageResponse { HasImage = false });
}
- return GetVideoImage((Audio)item, cancellationToken);
+ return GetImage((Audio)item, cancellationToken);
}
- public async Task<DynamicImageResponse> GetVideoImage(Audio item, CancellationToken cancellationToken)
+ public async Task<DynamicImageResponse> GetImage(Audio item, CancellationToken cancellationToken)
{
- var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false);
+ var path = GetAudioImagePath(item);
+
+ if (!File.Exists(path))
+ {
+ using (var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false))
+ {
+ var semaphore = GetLock(path);
+
+ Directory.CreateDirectory(Path.GetDirectoryName(path));
+
+ // Acquire a lock
+ await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+ try
+ {
+ using (var fileStream = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
+ {
+ await stream.CopyToAsync(fileStream).ConfigureAwait(false);
+ }
+ }
+ finally
+ {
+ semaphore.Release();
+ }
+ }
+ }
return new DynamicImageResponse
{
- Format = ImageFormat.Jpg,
HasImage = true,
- Stream = stream
+ Path = path
};
}
+ private string GetAudioImagePath(Audio item)
+ {
+ var album = item.Parent as MusicAlbum;
+
+ var filename = item.Album ?? string.Empty;
+ filename += item.Artists.FirstOrDefault() ?? string.Empty;
+ filename += album == null ? item.Id.ToString("N") + "_primary" + item.DateModified.Ticks : album.Id.ToString("N") + album.DateModified.Ticks + "_primary";
+
+ filename = filename.GetMD5() + ".jpg";
+
+ var prefix = filename.Substring(0, 1);
+
+ return Path.Combine(AudioImagesPath, prefix, filename);
+ }
+
+ public string AudioImagesPath
+ {
+ get
+ {
+ return Path.Combine(_config.ApplicationPaths.CachePath, "extracted-audio-images");
+ }
+ }
+
+ /// <summary>
+ /// Gets the lock.
+ /// </summary>
+ /// <param name="filename">The filename.</param>
+ /// <returns>SemaphoreSlim.</returns>
+ private SemaphoreSlim GetLock(string filename)
+ {
+ return _locks.GetOrAdd(filename, key => new SemaphoreSlim(1, 1));
+ }
+
public string Name
{
get { return "Embedded Image"; }