1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
|
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
namespace MediaBrowser.Providers.MediaInfo
{
/// <summary>
/// Uses ffmpeg to create video images
/// </summary>
public class AudioImageProvider : IDynamicImageProvider
{
private readonly IMediaEncoder _mediaEncoder;
private readonly IServerConfigurationManager _config;
private readonly IFileSystem _fileSystem;
public AudioImageProvider(IMediaEncoder mediaEncoder, IServerConfigurationManager config, IFileSystem fileSystem)
{
_mediaEncoder = mediaEncoder;
_config = config;
_fileSystem = fileSystem;
}
public IEnumerable<ImageType> GetSupportedImages(BaseItem item)
{
return new List<ImageType> { ImageType.Primary };
}
public Task<DynamicImageResponse> GetImage(BaseItem item, ImageType type, CancellationToken cancellationToken)
{
var audio = (Audio)item;
var imageStreams =
audio.GetMediaStreams(MediaStreamType.EmbeddedImage)
.Where(i => i.Type == MediaStreamType.EmbeddedImage)
.ToList();
// Can't extract if we didn't find a video stream in the file
if (imageStreams.Count == 0)
{
return Task.FromResult(new DynamicImageResponse { HasImage = false });
}
return GetImage((Audio)item, imageStreams, cancellationToken);
}
public async Task<DynamicImageResponse> GetImage(Audio item, List<MediaStream> imageStreams, CancellationToken cancellationToken)
{
var path = GetAudioImagePath(item);
if (!_fileSystem.FileExists(path))
{
_fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(path));
var imageStream = imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("front", StringComparison.OrdinalIgnoreCase) != -1) ??
imageStreams.FirstOrDefault(i => (i.Comment ?? string.Empty).IndexOf("cover", StringComparison.OrdinalIgnoreCase) != -1) ??
imageStreams.FirstOrDefault();
var imageStreamIndex = imageStream == null ? (int?)null : imageStream.Index;
var tempFile = await _mediaEncoder.ExtractAudioImage(item.Path, imageStreamIndex, cancellationToken).ConfigureAwait(false);
_fileSystem.CopyFile(tempFile, path, true);
try
{
_fileSystem.DeleteFile(tempFile);
}
catch
{
}
}
return new DynamicImageResponse
{
HasImage = true,
Path = path
};
}
private string GetAudioImagePath(Audio item)
{
string filename = null;
if (item.GetType() == typeof(Audio))
{
var albumArtist = item.AlbumArtists.FirstOrDefault();
if (!string.IsNullOrWhiteSpace(item.Album) && !string.IsNullOrWhiteSpace(albumArtist))
{
filename = (item.Album + "-" + albumArtist).GetMD5().ToString("N");
}
else
{
filename = item.Id.ToString("N");
}
filename += ".jpg";
}
else
{
// If it's an audio book or audio podcast, allow unique image per item
filename = item.Id.ToString("N") + ".jpg";
}
var prefix = filename.Substring(0, 1);
return Path.Combine(AudioImagesPath, prefix, filename);
}
public string AudioImagesPath => Path.Combine(_config.ApplicationPaths.CachePath, "extracted-audio-images");
public string Name => "Image Extractor";
public bool Supports(BaseItem item)
{
if (item.IsShortcut)
{
return false;
}
if (!item.IsFileProtocol)
{
return false;
}
var audio = item as Audio;
return audio != null;
}
}
}
|