diff --git a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
index c7378956d..f47e2d10a 100644
--- a/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
+++ b/Emby.Server.Implementations/Collections/CollectionImageProvider.cs
@@ -57,7 +57,7 @@ namespace Emby.Server.Implementations.Collections
return subItem;
}
- var parent = subItem.GetParent();
+ var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent();
if (parent != null && parent.HasImage(ImageType.Primary))
{
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 6811e42ec..2186982d3 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
@@ -253,6 +253,7 @@ namespace Emby.Server.Implementations.Data
AddColumn(db, "TypedBaseItems", "ExternalId", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "SeriesPresentationUniqueKey", "Text", existingColumnNames);
AddColumn(db, "TypedBaseItems", "ShowId", "Text", existingColumnNames);
+ AddColumn(db, "TypedBaseItems", "OwnerId", "Text", existingColumnNames);
existingColumnNames = GetColumnNames(db, "ItemValues");
AddColumn(db, "ItemValues", "CleanValue", "Text", existingColumnNames);
@@ -459,7 +460,8 @@ namespace Emby.Server.Implementations.Data
"AlbumArtists",
"ExternalId",
"SeriesPresentationUniqueKey",
- "ShowId"
+ "ShowId",
+ "OwnerId"
};
private readonly string[] _mediaStreamSaveColumns =
@@ -580,7 +582,8 @@ namespace Emby.Server.Implementations.Data
"AlbumArtists",
"ExternalId",
"SeriesPresentationUniqueKey",
- "ShowId"
+ "ShowId",
+ "OwnerId"
};
var saveItemCommandCommandText = "replace into TypedBaseItems (" + string.Join(",", saveColumns.ToArray()) + ") values (";
@@ -784,13 +787,14 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBind("@PremiereDate", item.PremiereDate);
saveItemStatement.TryBind("@ProductionYear", item.ProductionYear);
- if (item.ParentId == Guid.Empty)
+ var parentId = item.ParentId;
+ if (parentId == Guid.Empty)
{
saveItemStatement.TryBindNull("@ParentId");
}
else
{
- saveItemStatement.TryBind("@ParentId", item.ParentId);
+ saveItemStatement.TryBind("@ParentId", parentId);
}
if (item.Genres.Count > 0)
@@ -1057,6 +1061,16 @@ namespace Emby.Server.Implementations.Data
saveItemStatement.TryBindNull("@ShowId");
}
+ var ownerId = item.OwnerId;
+ if (ownerId != Guid.Empty)
+ {
+ saveItemStatement.TryBind("@OwnerId", ownerId);
+ }
+ else
+ {
+ saveItemStatement.TryBindNull("@OwnerId");
+ }
+
saveItemStatement.MoveNext();
}
@@ -1156,16 +1170,14 @@ namespace Emby.Server.Implementations.Data
delimeter +
image.DateModified.Ticks.ToString(CultureInfo.InvariantCulture) +
delimeter +
- image.Type +
- delimeter +
- image.IsPlaceholder;
+ image.Type;
}
public ItemImageInfo ItemImageInfoFromValueString(string value)
{
var parts = value.Split(new[] { '*' }, StringSplitOptions.None);
- if (parts.Length != 4)
+ if (parts.Length < 3)
{
return null;
}
@@ -1173,9 +1185,18 @@ namespace Emby.Server.Implementations.Data
var image = new ItemImageInfo();
image.Path = parts[0];
- image.DateModified = new DateTime(long.Parse(parts[1], CultureInfo.InvariantCulture), DateTimeKind.Utc);
- image.Type = (ImageType)Enum.Parse(typeof(ImageType), parts[2], true);
- image.IsPlaceholder = string.Equals(parts[3], true.ToString(), StringComparison.OrdinalIgnoreCase);
+
+ long ticks;
+ if (long.TryParse(parts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out ticks))
+ {
+ image.DateModified = new DateTime(ticks, DateTimeKind.Utc);
+ }
+
+ ImageType type;
+ if (Enum.TryParse(parts[2], true, out type))
+ {
+ image.Type = type;
+ }
return image;
}
@@ -1965,6 +1986,12 @@ namespace Emby.Server.Implementations.Data
}
}
+ if (!reader.IsDBNull(index))
+ {
+ item.OwnerId = reader.GetGuid(index);
+ }
+ index++;
+
return item;
}
@@ -4467,7 +4494,6 @@ namespace Emby.Server.Implementations.Data
}
}
-
var includedItemByNameTypes = GetItemByNameTypesInQuery(query).SelectMany(MapIncludeItemTypes).ToList();
var enableItemsByName = (query.IncludeItemsByName ?? false) && includedItemByNameTypes.Count > 0;
diff --git a/Emby.Server.Implementations/Dto/DtoService.cs b/Emby.Server.Implementations/Dto/DtoService.cs
index b57662e31..1854829a2 100644
--- a/Emby.Server.Implementations/Dto/DtoService.cs
+++ b/Emby.Server.Implementations/Dto/DtoService.cs
@@ -1487,7 +1487,7 @@ namespace Emby.Server.Implementations.Dto
}
}
- var parent = currentItem.DisplayParent ?? currentItem.GetParent();
+ var parent = currentItem.DisplayParent ?? (currentItem.IsOwnedItem ? currentItem.GetOwner() : currentItem.GetParent());
if (parent == null && !(originalItem is UserRootFolder) && !(originalItem is UserView) && !(originalItem is AggregateFolder) && !(originalItem is ICollectionFolder) && !(originalItem is Channel))
{
diff --git a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
index 796d8cf48..299da0744 100644
--- a/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/LibraryChangedNotifier.cs
@@ -198,9 +198,10 @@ namespace Emby.Server.Implementations.EntryPoints
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
}
- if (e.Item.Parent != null)
+ var parent = e.Item.GetParent() as Folder;
+ if (parent != null)
{
- _foldersAddedTo.Add(e.Item.Parent);
+ _foldersAddedTo.Add(parent);
}
_itemsAdded.Add(e.Item);
@@ -259,9 +260,10 @@ namespace Emby.Server.Implementations.EntryPoints
LibraryUpdateTimer.Change(LibraryUpdateDuration, Timeout.Infinite);
}
- if (e.Item.Parent != null)
+ var parent = e.Item.GetParent() as Folder;
+ if (parent != null)
{
- _foldersRemovedFrom.Add(e.Item.Parent);
+ _foldersRemovedFrom.Add(parent);
}
_itemsRemoved.Add(e.Item);
diff --git a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
index 13e14be36..4c16b1d39 100644
--- a/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
+++ b/Emby.Server.Implementations/EntryPoints/RefreshUsersMetadata.cs
@@ -1,43 +1,74 @@
using System;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.Plugins;
using System.Threading;
+using MediaBrowser.Model.Tasks;
+using System.Collections.Generic;
+using System.Linq;
+using System.Threading.Tasks;
+using MediaBrowser.Controller.Providers;
+using MediaBrowser.Model.IO;
namespace Emby.Server.Implementations.EntryPoints
{
///
/// Class RefreshUsersMetadata
///
- public class RefreshUsersMetadata : IServerEntryPoint
+ public class RefreshUsersMetadata : IScheduledTask, IConfigurableScheduledTask
{
///
/// The _user manager
///
private readonly IUserManager _userManager;
+ private IFileSystem _fileSystem;
+
+ public string Name => "Refresh Users";
+
+ public string Key => "RefreshUsers";
+
+ public string Description => "Refresh user infos";
+
+ public string Category
+ {
+ get { return "Library"; }
+ }
+
+ public bool IsHidden => true;
+
+ public bool IsEnabled => true;
+
+ public bool IsLogged => true;
///
/// Initializes a new instance of the class.
///
- /// The user manager.
- public RefreshUsersMetadata(IUserManager userManager)
+ public RefreshUsersMetadata(IUserManager userManager, IFileSystem fileSystem)
{
_userManager = userManager;
+ _fileSystem = fileSystem;
}
- ///
- /// Runs this instance.
- ///
- public async void Run()
+ public async Task Execute(CancellationToken cancellationToken, IProgress progress)
{
- await _userManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false);
+ var users = _userManager.Users.ToList();
+
+ foreach (var user in users)
+ {
+ cancellationToken.ThrowIfCancellationRequested();
+
+ await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
+ }
}
- ///
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- ///
- public void Dispose()
+ public IEnumerable GetDefaultTriggers()
{
- GC.SuppressFinalize(this);
+ return new List
+ {
+ new TaskTriggerInfo
+ {
+ IntervalTicks = TimeSpan.FromDays(1).Ticks,
+ Type = TaskTriggerInfo.TriggerInterval
+ }
+ };
}
}
}
diff --git a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
index 4a7182a43..13c72bf3c 100644
--- a/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
+++ b/Emby.Server.Implementations/EntryPoints/UserDataChangeNotifier.cs
@@ -77,7 +77,7 @@ namespace Emby.Server.Implementations.EntryPoints
// Go up one level for indicators
if (baseItem != null)
{
- var parent = baseItem.GetParent();
+ var parent = baseItem.IsOwnedItem ? baseItem.GetOwner() : baseItem.GetParent();
if (parent != null)
{
diff --git a/Emby.Server.Implementations/IO/FileRefresher.cs b/Emby.Server.Implementations/IO/FileRefresher.cs
index 20de8a518..315bee103 100644
--- a/Emby.Server.Implementations/IO/FileRefresher.cs
+++ b/Emby.Server.Implementations/IO/FileRefresher.cs
@@ -209,7 +209,7 @@ namespace Emby.Server.Implementations.IO
// If the item has been deleted find the first valid parent that still exists
while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
{
- item = item.GetParent();
+ item = item.IsOwnedItem ? item.GetOwner() : item.GetParent();
if (item == null)
{
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 139435faa..eab52e5e8 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -386,7 +386,7 @@ namespace Emby.Server.Implementations.Library
item.Id);
}
- var parent = item.Parent;
+ var parent = item.IsOwnedItem ? item.GetOwner() : item.GetParent();
var locationType = item.LocationType;
@@ -453,12 +453,28 @@ namespace Emby.Server.Implementations.Library
if (parent != null)
{
- await parent.ValidateChildren(new SimpleProgress(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
+ var parentFolder = parent as Folder;
+ if (parentFolder != null)
+ {
+ await parentFolder.ValidateChildren(new SimpleProgress(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
+ }
+ else
+ {
+ await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
+ }
}
}
else if (parent != null)
{
- parent.RemoveChild(item);
+ var parentFolder = parent as Folder;
+ if (parentFolder != null)
+ {
+ parentFolder.RemoveChild(item);
+ }
+ else
+ {
+ await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
+ }
}
ItemRepository.DeleteItem(item.Id, CancellationToken.None);
@@ -2604,8 +2620,11 @@ namespace Emby.Server.Implementations.Library
{
video = dbItem;
}
-
- video.ExtraType = ExtraType.Trailer;
+ else
+ {
+ // item is new
+ video.ExtraType = ExtraType.Trailer;
+ }
video.TrailerTypes = new List { TrailerType.LocalTrailer };
return video;
@@ -2846,13 +2865,6 @@ namespace Emby.Server.Implementations.Library
await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
- var newImage = item.GetImageInfo(image.Type, imageIndex);
-
- if (newImage != null)
- {
- newImage.IsPlaceholder = image.IsPlaceholder;
- }
-
await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
return item.GetImageInfo(image.Type, imageIndex);
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index c9de3c01b..0f48ff46b 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -518,11 +518,12 @@ namespace Emby.Server.Implementations.Library
///
/// The cancellation token.
/// Task.
- public Task RefreshUsersMetadata(CancellationToken cancellationToken)
+ public async Task RefreshUsersMetadata(CancellationToken cancellationToken)
{
- var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken)).ToList();
-
- return Task.WhenAll(tasks);
+ foreach (var user in Users)
+ {
+ await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
+ }
}
///
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
index 2a2e1886f..f0578d9ef 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/DirectRecorder.cs
@@ -42,6 +42,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
private async Task RecordFromDirectStreamProvider(IDirectStreamProvider directStreamProvider, string targetFile, TimeSpan duration, Action onStarted, CancellationToken cancellationToken)
{
+ _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
+
using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
onStarted();
@@ -76,6 +78,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
_logger.Info("Opened recording stream from tuner provider");
+ _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(targetFile));
+
using (var output = _fileSystem.GetFileStream(targetFile, FileOpenMode.Create, FileAccessMode.Write, FileShareMode.Read))
{
onStarted();
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index bd9754f26..1975a6b01 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1429,14 +1429,13 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
string liveStreamId = null;
- OnRecordingStatusChanged();
-
try
{
var recorder = await GetRecorder().ConfigureAwait(false);
var allMediaSources = await GetChannelStreamMediaSources(timer.ChannelId, CancellationToken.None).ConfigureAwait(false);
+ _logger.Info("Opening recording stream from tuner provider");
var liveStreamInfo = await GetChannelStreamInternal(timer.ChannelId, allMediaSources[0].Id, CancellationToken.None)
.ConfigureAwait(false);
@@ -1450,23 +1449,20 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
recordPath = EnsureFileUnique(recordPath, timer.Id);
_libraryMonitor.ReportFileSystemChangeBeginning(recordPath);
- _fileSystem.CreateDirectory(_fileSystem.GetDirectoryName(recordPath));
activeRecordingInfo.Path = recordPath;
var duration = recordingEndDate - DateTime.UtcNow;
- _logger.Info("Beginning recording. Will record for {0} minutes.",
- duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
+ _logger.Info("Beginning recording. Will record for {0} minutes.", duration.TotalMinutes.ToString(CultureInfo.InvariantCulture));
_logger.Info("Writing file to path: " + recordPath);
- _logger.Info("Opening recording stream from tuner provider");
- Action onStarted = () =>
+ Action onStarted = async () =>
{
timer.Status = RecordingStatus.InProgress;
_timerProvider.AddOrUpdate(timer, false);
- SaveRecordingMetadata(timer, recordPath, seriesPath);
+ await SaveRecordingMetadata(timer, recordPath, seriesPath).ConfigureAwait(false);
TriggerRefresh(recordPath);
EnforceKeepUpTo(timer, seriesPath);
};
@@ -1500,7 +1496,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
TriggerRefresh(recordPath);
- _libraryMonitor.ReportFileSystemChangeComplete(recordPath, true);
+ _libraryMonitor.ReportFileSystemChangeComplete(recordPath, false);
ActiveRecordingInfo removed;
_activeRecordings.TryRemove(timer.Id, out removed);
@@ -1526,17 +1522,29 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
_timerProvider.Delete(timer);
}
-
- OnRecordingStatusChanged();
}
private void TriggerRefresh(string path)
{
+ _logger.Debug("Triggering refresh on {0}", path);
+
var item = GetAffectedBaseItem(_fileSystem.GetDirectoryName(path));
if (item != null)
{
- item.ChangedExternally();
+ _logger.Debug("Refreshing recording parent {0}", item.Path);
+
+ _providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem)
+ {
+ ValidateChildren = true,
+ RefreshPaths = new List
+ {
+ path,
+ _fileSystem.GetDirectoryName(path),
+ _fileSystem.GetDirectoryName(_fileSystem.GetDirectoryName(path))
+ }
+
+ }, RefreshPriority.High);
}
}
@@ -1544,6 +1552,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
{
BaseItem item = null;
+ var parentPath = _fileSystem.GetDirectoryName(path);
+
while (item == null && !string.IsNullOrEmpty(path))
{
item = _libraryManager.FindByPath(path, null);
@@ -1553,14 +1563,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
if (item != null)
{
- // If the item has been deleted find the first valid parent that still exists
- while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
+ if (item.GetType() == typeof(Folder) && string.Equals(item.Path, parentPath, StringComparison.OrdinalIgnoreCase))
{
- item = item.GetParent();
-
- if (item == null)
+ var parentItem = item.GetParent();
+ if (parentItem != null && !(parentItem is AggregateFolder))
{
- break;
+ item = parentItem;
}
}
}
@@ -1568,14 +1576,6 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
return item;
}
- private void OnRecordingStatusChanged()
- {
- EventHelper.FireEventIfNotNull(RecordingStatusChanged, this, new RecordingStatusChangedEventArgs
- {
-
- }, _logger);
- }
-
private async void EnforceKeepUpTo(TimerInfo timer, string seriesPath)
{
if (string.IsNullOrWhiteSpace(timer.SeriesTimerId))
@@ -1960,7 +1960,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
}
}
- private async void SaveRecordingMetadata(TimerInfo timer, string recordingPath, string seriesPath)
+ private async Task SaveRecordingMetadata(TimerInfo timer, string recordingPath, string seriesPath)
{
try
{
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index 870a3b493..38d2fd3c6 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -843,8 +843,7 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo
{
Path = info.ImagePath,
- Type = ImageType.Primary,
- IsPlaceholder = true
+ Type = ImageType.Primary
}, 0);
}
else if (!string.IsNullOrWhiteSpace(info.ImageUrl))
@@ -852,8 +851,7 @@ namespace Emby.Server.Implementations.LiveTv
item.SetImage(new ItemImageInfo
{
Path = info.ImageUrl,
- Type = ImageType.Primary,
- IsPlaceholder = true
+ Type = ImageType.Primary
}, 0);
}
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
index 4dcbc4b54..af064755d 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHttpStream.cs
@@ -134,7 +134,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
}
_liveStreamTaskCompletionSource.TrySetResult(true);
- //await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
+ await DeleteTempFile(_tempFilePath).ConfigureAwait(false);
});
}
diff --git a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
index 525df0350..36e8b4dd8 100644
--- a/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
+++ b/Emby.Server.Implementations/Playlists/PlaylistImageProvider.cs
@@ -53,7 +53,7 @@ namespace Emby.Server.Implementations.Playlists
return subItem;
}
- var parent = subItem.GetParent();
+ var parent = subItem.IsOwnedItem ? subItem.GetOwner() : subItem.GetParent();
if (parent != null && parent.HasImage(ImageType.Primary))
{
diff --git a/MediaBrowser.Controller/Entities/AggregateFolder.cs b/MediaBrowser.Controller/Entities/AggregateFolder.cs
index 2105ef907..00fac1eab 100644
--- a/MediaBrowser.Controller/Entities/AggregateFolder.cs
+++ b/MediaBrowser.Controller/Entities/AggregateFolder.cs
@@ -137,7 +137,7 @@ namespace MediaBrowser.Controller.Entities
{
FileInfo = FileSystem.GetDirectoryInfo(path),
Path = path,
- Parent = Parent
+ Parent = GetParent() as Folder
};
// Gather child folder and files
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 4416c5e91..502ba6c60 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -97,7 +97,7 @@ namespace MediaBrowser.Controller.Entities
public string Tagline { get; set; }
[IgnoreDataMember]
- public ItemImageInfo[] ImageInfos { get; set; }
+ public virtual ItemImageInfo[] ImageInfos { get; set; }
[IgnoreDataMember]
public bool IsVirtualItem { get; set; }
@@ -216,6 +216,9 @@ namespace MediaBrowser.Controller.Entities
[IgnoreDataMember]
public Guid Id { get; set; }
+ [IgnoreDataMember]
+ public Guid OwnerId { get; set; }
+
///
/// Gets or sets a value indicating whether this instance is hd.
///
@@ -321,12 +324,31 @@ namespace MediaBrowser.Controller.Entities
{
get
{
+ if (OwnerId != Guid.Empty)
+ {
+ return true;
+ }
+
+ // legacy
+
// Local trailer, special feature, theme video, etc.
// An item that belongs to another item but is not part of the Parent-Child tree
- return !IsFolder && ParentId == Guid.Empty && LocationType == LocationType.FileSystem;
+ // This is a hack for now relying on ExtraType. Eventually we may need to persist this
+ if (ParentId == Guid.Empty && !IsFolder && LocationType == LocationType.FileSystem)
+ {
+ return true;
+ }
+
+ return false;
}
}
+ public BaseItem GetOwner()
+ {
+ var ownerId = OwnerId;
+ return ownerId == Guid.Empty ? null : LibraryManager.GetItemById(ownerId);
+ }
+
///
/// Gets or sets the type of the location.
///
@@ -727,17 +749,12 @@ namespace MediaBrowser.Controller.Entities
ParentId = parent == null ? Guid.Empty : parent.Id;
}
- [IgnoreDataMember]
- public IEnumerable Parents
- {
- get { return GetParents().OfType(); }
- }
-
public BaseItem GetParent()
{
- if (ParentId != Guid.Empty)
+ var parentId = ParentId;
+ if (parentId != Guid.Empty)
{
- return LibraryManager.GetItemById(ParentId);
+ return LibraryManager.GetItemById(parentId);
}
return null;
@@ -779,11 +796,13 @@ namespace MediaBrowser.Controller.Entities
{
get
{
- if (ParentId == Guid.Empty)
+ var parentId = ParentId;
+
+ if (parentId == Guid.Empty)
{
return null;
}
- return ParentId;
+ return parentId;
}
}
@@ -1002,8 +1021,11 @@ namespace MediaBrowser.Controller.Entities
{
audio = dbItem;
}
-
- audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
+ else
+ {
+ // item is new
+ audio.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
+ }
return audio;
@@ -1032,8 +1054,11 @@ namespace MediaBrowser.Controller.Entities
{
item = dbItem;
}
-
- item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
+ else
+ {
+ // item is new
+ item.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
+ }
return item;
@@ -1178,8 +1203,25 @@ namespace MediaBrowser.Controller.Entities
var newItemIds = newItems.Select(i => i.Id).ToArray();
var itemsChanged = !item.LocalTrailerIds.SequenceEqual(newItemIds);
+ var ownerId = item.Id;
- var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, true, options, cancellationToken));
+ var tasks = newItems.Select(i =>
+ {
+ var subOptions = new MetadataRefreshOptions(options);
+
+ if (!i.ExtraType.HasValue ||
+ i.ExtraType.Value != Model.Entities.ExtraType.Trailer ||
+ i.OwnerId != ownerId ||
+ i.ParentId != Guid.Empty)
+ {
+ i.ExtraType = Model.Entities.ExtraType.Trailer;
+ i.OwnerId = ownerId;
+ i.ParentId = Guid.Empty;
+ subOptions.ForceSave = true;
+ }
+
+ return RefreshMetadataForOwnedItem(i, true, subOptions, cancellationToken);
+ });
await Task.WhenAll(tasks).ConfigureAwait(false);
@@ -1196,13 +1238,20 @@ namespace MediaBrowser.Controller.Entities
var themeVideosChanged = !item.ThemeVideoIds.SequenceEqual(newThemeVideoIds);
+ var ownerId = item.Id;
+
var tasks = newThemeVideos.Select(i =>
{
var subOptions = new MetadataRefreshOptions(options);
- if (!i.IsThemeMedia)
+ if (!i.ExtraType.HasValue ||
+ i.ExtraType.Value != Model.Entities.ExtraType.ThemeVideo ||
+ i.OwnerId != ownerId ||
+ i.ParentId != Guid.Empty)
{
- i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeVideo;
+ i.ExtraType = Model.Entities.ExtraType.ThemeVideo;
+ i.OwnerId = ownerId;
+ i.ParentId = Guid.Empty;
subOptions.ForceSave = true;
}
@@ -1226,13 +1275,20 @@ namespace MediaBrowser.Controller.Entities
var themeSongsChanged = !item.ThemeSongIds.SequenceEqual(newThemeSongIds);
+ var ownerId = item.Id;
+
var tasks = newThemeSongs.Select(i =>
{
var subOptions = new MetadataRefreshOptions(options);
- if (!i.IsThemeMedia)
+ if (!i.ExtraType.HasValue ||
+ i.ExtraType.Value != Model.Entities.ExtraType.ThemeSong ||
+ i.OwnerId != ownerId ||
+ i.ParentId != Guid.Empty)
{
- i.ExtraType = MediaBrowser.Model.Entities.ExtraType.ThemeSong;
+ i.ExtraType = Model.Entities.ExtraType.ThemeSong;
+ i.OwnerId = ownerId;
+ i.ParentId = Guid.Empty;
subOptions.ForceSave = true;
}
@@ -1868,7 +1924,6 @@ namespace MediaBrowser.Controller.Entities
{
existingImage.Path = image.Path;
existingImage.DateModified = image.DateModified;
- existingImage.IsPlaceholder = image.IsPlaceholder;
}
else
@@ -1902,7 +1957,6 @@ namespace MediaBrowser.Controller.Entities
image.Path = file.FullName;
image.DateModified = imageInfo.DateModified;
- image.IsPlaceholder = false;
}
}
@@ -2359,6 +2413,14 @@ namespace MediaBrowser.Controller.Entities
newOptions.ForceSave = true;
}
+ //var parentId = Id;
+ //if (!video.IsOwnedItem || video.ParentId != parentId)
+ //{
+ // video.IsOwnedItem = true;
+ // video.ParentId = parentId;
+ // newOptions.ForceSave = true;
+ //}
+
if (video == null)
{
return Task.FromResult(true);
diff --git a/MediaBrowser.Controller/Entities/CollectionFolder.cs b/MediaBrowser.Controller/Entities/CollectionFolder.cs
index 537beb26b..a83e084db 100644
--- a/MediaBrowser.Controller/Entities/CollectionFolder.cs
+++ b/MediaBrowser.Controller/Entities/CollectionFolder.cs
@@ -280,7 +280,7 @@ namespace MediaBrowser.Controller.Entities
{
FileInfo = FileSystem.GetDirectoryInfo(path),
Path = path,
- Parent = Parent,
+ Parent = GetParent() as Folder,
CollectionType = CollectionType
};
diff --git a/MediaBrowser.Controller/Entities/Folder.cs b/MediaBrowser.Controller/Entities/Folder.cs
index 2e741a8c4..6d88f7015 100644
--- a/MediaBrowser.Controller/Entities/Folder.cs
+++ b/MediaBrowser.Controller/Entities/Folder.cs
@@ -378,6 +378,7 @@ namespace MediaBrowser.Controller.Entities
cancellationToken.ThrowIfCancellationRequested();
var validChildren = new List();
+ var validChildrenNeedGeneration = false;
var allLibraryPaths = LibraryManager
.GetVirtualFolders()
@@ -474,11 +475,7 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- if (recursive || refreshChildMetadata)
- {
- // used below
- validChildren = Children.ToList();
- }
+ validChildrenNeedGeneration = true;
}
progress.Report(10);
@@ -502,6 +499,12 @@ namespace MediaBrowser.Controller.Entities
ProviderManager.OnRefreshProgress(folder, newPct);
});
+ if (validChildrenNeedGeneration)
+ {
+ validChildren = Children.ToList();
+ validChildrenNeedGeneration = false;
+ }
+
await ValidateSubFolders(validChildren.OfType().ToList(), directoryService, innerProgress, cancellationToken).ConfigureAwait(false);
}
}
@@ -536,6 +539,12 @@ namespace MediaBrowser.Controller.Entities
}
else
{
+ if (validChildrenNeedGeneration)
+ {
+ validChildren = Children.ToList();
+ validChildrenNeedGeneration = false;
+ }
+
await RefreshMetadataRecursive(validChildren, refreshOptions, recursive, innerProgress, cancellationToken);
}
}
@@ -565,7 +574,7 @@ namespace MediaBrowser.Controller.Entities
});
await RefreshChildMetadata(child, refreshOptions, recursive && child.IsFolder, innerProgress, cancellationToken)
- .ConfigureAwait(false);
+ .ConfigureAwait(false);
}
numComplete++;
@@ -588,7 +597,10 @@ namespace MediaBrowser.Controller.Entities
}
else
{
- await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ if (refreshOptions.RefreshItem(child))
+ {
+ await child.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
if (recursive)
{
@@ -1196,11 +1208,21 @@ namespace MediaBrowser.Controller.Entities
/// Gets the linked children.
///
/// IEnumerable{BaseItem}.
- public IEnumerable GetLinkedChildren()
+ public List GetLinkedChildren()
{
- return LinkedChildren
- .Select(GetLinkedChild)
- .Where(i => i != null);
+ var linkedChildren = LinkedChildren;
+ var list = new List(linkedChildren.Length);
+
+ foreach (var i in linkedChildren)
+ {
+ var child = GetLinkedChild(i);
+
+ if (child != null)
+ {
+ list.Add(child);
+ }
+ }
+ return list;
}
protected virtual bool FilterLinkedChildrenPerUser
@@ -1211,16 +1233,19 @@ namespace MediaBrowser.Controller.Entities
}
}
- public IEnumerable GetLinkedChildren(User user)
+ public List GetLinkedChildren(User user)
{
if (!FilterLinkedChildrenPerUser || user == null)
{
return GetLinkedChildren();
}
- if (LinkedChildren.Length == 0)
+ var linkedChildren = LinkedChildren;
+ var list = new List(linkedChildren.Length);
+
+ if (linkedChildren.Length == 0)
{
- return new List();
+ return list;
}
var allUserRootChildren = user.RootFolder.Children.OfType().ToList();
@@ -1231,37 +1256,43 @@ namespace MediaBrowser.Controller.Entities
.Select(i => i.Id)
.ToList();
- return LinkedChildren
- .Select(i =>
+ foreach (var i in linkedChildren)
+ {
+ var child = GetLinkedChild(i);
+
+ if (child == null)
{
- var child = GetLinkedChild(i);
+ continue;
+ }
- if (child != null)
+ var childOwner = child.IsOwnedItem ? (child.GetOwner() ?? child) : child;
+
+ if (childOwner != null)
+ {
+ var childLocationType = childOwner.LocationType;
+ if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
{
- var childLocationType = child.LocationType;
- if (childLocationType == LocationType.Remote || childLocationType == LocationType.Virtual)
+ if (!childOwner.IsVisibleStandalone(user))
{
- if (!child.IsVisibleStandalone(user))
- {
- return null;
- }
- }
- else if (childLocationType == LocationType.FileSystem)
- {
- var itemCollectionFolderIds =
- LibraryManager.GetCollectionFolders(child, allUserRootChildren)
- .Select(f => f.Id).ToList();
-
- if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
- {
- return null;
- }
+ continue;
}
}
+ else if (childLocationType == LocationType.FileSystem)
+ {
+ var itemCollectionFolderIds =
+ LibraryManager.GetCollectionFolders(childOwner, allUserRootChildren).Select(f => f.Id);
- return child;
- })
- .Where(i => i != null);
+ if (!itemCollectionFolderIds.Any(collectionFolderIds.Contains))
+ {
+ continue;
+ }
+ }
+ }
+
+ list.Add(child);
+ }
+
+ return list;
}
///
diff --git a/MediaBrowser.Controller/Entities/IHasTrailers.cs b/MediaBrowser.Controller/Entities/IHasTrailers.cs
index 8686c802a..07dde3789 100644
--- a/MediaBrowser.Controller/Entities/IHasTrailers.cs
+++ b/MediaBrowser.Controller/Entities/IHasTrailers.cs
@@ -5,7 +5,7 @@ using System.Linq;
namespace MediaBrowser.Controller.Entities
{
- public interface IHasTrailers : IHasProviderIds
+ public interface IHasTrailers : IHasMetadata
{
///
/// Gets or sets the remote trailers.
diff --git a/MediaBrowser.Controller/Entities/ItemImageInfo.cs b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
index 672595db8..6b2d2392d 100644
--- a/MediaBrowser.Controller/Entities/ItemImageInfo.cs
+++ b/MediaBrowser.Controller/Entities/ItemImageInfo.cs
@@ -24,12 +24,6 @@ namespace MediaBrowser.Controller.Entities
/// The date modified.
public DateTime DateModified { get; set; }
- ///
- /// Gets or sets a value indicating whether this instance is placeholder.
- ///
- /// true if this instance is placeholder; otherwise, false.
- public bool IsPlaceholder { get; set; }
-
[IgnoreDataMember]
public bool IsLocalFile
{
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index 3a41709fe..2e0e01944 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -81,7 +81,20 @@ namespace MediaBrowser.Controller.Entities.Movies
var itemsChanged = !SpecialFeatureIds.SequenceEqual(newItemIds);
- var tasks = newItems.Select(i => RefreshMetadataForOwnedItem(i, false, options, cancellationToken));
+ var ownerId = Id;
+
+ var tasks = newItems.Select(i =>
+ {
+ var subOptions = new MetadataRefreshOptions(options);
+
+ if (i.OwnerId != ownerId)
+ {
+ i.OwnerId = ownerId;
+ subOptions.ForceSave = true;
+ }
+
+ return RefreshMetadataForOwnedItem(i, false, subOptions, cancellationToken);
+ });
await Task.WhenAll(tasks).ConfigureAwait(false);
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 60d2624fa..5931c32e1 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -347,7 +347,10 @@ namespace MediaBrowser.Controller.Entities.TV
cancellationToken.ThrowIfCancellationRequested();
- await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ if (refreshOptions.RefreshItem(item))
+ {
+ await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
numComplete++;
double percent = numComplete;
@@ -382,7 +385,10 @@ namespace MediaBrowser.Controller.Entities.TV
if (!skipItem)
{
- await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ if (refreshOptions.RefreshItem(item))
+ {
+ await item.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+ }
}
numComplete++;
diff --git a/MediaBrowser.Controller/Entities/User.cs b/MediaBrowser.Controller/Entities/User.cs
index cca3091c1..4aa1311e1 100644
--- a/MediaBrowser.Controller/Entities/User.cs
+++ b/MediaBrowser.Controller/Entities/User.cs
@@ -37,6 +37,9 @@ namespace MediaBrowser.Controller.Entities
public UserLinkType? ConnectLinkType { get; set; }
public string ConnectAccessKey { get; set; }
+ // Strictly to remove IgnoreDataMember
+ public override ItemImageInfo[] ImageInfos { get => base.ImageInfos; set => base.ImageInfos = value; }
+
///
/// Gets or sets the path.
///
diff --git a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
index 86cef628e..0df2370bd 100644
--- a/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
+++ b/MediaBrowser.Controller/Providers/MetadataRefreshOptions.cs
@@ -1,5 +1,7 @@
-using System.Linq;
-
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.IO;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.Logging;
@@ -20,6 +22,8 @@ namespace MediaBrowser.Controller.Providers
public MetadataRefreshMode MetadataRefreshMode { get; set; }
public RemoteSearchResult SearchResult { get; set; }
+ public List RefreshPaths { get; set; }
+
public bool ForceSave { get; set; }
public MetadataRefreshOptions(IFileSystem fileSystem)
@@ -44,6 +48,26 @@ namespace MediaBrowser.Controller.Providers
ReplaceAllImages = copy.ReplaceAllImages;
ReplaceImages = copy.ReplaceImages.ToList();
SearchResult = copy.SearchResult;
+
+ if (copy.RefreshPaths != null && copy.RefreshPaths.Count > 0)
+ {
+ if (RefreshPaths == null)
+ {
+ RefreshPaths = new List();
+ }
+
+ RefreshPaths.AddRange(copy.RefreshPaths);
+ }
+ }
+
+ public bool RefreshItem(BaseItem item)
+ {
+ if (RefreshPaths != null && RefreshPaths.Count > 0)
+ {
+ return RefreshPaths.Contains(item.Path ?? string.Empty, StringComparer.OrdinalIgnoreCase);
+ }
+
+ return true;
}
}
}
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index 2c2f22e86..a70a1066d 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -33,7 +33,6 @@ namespace MediaBrowser.Model.LiveTv
MediaLocationsCreated = new string[] { };
RecordingEncodingFormat = "mkv";
RecordingPostProcessorArguments = "\"{path}\"";
- EnableRecordingEncoding = true;
}
}
diff --git a/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs b/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
index e24547614..0e6c07357 100644
--- a/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
+++ b/MediaBrowser.Providers/Manager/GenericPriorityQueue.cs
@@ -1,6 +1,7 @@
using System;
using System.Collections;
using System.Collections.Generic;
+using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
@@ -66,9 +67,7 @@ namespace Priority_Queue
/// Removes every node from the queue.
/// O(n) (So, don't do this often!)
///
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
public void Clear()
{
Array.Clear(_nodes, 1, _numNodes);
@@ -78,9 +77,7 @@ namespace Priority_Queue
///
/// Returns (in O(1)!) whether the given node is in the queue. O(1)
///
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
public bool Contains(TItem node)
{
#if DEBUG
@@ -103,9 +100,7 @@ namespace Priority_Queue
/// If the node is already enqueued, the result is undefined.
/// O(log n)
///
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
public void Enqueue(TItem node, TPriority priority)
{
#if DEBUG
@@ -131,9 +126,7 @@ namespace Priority_Queue
CascadeUp(_nodes[_numNodes]);
}
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
private void Swap(TItem node1, TItem node2)
{
//Swap the nodes
@@ -164,9 +157,7 @@ namespace Priority_Queue
}
}
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
private void CascadeDown(TItem node)
{
//aka Heapify-down
@@ -228,9 +219,7 @@ namespace Priority_Queue
/// Returns true if 'higher' has higher priority than 'lower', false otherwise.
/// Note that calling HasHigherPriority(node, node) (ie. both arguments the same node) will return false
///
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
private bool HasHigherPriority(TItem higher, TItem lower)
{
var cmp = higher.Priority.CompareTo(lower.Priority);
@@ -319,9 +308,7 @@ namespace Priority_Queue
/// Calling this method on a node not in the queue results in undefined behavior
/// O(log n)
///
-#if NET_VERSION_4_5
[MethodImpl(MethodImplOptions.AggressiveInlining)]
-#endif
public void UpdatePriority(TItem node, TPriority priority)
{
#if DEBUG
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index e62ce0225..a6d4d4c33 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -206,8 +206,7 @@ namespace MediaBrowser.Providers.Manager
{
var image = item.GetImageInfo(type, 0);
- // if it's a placeholder image then pretend like it's not there so that we can replace it
- return image != null && !image.IsPlaceholder;
+ return image != null;
}
///
@@ -547,7 +546,7 @@ namespace MediaBrowser.Providers.Manager
switch (type)
{
case ImageType.Primary:
- return !(item is Movie || item is Series || item is Game);
+ return true;
default:
return true;
}
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index ae029cc59..b93f78341 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -262,8 +262,7 @@ namespace MediaBrowser.Providers.Manager
personEntity.SetImage(new ItemImageInfo
{
Path = imageUrl,
- Type = ImageType.Primary,
- IsPlaceholder = true
+ Type = ImageType.Primary
}, 0);
}
diff --git a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
index 333f3d593..a9aa71bfa 100644
--- a/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/FFProbeProvider.cs
@@ -146,6 +146,11 @@ namespace MediaBrowser.Providers.MediaInfo
return _cachedTask;
}
+ if (!item.IsCompleteMedia)
+ {
+ return _cachedTask;
+ }
+
if (item.IsShortcut)
{
FetchShortcutInfo(item);
diff --git a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
index f666d8b7f..9b0d29cf0 100644
--- a/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/VideoImageProvider.cs
@@ -133,7 +133,7 @@ namespace MediaBrowser.Providers.MediaInfo
{
var video = item as Video;
- if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut)
+ if (item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && video.IsCompleteMedia)
{
return true;
}