Merge branch 'master' of https://github.com/MediaBrowser/MediaBrowser
This commit is contained in:
commit
2a9e59e623
|
@ -93,7 +93,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
await Fetch(myItem, cancellationToken, result, isoMount).ConfigureAwait(false);
|
Fetch(myItem, cancellationToken, result, isoMount);
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
@ -180,7 +180,7 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
/// <param name="result">The result.</param>
|
/// <param name="result">The result.</param>
|
||||||
/// <param name="isoMount">The iso mount.</param>
|
/// <param name="isoMount">The iso mount.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
protected abstract Task Fetch(T item, CancellationToken cancellationToken, FFProbeResult result, IIsoMount isoMount);
|
protected abstract void Fetch(T item, CancellationToken cancellationToken, FFProbeResult result, IIsoMount isoMount);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Converts ffprobe stream info to our MediaStream class
|
/// Converts ffprobe stream info to our MediaStream class
|
||||||
|
|
|
@ -57,12 +57,6 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
|
|
||||||
if (video != null)
|
if (video != null)
|
||||||
{
|
{
|
||||||
// Can't extract images if there are no video streams
|
|
||||||
if (video.MediaStreams == null || video.MediaStreams.All(m => m.Type != MediaStreamType.Video))
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (video.VideoType == VideoType.Iso && video.IsoType.HasValue && _isoManager.CanMount(item.Path))
|
if (video.VideoType == VideoType.Iso && video.IsoType.HasValue && _isoManager.CanMount(item.Path))
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -93,17 +87,21 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
{
|
{
|
||||||
var video = (Video)item;
|
var video = (Video)item;
|
||||||
|
|
||||||
var filename = item.Id + "_" + item.DateModified.Ticks + "_primary";
|
// We can only extract images from videos if we know there's an embedded video stream
|
||||||
|
if (video.MediaStreams != null && video.MediaStreams.Any(m => m.Type == MediaStreamType.Video))
|
||||||
var path = Kernel.Instance.FFMpegManager.VideoImageCache.GetResourcePath(filename, ".jpg");
|
|
||||||
|
|
||||||
if (!Kernel.Instance.FFMpegManager.VideoImageCache.ContainsFilePath(path))
|
|
||||||
{
|
{
|
||||||
return ExtractImage(video, path, cancellationToken);
|
var filename = item.Id + "_" + item.DateModified.Ticks + "_primary";
|
||||||
}
|
|
||||||
|
|
||||||
// Image is already in the cache
|
var path = Kernel.Instance.FFMpegManager.VideoImageCache.GetResourcePath(filename, ".jpg");
|
||||||
item.PrimaryImagePath = path;
|
|
||||||
|
if (!Kernel.Instance.FFMpegManager.VideoImageCache.ContainsFilePath(path))
|
||||||
|
{
|
||||||
|
return ExtractImage(video, path, cancellationToken);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Image is already in the cache
|
||||||
|
item.PrimaryImagePath = path;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SetLastRefreshed(item, DateTime.UtcNow);
|
SetLastRefreshed(item, DateTime.UtcNow);
|
||||||
|
|
|
@ -42,41 +42,38 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
/// <param name="data">The data.</param>
|
/// <param name="data">The data.</param>
|
||||||
/// <param name="isoMount">The iso mount.</param>
|
/// <param name="isoMount">The iso mount.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
protected override Task Fetch(Audio audio, CancellationToken cancellationToken, FFProbeResult data, IIsoMount isoMount)
|
protected override void Fetch(Audio audio, CancellationToken cancellationToken, FFProbeResult data, IIsoMount isoMount)
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
if (data.streams == null)
|
||||||
{
|
{
|
||||||
if (data.streams == null)
|
Logger.Error("Audio item has no streams: " + audio.Path);
|
||||||
{
|
return;
|
||||||
Logger.Error("Audio item has no streams: " + audio.Path);
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
audio.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format)).ToList();
|
audio.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format)).ToList();
|
||||||
|
|
||||||
// Get the first audio stream
|
// Get the first audio stream
|
||||||
var stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
|
var stream = data.streams.First(s => s.codec_type.Equals("audio", StringComparison.OrdinalIgnoreCase));
|
||||||
|
|
||||||
// Get duration from stream properties
|
// Get duration from stream properties
|
||||||
var duration = stream.duration;
|
var duration = stream.duration;
|
||||||
|
|
||||||
// If it's not there go into format properties
|
// If it's not there go into format properties
|
||||||
if (string.IsNullOrEmpty(duration))
|
if (string.IsNullOrEmpty(duration))
|
||||||
{
|
{
|
||||||
duration = data.format.duration;
|
duration = data.format.duration;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we got something, parse it
|
// If we got something, parse it
|
||||||
if (!string.IsNullOrEmpty(duration))
|
if (!string.IsNullOrEmpty(duration))
|
||||||
{
|
{
|
||||||
audio.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(duration, UsCulture)).Ticks;
|
audio.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(duration, UsCulture)).Ticks;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.format.tags != null)
|
if (data.format.tags != null)
|
||||||
{
|
{
|
||||||
FetchDataFromTags(audio, data.format.tags);
|
FetchDataFromTags(audio, data.format.tags);
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -187,44 +187,41 @@ namespace MediaBrowser.Controller.Providers.MediaInfo
|
||||||
/// <param name="data">The data.</param>
|
/// <param name="data">The data.</param>
|
||||||
/// <param name="isoMount">The iso mount.</param>
|
/// <param name="isoMount">The iso mount.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
protected override Task Fetch(Video video, CancellationToken cancellationToken, FFProbeResult data, IIsoMount isoMount)
|
protected override void Fetch(Video video, CancellationToken cancellationToken, FFProbeResult data, IIsoMount isoMount)
|
||||||
{
|
{
|
||||||
return Task.Run(() =>
|
if (data.format != null)
|
||||||
{
|
{
|
||||||
if (data.format != null)
|
// For dvd's this may not always be accurate, so don't set the runtime if the item already has one
|
||||||
|
var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;
|
||||||
|
|
||||||
|
if (needToSetRuntime && !string.IsNullOrEmpty(data.format.duration))
|
||||||
{
|
{
|
||||||
// For dvd's this may not always be accurate, so don't set the runtime if the item already has one
|
video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, UsCulture)).Ticks;
|
||||||
var needToSetRuntime = video.VideoType != VideoType.Dvd || video.RunTimeTicks == null || video.RunTimeTicks.Value == 0;
|
|
||||||
|
|
||||||
if (needToSetRuntime && !string.IsNullOrEmpty(data.format.duration))
|
|
||||||
{
|
|
||||||
video.RunTimeTicks = TimeSpan.FromSeconds(double.Parse(data.format.duration, UsCulture)).Ticks;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (data.streams != null)
|
if (data.streams != null)
|
||||||
{
|
{
|
||||||
video.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format)).ToList();
|
video.MediaStreams = data.streams.Select(s => GetMediaStream(s, data.format)).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.Chapters != null)
|
if (data.Chapters != null)
|
||||||
{
|
{
|
||||||
video.Chapters = data.Chapters;
|
video.Chapters = data.Chapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (video.Chapters == null || video.Chapters.Count == 0)
|
if (video.Chapters == null || video.Chapters.Count == 0)
|
||||||
{
|
{
|
||||||
AddDummyChapters(video);
|
AddDummyChapters(video);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
|
if (video.VideoType == VideoType.BluRay || (video.IsoType.HasValue && video.IsoType.Value == IsoType.BluRay))
|
||||||
{
|
{
|
||||||
var inputPath = isoMount != null ? isoMount.MountedPath : video.Path;
|
var inputPath = isoMount != null ? isoMount.MountedPath : video.Path;
|
||||||
FetchBdInfo(video, inputPath, BdInfoCache, cancellationToken);
|
FetchBdInfo(video, inputPath, BdInfoCache, cancellationToken);
|
||||||
}
|
}
|
||||||
|
|
||||||
AddExternalSubtitles(video);
|
AddExternalSubtitles(video);
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -104,7 +104,7 @@ namespace MediaBrowser.Server.Implementations.Providers
|
||||||
/// <param name="providers">The providers.</param>
|
/// <param name="providers">The providers.</param>
|
||||||
public void AddMetadataProviders(IEnumerable<BaseMetadataProvider> providers)
|
public void AddMetadataProviders(IEnumerable<BaseMetadataProvider> providers)
|
||||||
{
|
{
|
||||||
MetadataProviders = providers.ToArray();
|
MetadataProviders = providers.OrderBy(e => e.Priority).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -30,7 +30,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The flush interval
|
/// The flush interval
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private const int FlushInterval = 5000;
|
private const int FlushInterval = 2000;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The flush timer
|
/// The flush timer
|
||||||
|
|
|
@ -34,6 +34,18 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether [enable delayed commands].
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
||||||
|
protected override bool EnableDelayedCommands
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The _protobuf serializer
|
/// The _protobuf serializer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -106,7 +118,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// or
|
/// or
|
||||||
/// userDataId
|
/// userDataId
|
||||||
/// </exception>
|
/// </exception>
|
||||||
public Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData, CancellationToken cancellationToken)
|
public async Task SaveUserData(Guid userId, Guid userDataId, UserItemData userData, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (userData == null)
|
if (userData == null)
|
||||||
{
|
{
|
||||||
|
@ -127,19 +139,36 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
return Task.Run(() =>
|
var serialized = _protobufSerializer.SerializeToBytes(userData);
|
||||||
|
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = "replace into userdata (id, userId, data) values (@1, @2, @3)";
|
||||||
|
cmd.AddParam("@1", userDataId);
|
||||||
|
cmd.AddParam("@2", userId);
|
||||||
|
cmd.AddParam("@3", serialized);
|
||||||
|
|
||||||
|
using (var tran = connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
var serialized = _protobufSerializer.SerializeToBytes(userData);
|
try
|
||||||
|
{
|
||||||
|
cmd.Transaction = tran;
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
await cmd.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
|
||||||
var cmd = connection.CreateCommand();
|
tran.Commit();
|
||||||
cmd.CommandText = "replace into userdata (id, userId, data) values (@1, @2, @3)";
|
}
|
||||||
cmd.AddParam("@1", userDataId);
|
catch (OperationCanceledException)
|
||||||
cmd.AddParam("@2", userId);
|
{
|
||||||
cmd.AddParam("@3", serialized);
|
tran.Rollback();
|
||||||
QueueCommand(cmd);
|
}
|
||||||
});
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
Logger.ErrorException("Failed to commit transaction.", e);
|
||||||
|
tran.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -45,6 +45,18 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private readonly IApplicationPaths _appPaths;
|
private readonly IApplicationPaths _appPaths;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a value indicating whether [enable delayed commands].
|
||||||
|
/// </summary>
|
||||||
|
/// <value><c>true</c> if [enable delayed commands]; otherwise, <c>false</c>.</value>
|
||||||
|
protected override bool EnableDelayedCommands
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
/// Initializes a new instance of the <see cref="SQLiteUserDataRepository" /> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -97,7 +109,7 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
/// <param name="cancellationToken">The cancellation token.</param>
|
/// <param name="cancellationToken">The cancellation token.</param>
|
||||||
/// <returns>Task.</returns>
|
/// <returns>Task.</returns>
|
||||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||||
public Task SaveUser(User user, CancellationToken cancellationToken)
|
public async Task SaveUser(User user, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
if (user == null)
|
if (user == null)
|
||||||
{
|
{
|
||||||
|
@ -109,20 +121,37 @@ namespace MediaBrowser.Server.Implementations.Sqlite
|
||||||
throw new ArgumentNullException("cancellationToken");
|
throw new ArgumentNullException("cancellationToken");
|
||||||
}
|
}
|
||||||
|
|
||||||
return Task.Run(() =>
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var serialized = _jsonSerializer.SerializeToBytes(user);
|
||||||
|
|
||||||
|
cancellationToken.ThrowIfCancellationRequested();
|
||||||
|
|
||||||
|
var cmd = connection.CreateCommand();
|
||||||
|
cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
|
||||||
|
cmd.AddParam("@1", user.Id);
|
||||||
|
cmd.AddParam("@2", serialized);
|
||||||
|
|
||||||
|
using (var tran = connection.BeginTransaction())
|
||||||
{
|
{
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
try
|
||||||
|
{
|
||||||
|
cmd.Transaction = tran;
|
||||||
|
|
||||||
var serialized = _jsonSerializer.SerializeToBytes(user);
|
await cmd.ExecuteNonQueryAsync(cancellationToken);
|
||||||
|
|
||||||
cancellationToken.ThrowIfCancellationRequested();
|
tran.Commit();
|
||||||
|
}
|
||||||
var cmd = connection.CreateCommand();
|
catch (OperationCanceledException)
|
||||||
cmd.CommandText = "replace into users (guid, data) values (@1, @2)";
|
{
|
||||||
cmd.AddParam("@1", user.Id);
|
tran.Rollback();
|
||||||
cmd.AddParam("@2", serialized);
|
}
|
||||||
QueueCommand(cmd);
|
catch (Exception e)
|
||||||
});
|
{
|
||||||
|
Logger.ErrorException("Failed to commit transaction.", e);
|
||||||
|
tran.Rollback();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -298,7 +298,7 @@ namespace MediaBrowser.ServerApplication
|
||||||
|
|
||||||
() => LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>(), GetExports<IBaseItemComparer>()),
|
() => LibraryManager.AddParts(GetExports<IResolverIgnoreRule>(), GetExports<IVirtualFolderCreator>(), GetExports<IItemResolver>(), GetExports<IIntroProvider>(), GetExports<IBaseItemComparer>()),
|
||||||
|
|
||||||
() => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().OrderBy(e => e.Priority).ToArray())
|
() => ProviderManager.AddMetadataProviders(GetExports<BaseMetadataProvider>().ToArray())
|
||||||
);
|
);
|
||||||
|
|
||||||
UdpServer = new UdpServer(Logger, NetworkManager, ServerConfigurationManager);
|
UdpServer = new UdpServer(Logger, NetworkManager, ServerConfigurationManager);
|
||||||
|
|
Loading…
Reference in New Issue
Block a user