Fix build and address comments

pull/1838/head
Bond_009 5 years ago committed by dkanada
parent aca31457c0
commit a253fa616d

@ -878,7 +878,7 @@ namespace Emby.Server.Implementations
serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager)); serviceCollection.AddSingleton(typeof(IResourceFileManager), typeof(ResourceFileManager));
serviceCollection.AddSingleton<EncodingHelper>(); serviceCollection.AddSingleton<EncodingHelper>();
serviceCollection.AddSingleton(typeof(MediaBrowser.Controller.MediaEncoding.IAttachmentExtractor),typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor)); serviceCollection.AddSingleton(typeof(IAttachmentExtractor), typeof(MediaBrowser.MediaEncoding.Attachments.AttachmentExtractor));
_displayPreferencesRepository.Initialize(); _displayPreferencesRepository.Initialize();

@ -55,8 +55,8 @@ namespace Emby.Server.Implementations.Data
queryPrefixText.Append("insert into mediaattachments ("); queryPrefixText.Append("insert into mediaattachments (");
foreach (var column in _mediaAttachmentSaveColumns) foreach (var column in _mediaAttachmentSaveColumns)
{ {
queryPrefixText.Append(column); queryPrefixText.Append(column)
queryPrefixText.Append(','); .Append(',');
} }
queryPrefixText.Length -= 1; queryPrefixText.Length -= 1;
@ -449,6 +449,7 @@ namespace Emby.Server.Implementations.Data
"Filename", "Filename",
"MIMEType" "MIMEType"
}; };
private static readonly string _mediaAttachmentInsertPrefix; private static readonly string _mediaAttachmentInsertPrefix;
private static string GetSaveItemCommandText() private static string GetSaveItemCommandText()
@ -6208,7 +6209,10 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
return list; return list;
} }
public void SaveMediaAttachments(Guid id, List<MediaAttachment> attachments, CancellationToken cancellationToken) public void SaveMediaAttachments(
Guid id,
List<MediaAttachment> attachments,
CancellationToken cancellationToken)
{ {
CheckDisposed(); CheckDisposed();
if (id == Guid.Empty) if (id == Guid.Empty)
@ -6237,24 +6241,22 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
} }
} }
private void InsertMediaAttachments(byte[] idBlob, List<MediaAttachment> attachments, IDatabaseConnection db, CancellationToken cancellationToken) private void InsertMediaAttachments(
byte[] idBlob,
List<MediaAttachment> attachments,
IDatabaseConnection db,
CancellationToken cancellationToken)
{ {
var startIndex = 0; const int InsertAtOnce = 10;
var insertAtOnce = 10;
while (startIndex < attachments.Count) for (var startIndex = 0; startIndex < attachments.Count; startIndex += InsertAtOnce)
{ {
var insertText = new StringBuilder(_mediaAttachmentInsertPrefix); var insertText = new StringBuilder(_mediaAttachmentInsertPrefix);
var endIndex = Math.Min(attachments.Count, startIndex + insertAtOnce); var endIndex = Math.Min(attachments.Count, startIndex + InsertAtOnce);
for (var i = startIndex; i < endIndex; i++) for (var i = startIndex; i < endIndex; i++)
{ {
if (i != startIndex)
{
insertText.Append(',');
}
var index = i.ToString(CultureInfo.InvariantCulture); var index = i.ToString(CultureInfo.InvariantCulture);
insertText.Append("(@ItemId, "); insertText.Append("(@ItemId, ");
@ -6265,9 +6267,11 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
insertText.Length -= 1; insertText.Length -= 1;
insertText.Append(")"); insertText.Append("),");
} }
insertText.Length--;
cancellationToken.ThrowIfCancellationRequested(); cancellationToken.ThrowIfCancellationRequested();
using (var statement = PrepareStatement(db, insertText.ToString())) using (var statement = PrepareStatement(db, insertText.ToString()))
@ -6291,8 +6295,6 @@ where AncestorIdText not null and ItemValues.Value not null and ItemValues.Type
statement.Reset(); statement.Reset();
statement.MoveNext(); statement.MoveNext();
} }
startIndex += insertAtOnce;
} }
} }

@ -136,15 +136,6 @@ namespace Emby.Server.Implementations.Library
return _itemRepo.GetMediaAttachments(query); return _itemRepo.GetMediaAttachments(query);
} }
/// <inheritdoc />
public List<MediaAttachment> GetMediaAttachments(string mediaSourceId)
{
return GetMediaAttachments(new MediaAttachmentQuery
{
ItemId = new Guid(mediaSourceId)
});
}
/// <inheritdoc /> /// <inheritdoc />
public List<MediaAttachment> GetMediaAttachments(Guid itemId) public List<MediaAttachment> GetMediaAttachments(Guid itemId)
{ {

@ -96,7 +96,6 @@ namespace Jellyfin.Api.Controllers
public StartupUserDto GetFirstUser() public StartupUserDto GetFirstUser()
{ {
var user = _userManager.Users.First(); var user = _userManager.Users.First();
return new StartupUserDto return new StartupUserDto
{ {
Name = user.Name, Name = user.Name,

@ -1,22 +1,14 @@
using System; using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO; using System.IO;
using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net; using MediaBrowser.Controller.Net;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Providers;
using MediaBrowser.Model.Services; using MediaBrowser.Model.Services;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using MimeTypes = MediaBrowser.Model.Net.MimeTypes;
namespace MediaBrowser.Api.Attachments namespace MediaBrowser.Api.Attachments
{ {
@ -38,7 +30,13 @@ namespace MediaBrowser.Api.Attachments
private readonly ILibraryManager _libraryManager; private readonly ILibraryManager _libraryManager;
private readonly IAttachmentExtractor _attachmentExtractor; private readonly IAttachmentExtractor _attachmentExtractor;
public AttachmentService(ILibraryManager libraryManager, IAttachmentExtractor attachmentExtractor) public AttachmentService(
ILogger<AttachmentService> logger,
IServerConfigurationManager serverConfigurationManager,
IHttpResultFactory httpResultFactory,
ILibraryManager libraryManager,
IAttachmentExtractor attachmentExtractor)
: base(logger, serverConfigurationManager, httpResultFactory)
{ {
_libraryManager = libraryManager; _libraryManager = libraryManager;
_attachmentExtractor = attachmentExtractor; _attachmentExtractor = attachmentExtractor;
@ -46,7 +44,6 @@ namespace MediaBrowser.Api.Attachments
public async Task<object> Get(GetAttachment request) public async Task<object> Get(GetAttachment request)
{ {
var item = (Video)_libraryManager.GetItemById(request.Id);
var (attachment, attachmentStream) = await GetAttachment(request).ConfigureAwait(false); var (attachment, attachmentStream) = await GetAttachment(request).ConfigureAwait(false);
var mime = string.IsNullOrWhiteSpace(attachment.MIMEType) ? "application/octet-stream" : attachment.MIMEType; var mime = string.IsNullOrWhiteSpace(attachment.MIMEType) ? "application/octet-stream" : attachment.MIMEType;

@ -41,21 +41,14 @@ namespace MediaBrowser.Controller.Library
/// <summary> /// <summary>
/// Gets the media attachments. /// Gets the media attachments.
/// </summary> /// </summary>
/// <param name="">The item identifier.</param> /// <param name="itemId">The item identifier.</param>
/// <returns>IEnumerable&lt;MediaAttachment&gt;.</returns> /// <returns>IEnumerable&lt;MediaAttachment&gt;.</returns>
List<MediaAttachment> GetMediaAttachments(Guid itemId); List<MediaAttachment> GetMediaAttachments(Guid itemId);
/// <summary> /// <summary>
/// Gets the media attachments. /// Gets the media attachments.
/// </summary> /// </summary>
/// <param name="">The The media source identifier.</param> /// <param name="query">The query.</param>
/// <returns>IEnumerable&lt;MediaAttachment&gt;.</returns>
List<MediaAttachment> GetMediaAttachments(string mediaSourceId);
/// <summary>
/// Gets the media attachments.
/// </summary>
/// <param name="">The query.</param>
/// <returns>IEnumerable&lt;MediaAttachment&gt;.</returns> /// <returns>IEnumerable&lt;MediaAttachment&gt;.</returns>
List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query); List<MediaAttachment> GetMediaAttachments(MediaAttachmentQuery query);

@ -2,14 +2,14 @@ using System.IO;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
namespace MediaBrowser.Controller.MediaEncoding namespace MediaBrowser.Controller.MediaEncoding
{ {
public interface IAttachmentExtractor public interface IAttachmentExtractor
{ {
Task<(MediaAttachment attachment, Stream stream)> GetAttachment(BaseItem item, Task<(MediaAttachment attachment, Stream stream)> GetAttachment(
BaseItem item,
string mediaSourceId, string mediaSourceId,
int attachmentStreamIndex, int attachmentStreamIndex,
CancellationToken cancellationToken); CancellationToken cancellationToken);

@ -4,44 +4,41 @@ using System.Collections.Concurrent;
using System.Globalization; using System.Globalization;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using MediaBrowser.Common.Configuration; using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding; using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Diagnostics;
using MediaBrowser.Model.Dto; using MediaBrowser.Model.Dto;
using MediaBrowser.Model.Entities; using MediaBrowser.Model.Entities;
using MediaBrowser.Model.IO; using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using MediaBrowser.Model.Serialization;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
using UtfUnknown;
namespace MediaBrowser.MediaEncoding.Attachments namespace MediaBrowser.MediaEncoding.Attachments
{ {
public class AttachmentExtractor : IAttachmentExtractor public class AttachmentExtractor : IAttachmentExtractor, IDisposable
{ {
private readonly ILibraryManager _libraryManager;
private readonly ILogger _logger; private readonly ILogger _logger;
private readonly IApplicationPaths _appPaths; private readonly IApplicationPaths _appPaths;
private readonly IFileSystem _fileSystem; private readonly IFileSystem _fileSystem;
private readonly IMediaEncoder _mediaEncoder; private readonly IMediaEncoder _mediaEncoder;
private readonly IMediaSourceManager _mediaSourceManager; private readonly IMediaSourceManager _mediaSourceManager;
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
new ConcurrentDictionary<string, SemaphoreSlim>();
private bool _disposed = false;
public AttachmentExtractor( public AttachmentExtractor(
ILibraryManager libraryManager,
ILogger<AttachmentExtractor> logger, ILogger<AttachmentExtractor> logger,
IApplicationPaths appPaths, IApplicationPaths appPaths,
IFileSystem fileSystem, IFileSystem fileSystem,
IMediaEncoder mediaEncoder, IMediaEncoder mediaEncoder,
IMediaSourceManager mediaSourceManager) IMediaSourceManager mediaSourceManager)
{ {
_libraryManager = libraryManager;
_logger = logger; _logger = logger;
_appPaths = appPaths; _appPaths = appPaths;
_fileSystem = fileSystem; _fileSystem = fileSystem;
@ -49,8 +46,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
_mediaSourceManager = mediaSourceManager; _mediaSourceManager = mediaSourceManager;
} }
private string AttachmentCachePath => Path.Combine(_appPaths.DataPath, "attachments"); /// <inheritdoc />
public async Task<(MediaAttachment attachment, Stream stream)> GetAttachment(BaseItem item, string mediaSourceId, int attachmentStreamIndex, CancellationToken cancellationToken) public async Task<(MediaAttachment attachment, Stream stream)> GetAttachment(BaseItem item, string mediaSourceId, int attachmentStreamIndex, CancellationToken cancellationToken)
{ {
if (item == null) if (item == null)
@ -70,12 +66,14 @@ namespace MediaBrowser.MediaEncoding.Attachments
{ {
throw new ResourceNotFoundException($"MediaSource {mediaSourceId} not found"); throw new ResourceNotFoundException($"MediaSource {mediaSourceId} not found");
} }
var mediaAttachment = mediaSource.MediaAttachments var mediaAttachment = mediaSource.MediaAttachments
.FirstOrDefault(i => i.Index == attachmentStreamIndex); .FirstOrDefault(i => i.Index == attachmentStreamIndex);
if (mediaAttachment == null) if (mediaAttachment == null)
{ {
throw new ResourceNotFoundException($"MediaSource {mediaSourceId} has no attachment with stream index {attachmentStreamIndex}"); throw new ResourceNotFoundException($"MediaSource {mediaSourceId} has no attachment with stream index {attachmentStreamIndex}");
} }
var attachmentStream = await GetAttachmentStream(mediaSource, mediaAttachment, cancellationToken) var attachmentStream = await GetAttachmentStream(mediaSource, mediaAttachment, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -87,49 +85,32 @@ namespace MediaBrowser.MediaEncoding.Attachments
MediaAttachment mediaAttachment, MediaAttachment mediaAttachment,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var inputFiles = new[] { mediaSource.Path }; var attachmentPath = await GetReadableFile(mediaSource.Path, mediaSource.Path, mediaSource.Protocol, mediaAttachment, cancellationToken).ConfigureAwait(false);
var attachmentPath = await GetReadableFile(mediaSource.Path, inputFiles, mediaSource.Protocol, mediaAttachment, cancellationToken).ConfigureAwait(false); return File.OpenRead(attachmentPath);
var stream = await GetAttachmentStream(attachmentPath, cancellationToken).ConfigureAwait(false);
return stream;
} }
private async Task<Stream> GetAttachmentStream( private async Task<string> GetReadableFile(
string path,
CancellationToken cancellationToken)
{
return File.OpenRead(path);
}
private async Task<String> GetReadableFile(
string mediaPath, string mediaPath,
string[] inputFiles, string inputFile,
MediaProtocol protocol, MediaProtocol protocol,
MediaAttachment mediaAttachment, MediaAttachment mediaAttachment,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var outputPath = GetAttachmentCachePath(mediaPath, protocol, mediaAttachment.Index); var outputPath = GetAttachmentCachePath(mediaPath, protocol, mediaAttachment.Index);
await ExtractAttachment(inputFiles, protocol, mediaAttachment.Index, outputPath, cancellationToken) await ExtractAttachment(inputFile, protocol, mediaAttachment.Index, outputPath, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
return outputPath; return outputPath;
} }
private readonly ConcurrentDictionary<string, SemaphoreSlim> _semaphoreLocks =
new ConcurrentDictionary<string, SemaphoreSlim>();
private SemaphoreSlim GetLock(string filename)
{
return _semaphoreLocks.GetOrAdd(filename, key => new SemaphoreSlim(1, 1));
}
private async Task ExtractAttachment( private async Task ExtractAttachment(
string[] inputFiles, string inputFile,
MediaProtocol protocol, MediaProtocol protocol,
int attachmentStreamIndex, int attachmentStreamIndex,
string outputPath, string outputPath,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
var semaphore = GetLock(outputPath); var semaphore = _semaphoreLocks.GetOrAdd(outputPath, key => new SemaphoreSlim(1, 1));
await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false); await semaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
@ -137,7 +118,11 @@ namespace MediaBrowser.MediaEncoding.Attachments
{ {
if (!File.Exists(outputPath)) if (!File.Exists(outputPath))
{ {
await ExtractAttachmentInternal(_mediaEncoder.GetInputArgument(inputFiles, protocol), attachmentStreamIndex, outputPath, cancellationToken).ConfigureAwait(false); await ExtractAttachmentInternal(
_mediaEncoder.GetInputArgument(new[] { inputFile }, protocol),
attachmentStreamIndex,
outputPath,
cancellationToken).ConfigureAwait(false);
} }
} }
finally finally
@ -186,16 +171,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
_logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments); _logger.LogInformation("{File} {Arguments}", process.StartInfo.FileName, process.StartInfo.Arguments);
try process.Start();
{
process.Start();
}
catch (Exception ex)
{
_logger.LogError(ex, "Error starting ffmpeg");
throw;
}
var processTcs = new TaskCompletionSource<bool>(); var processTcs = new TaskCompletionSource<bool>();
process.EnableRaisingEvents = true; process.EnableRaisingEvents = true;
@ -216,6 +192,7 @@ namespace MediaBrowser.MediaEncoding.Attachments
_logger.LogError(ex, "Error killing attachment extraction process"); _logger.LogError(ex, "Error killing attachment extraction process");
} }
} }
var exitCode = ranToCompletion ? process.ExitCode : -1; var exitCode = ranToCompletion ? process.ExitCode : -1;
process.Dispose(); process.Dispose();
@ -270,9 +247,35 @@ namespace MediaBrowser.MediaEncoding.Attachments
{ {
filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D"); filename = (mediaPath + attachmentStreamIndex.ToString(CultureInfo.InvariantCulture)).GetMD5().ToString("D");
} }
var prefix = filename.Substring(0, 1); var prefix = filename.Substring(0, 1);
return Path.Combine(AttachmentCachePath, prefix, filename); return Path.Combine(_appPaths.DataPath, "attachments", prefix, filename);
}
/// <inheritdoc />
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
} }
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (_disposed)
{
return;
}
if (disposing)
{
}
_disposed = true;
}
} }
} }

@ -43,7 +43,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
/// </summary> /// </summary>
/// <param name="path">The path.</param> /// <param name="path">The path.</param>
/// <returns>System.String.</returns> /// <returns>System.String.</returns>
private static string GetFileInputArgument(string path) public static string GetFileInputArgument(string path)
{ {
if (path.IndexOf("://") != -1) if (path.IndexOf("://") != -1)
{ {

Loading…
Cancel
Save