diff options
Diffstat (limited to 'MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs')
| -rw-r--r-- | MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs | 207 |
1 files changed, 40 insertions, 167 deletions
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs index ad3211650..20ce952db 100644 --- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs +++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs @@ -1,16 +1,13 @@ -using MediaBrowser.Common.Extensions; -using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Configuration; +using MediaBrowser.Controller.Drawing; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Audio; -using MediaBrowser.Controller.Library; using MediaBrowser.Controller.MediaInfo; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Entities; -using MediaBrowser.Model.Logging; +using MediaBrowser.Model.IO; using System; -using System.Collections.Concurrent; -using System.IO; -using System.Linq; +using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -19,207 +16,83 @@ namespace MediaBrowser.Providers.MediaInfo /// <summary> /// Uses ffmpeg to create video images /// </summary> - public class AudioImageProvider : BaseMetadataProvider + public class AudioImageProvider : IDynamicImageProvider, IHasChangeMonitor { - /// <summary> - /// The _locks - /// </summary> - private readonly ConcurrentDictionary<string, SemaphoreSlim> _locks = new ConcurrentDictionary<string, SemaphoreSlim>(); - - /// <summary> - /// The _media encoder - /// </summary> + private readonly IIsoManager _isoManager; private readonly IMediaEncoder _mediaEncoder; + private readonly IServerConfigurationManager _config; - /// <summary> - /// Initializes a new instance of the <see cref="BaseMetadataProvider" /> class. - /// </summary> - /// <param name="logManager">The log manager.</param> - /// <param name="configurationManager">The configuration manager.</param> - /// <param name="mediaEncoder">The media encoder.</param> - public AudioImageProvider(ILogManager logManager, IServerConfigurationManager configurationManager, IMediaEncoder mediaEncoder) - : base(logManager, configurationManager) + public AudioImageProvider(IIsoManager isoManager, IMediaEncoder mediaEncoder, IServerConfigurationManager config) { + _isoManager = isoManager; _mediaEncoder = mediaEncoder; + _config = config; } /// <summary> - /// Gets a value indicating whether [refresh on version change]. + /// The null mount task result /// </summary> - /// <value><c>true</c> if [refresh on version change]; otherwise, <c>false</c>.</value> - protected override bool RefreshOnVersionChange - { - get - { - return true; - } - } + protected readonly Task<IIsoMount> NullMountTaskResult = Task.FromResult<IIsoMount>(null); /// <summary> - /// Gets the provider version. + /// Mounts the iso if needed. /// </summary> - /// <value>The provider version.</value> - protected override string ProviderVersion + /// <param name="item">The item.</param> + /// <param name="cancellationToken">The cancellation token.</param> + /// <returns>Task{IIsoMount}.</returns> + protected Task<IIsoMount> MountIsoIfNeeded(Video item, CancellationToken cancellationToken) { - get + if (item.VideoType == VideoType.Iso) { - return "1"; + return _isoManager.Mount(item.Path, cancellationToken); } - } - /// <summary> - /// Supportses the specified item. - /// </summary> - /// <param name="item">The item.</param> - /// <returns><c>true</c> if XXXX, <c>false</c> otherwise</returns> - public override bool Supports(BaseItem item) - { - return item.LocationType == LocationType.FileSystem && item is Audio; + return NullMountTaskResult; } - /// <summary> - /// Override this to return the date that should be compared to the last refresh date - /// to determine if this provider should be re-fetched. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>DateTime.</returns> - protected override DateTime CompareDate(BaseItem item) + public IEnumerable<ImageType> GetSupportedImages(IHasImages item) { - return item.DateModified; - } - - /// <summary> - /// Gets the priority. - /// </summary> - /// <value>The priority.</value> - public override MetadataProviderPriority Priority - { - get { return MetadataProviderPriority.Last; } - } - - public override ItemUpdateType ItemUpdateType - { - get - { - return ItemUpdateType.ImageUpdate; - } + return new List<ImageType> { ImageType.Primary }; } - /// <summary> - /// Fetches metadata and returns true or false indicating if any work that requires persistence was done - /// </summary> - /// <param name="item">The item.</param> - /// <param name="force">if set to <c>true</c> [force].</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task{System.Boolean}.</returns> - public override async Task<bool> FetchAsync(BaseItem item, bool force, BaseProviderInfo providerInfo, CancellationToken cancellationToken) + public Task<DynamicImageResponse> GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken) { - item.ValidateImages(); - var audio = (Audio)item; - if (string.IsNullOrEmpty(audio.PrimaryImagePath) && audio.HasEmbeddedImage) + // Can't extract if we didn't find a video stream in the file + if (!audio.HasEmbeddedImage) { - try - { - await CreateImagesForSong(audio, cancellationToken).ConfigureAwait(false); - } - catch (Exception ex) - { - Logger.ErrorException("Error extracting image for {0}", ex, item.Name); - } + return Task.FromResult(new DynamicImageResponse { HasImage = false }); } - SetLastRefreshed(item, DateTime.UtcNow, providerInfo); - return true; + return GetVideoImage((Audio)item, cancellationToken); } - /// <summary> - /// Creates the images for song. - /// </summary> - /// <param name="item">The item.</param> - /// <param name="cancellationToken">The cancellation token.</param> - /// <returns>Task.</returns> - /// <exception cref="System.InvalidOperationException">Can't extract an image unless the audio file has an embedded image.</exception> - private async Task CreateImagesForSong(Audio item, CancellationToken cancellationToken) + public async Task<DynamicImageResponse> GetVideoImage(Audio item, CancellationToken cancellationToken) { - cancellationToken.ThrowIfCancellationRequested(); + var stream = await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, cancellationToken).ConfigureAwait(false); - var path = GetAudioImagePath(item); - - if (!File.Exists(path)) + return new DynamicImageResponse { - var semaphore = GetLock(path); - - // Acquire a lock - await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); - - // Check again - if (!File.Exists(path)) - { - try - { - var parentPath = Path.GetDirectoryName(path); - - Directory.CreateDirectory(parentPath); - - await _mediaEncoder.ExtractImage(new[] { item.Path }, InputType.File, true, null, null, path, cancellationToken).ConfigureAwait(false); - } - finally - { - semaphore.Release(); - } - } - else - { - semaphore.Release(); - } - } - - // Image is already in the cache - item.SetImagePath(ImageType.Primary, path); + Format = ImageFormat.Jpg, + HasImage = true, + Stream = stream + }; } - /// <summary> - /// Gets the audio image path. - /// </summary> - /// <param name="item">The item.</param> - /// <returns>System.String.</returns> - private string GetAudioImagePath(Audio item) + public string Name { - 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); + get { return "Embedded Image"; } } - /// <summary> - /// Gets the audio images data path. - /// </summary> - /// <value>The audio images data path.</value> - public string AudioImagesPath + public bool Supports(IHasImages item) { - get - { - return Path.Combine(ConfigurationManager.ApplicationPaths.DataPath, "extracted-audio-images"); - } + return item.LocationType == LocationType.FileSystem && item is Audio; } - /// <summary> - /// Gets the lock. - /// </summary> - /// <param name="filename">The filename.</param> - /// <returns>SemaphoreSlim.</returns> - private SemaphoreSlim GetLock(string filename) + public bool HasChanged(IHasMetadata item, DateTime date) { - return _locks.GetOrAdd(filename, key => new SemaphoreSlim(1, 1)); + return item.DateModified > date; } } } |
