Browse Source

update program titles

Luke Pulverenti 8 years ago
parent
commit
2ef30a3ba8
27 changed files with 275 additions and 273 deletions
  1. 0 6
      Emby.Common.Implementations/BaseApplicationHost.cs
  2. 2 1
      Emby.Server.Core/ApplicationHost.cs
  3. 12 2
      Emby.Server.Implementations/Data/SqliteItemRepository.cs
  4. 3 2
      Emby.Server.Implementations/EntryPoints/SystemEvents.cs
  5. 3 2
      Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
  6. 3 2
      Emby.Server.Implementations/EntryPoints/UsageReporter.cs
  7. 168 166
      Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
  8. 1 2
      Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
  9. 2 0
      Emby.Server.Implementations/Library/MediaSourceManager.cs
  10. 2 0
      Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
  11. 1 9
      Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs
  12. 1 9
      Emby.Server.Implementations/LiveTv/LiveTvManager.cs
  13. 1 9
      Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
  14. 2 0
      Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
  15. 0 1
      Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
  16. 2 0
      Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
  17. 11 0
      MediaBrowser.Api/Playback/MediaInfoService.cs
  18. 0 6
      MediaBrowser.Common/IApplicationHost.cs
  19. 1 6
      MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
  20. 2 9
      MediaBrowser.Controller/Entities/Audio/Audio.cs
  21. 1 1
      MediaBrowser.Controller/Entities/InternalItemsQuery.cs
  22. 2 16
      MediaBrowser.Controller/Entities/Video.cs
  23. 6 0
      MediaBrowser.Controller/IServerApplicationHost.cs
  24. 28 2
      MediaBrowser.Model/Dto/MediaSourceInfo.cs
  25. 0 6
      MediaBrowser.Model/System/SystemInfo.cs
  26. 19 16
      MediaBrowser.Providers/Manager/ProviderManager.cs
  27. 2 0
      MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs

+ 0 - 6
Emby.Common.Implementations/BaseApplicationHost.cs

@@ -161,12 +161,6 @@ namespace Emby.Common.Implementations
         /// <value>The name.</value>
         public abstract string Name { get; }
 
-        /// <summary>
-        /// Gets a value indicating whether this instance is running as service.
-        /// </summary>
-        /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
-        public abstract bool IsRunningAsService { get; }
-
         protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
 
         protected IEnvironmentInfo EnvironmentInfo { get; private set; }

+ 2 - 1
Emby.Server.Core/ApplicationHost.cs

@@ -326,6 +326,8 @@ namespace Emby.Server.Core
             }
         }
 
+        public abstract bool IsRunningAsService { get; }
+
         private Assembly GetAssembly(Type type)
         {
             return type.GetTypeInfo().Assembly;
@@ -1247,7 +1249,6 @@ namespace Emby.Server.Core
                 HasUpdateAvailable = HasUpdateAvailable,
                 SupportsAutoRunAtStartup = SupportsAutoRunAtStartup,
                 TranscodingTempPath = ApplicationPaths.TranscodingTempPath,
-                IsRunningAsService = IsRunningAsService,
                 SupportsRunningAsService = SupportsRunningAsService,
                 ServerName = FriendlyName,
                 LocalAddress = localAddress,

+ 12 - 2
Emby.Server.Implementations/Data/SqliteItemRepository.cs

@@ -2384,8 +2384,17 @@ namespace Emby.Server.Implementations.Data
 
                 var excludeIds = query.ExcludeItemIds.ToList();
                 excludeIds.Add(item.Id.ToString("N"));
-                query.ExcludeItemIds = excludeIds.ToArray();
 
+                if (query.IncludeItemTypes.Length == 0 || query.IncludeItemTypes.Contains(typeof(Trailer).Name))
+                {
+                    var hasTrailers = item as IHasTrailers;
+                    if (hasTrailers != null)
+                    {
+                        excludeIds.AddRange(hasTrailers.GetTrailerIds().Select(i => i.ToString("N")));
+                    }
+                }
+
+                query.ExcludeItemIds = excludeIds.ToArray();
                 query.ExcludeProviderIds = item.ProviderIds;
             }
 
@@ -2821,8 +2830,9 @@ namespace Emby.Server.Implementations.Data
             {
                 if (orderBy.Count == 0)
                 {
-                    orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
                     orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
+                    orderBy.Add(new Tuple<string, SortOrder>("SimilarityScore", SortOrder.Descending));
+                    //orderBy.Add(new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending));
                     query.SortOrder = SortOrder.Descending;
                     enableOrderInversion = false;
                 }

+ 3 - 2
Emby.Server.Implementations/EntryPoints/SystemEvents.cs

@@ -6,15 +6,16 @@ using System.Threading.Tasks;
 using MediaBrowser.Model.System;
 using MediaBrowser.Controller.Plugins;
 using MediaBrowser.Common;
+using MediaBrowser.Controller;
 
 namespace Emby.Server.Implementations.EntryPoints
 {
     public class SystemEvents : IServerEntryPoint
     {
         private readonly ISystemEvents _systemEvents;
-        private readonly IApplicationHost _appHost;
+        private readonly IServerApplicationHost _appHost;
 
-        public SystemEvents(ISystemEvents systemEvents, IApplicationHost appHost)
+        public SystemEvents(ISystemEvents systemEvents, IServerApplicationHost appHost)
         {
             _systemEvents = systemEvents;
             _appHost = appHost;

+ 3 - 2
Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs

@@ -10,6 +10,7 @@ using System.Collections.Concurrent;
 using System.Collections.Generic;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller;
 using MediaBrowser.Controller.Configuration;
 
 namespace Emby.Server.Implementations.EntryPoints
@@ -19,7 +20,7 @@ namespace Emby.Server.Implementations.EntryPoints
     /// </summary>
     public class UsageEntryPoint : IServerEntryPoint
     {
-        private readonly IApplicationHost _applicationHost;
+        private readonly IServerApplicationHost _applicationHost;
         private readonly IHttpClient _httpClient;
         private readonly ILogger _logger;
         private readonly ISessionManager _sessionManager;
@@ -28,7 +29,7 @@ namespace Emby.Server.Implementations.EntryPoints
 
         private readonly ConcurrentDictionary<Guid, ClientInfo> _apps = new ConcurrentDictionary<Guid, ClientInfo>();
 
-        public UsageEntryPoint(ILogger logger, IApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config)
+        public UsageEntryPoint(ILogger logger, IServerApplicationHost applicationHost, IHttpClient httpClient, ISessionManager sessionManager, IUserManager userManager, IServerConfigurationManager config)
         {
             _logger = logger;
             _applicationHost = applicationHost;

+ 3 - 2
Emby.Server.Implementations/EntryPoints/UsageReporter.cs

@@ -8,19 +8,20 @@ using System.Globalization;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller;
 using MediaBrowser.Model.Logging;
 
 namespace Emby.Server.Implementations.EntryPoints
 {
     public class UsageReporter
     {
-        private readonly IApplicationHost _applicationHost;
+        private readonly IServerApplicationHost _applicationHost;
         private readonly IHttpClient _httpClient;
         private readonly IUserManager _userManager;
         private readonly ILogger _logger;
         private const string MbAdminUrl = "https://www.mb3admin.com/admin/";
 
-        public UsageReporter(IApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger)
+        public UsageReporter(IServerApplicationHost applicationHost, IHttpClient httpClient, IUserManager userManager, ILogger logger)
         {
             _applicationHost = applicationHost;
             _httpClient = httpClient;

+ 168 - 166
Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs

@@ -61,92 +61,92 @@ namespace Emby.Server.Implementations.FileOrganization
             };
 
             try
-            { 
-            if (_libraryMonitor.IsPathLocked(path))
             {
-                result.Status = FileSortingStatus.Failure;
-                result.StatusMessage = "Path is locked by other processes. Please try again later.";
-                return result;
-            }
+                if (_libraryMonitor.IsPathLocked(path))
+                {
+                    result.Status = FileSortingStatus.Failure;
+                    result.StatusMessage = "Path is locked by other processes. Please try again later.";
+                    return result;
+                }
 
-            var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
-            var resolver = new EpisodeResolver(namingOptions, new NullLogger());
+                var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
+                var resolver = new EpisodeResolver(namingOptions, new NullLogger());
 
-            var episodeInfo = resolver.Resolve(path, false) ??
-                new MediaBrowser.Naming.TV.EpisodeInfo();
+                var episodeInfo = resolver.Resolve(path, false) ??
+                    new MediaBrowser.Naming.TV.EpisodeInfo();
 
-            var seriesName = episodeInfo.SeriesName;
+                var seriesName = episodeInfo.SeriesName;
 
-            if (!string.IsNullOrEmpty(seriesName))
-            {
-                var seasonNumber = episodeInfo.SeasonNumber;
+                if (!string.IsNullOrEmpty(seriesName))
+                {
+                    var seasonNumber = episodeInfo.SeasonNumber;
 
-                result.ExtractedSeasonNumber = seasonNumber;
+                    result.ExtractedSeasonNumber = seasonNumber;
 
-                // Passing in true will include a few extra regex's
-                var episodeNumber = episodeInfo.EpisodeNumber;
+                    // Passing in true will include a few extra regex's
+                    var episodeNumber = episodeInfo.EpisodeNumber;
 
-                result.ExtractedEpisodeNumber = episodeNumber;
+                    result.ExtractedEpisodeNumber = episodeNumber;
 
-                var premiereDate = episodeInfo.IsByDate ?
-                    new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
-                    (DateTime?)null;
+                    var premiereDate = episodeInfo.IsByDate ?
+                        new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
+                        (DateTime?)null;
 
-                if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
-                {
-                    if (episodeInfo.IsByDate)
+                    if (episodeInfo.IsByDate || (seasonNumber.HasValue && episodeNumber.HasValue))
                     {
-                        _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
+                        if (episodeInfo.IsByDate)
+                        {
+                            _logger.Debug("Extracted information from {0}. Series name {1}, Date {2}", path, seriesName, premiereDate.Value);
+                        }
+                        else
+                        {
+                            _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
+                        }
+
+                        var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;
+
+                        result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;
+
+                        await OrganizeEpisode(path,
+                            seriesName,
+                            seasonNumber,
+                            episodeNumber,
+                            endingEpisodeNumber,
+                            premiereDate,
+                            options,
+                            overwriteExisting,
+                            false,
+                            result,
+                            cancellationToken).ConfigureAwait(false);
                     }
                     else
                     {
-                        _logger.Debug("Extracted information from {0}. Series name {1}, Season {2}, Episode {3}", path, seriesName, seasonNumber, episodeNumber);
+                        var msg = string.Format("Unable to determine episode number from {0}", path);
+                        result.Status = FileSortingStatus.Failure;
+                        result.StatusMessage = msg;
+                        _logger.Warn(msg);
                     }
-
-                    var endingEpisodeNumber = episodeInfo.EndingEpsiodeNumber;
-
-                    result.ExtractedEndingEpisodeNumber = endingEpisodeNumber;
-
-                    await OrganizeEpisode(path,
-                        seriesName,
-                        seasonNumber,
-                        episodeNumber,
-                        endingEpisodeNumber,
-                        premiereDate,
-                        options,
-                        overwriteExisting,
-                        false,
-                        result,
-                        cancellationToken).ConfigureAwait(false);
                 }
                 else
                 {
-                    var msg = string.Format("Unable to determine episode number from {0}", path);
+                    var msg = string.Format("Unable to determine series name from {0}", path);
                     result.Status = FileSortingStatus.Failure;
                     result.StatusMessage = msg;
                     _logger.Warn(msg);
                 }
-            }
-            else
-            {
-                var msg = string.Format("Unable to determine series name from {0}", path);
-                result.Status = FileSortingStatus.Failure;
-                result.StatusMessage = msg;
-                _logger.Warn(msg);
-            }
 
-            var previousResult = _organizationService.GetResultBySourcePath(path);
+                var previousResult = _organizationService.GetResultBySourcePath(path);
 
-            if (previousResult != null)
-            {
-                // Don't keep saving the same result over and over if nothing has changed
-                if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
+                if (previousResult != null)
                 {
-                    return previousResult;
+                    // Don't keep saving the same result over and over if nothing has changed
+                    if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
+                    {
+                        return previousResult;
+                    }
                 }
-            }
 
-            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
+                await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
             }
             catch (Exception ex)
             {
@@ -162,58 +162,60 @@ namespace Emby.Server.Implementations.FileOrganization
             var result = _organizationService.GetResult(request.ResultId);
 
             try
-            { 
-            Series series = null;
-
-            if (request.NewSeriesProviderIds.Count > 0)
             {
-                // We're having a new series here
-                SeriesInfo seriesRequest = new SeriesInfo();
-                seriesRequest.ProviderIds = request.NewSeriesProviderIds;
-
-                var refreshOptions = new MetadataRefreshOptions(_fileSystem);
-                series = new Series();
-                series.Id = Guid.NewGuid();
-                series.Name = request.NewSeriesName;
+                Series series = null;
 
-                int year;
-                if (int.TryParse(request.NewSeriesYear, out year))
+                if (request.NewSeriesProviderIds.Count > 0)
                 {
-                    series.ProductionYear = year;
-                }
+                    // We're having a new series here
+                    SeriesInfo seriesRequest = new SeriesInfo();
+                    seriesRequest.ProviderIds = request.NewSeriesProviderIds;
 
-                var seriesFolderName = series.Name;
-                if (series.ProductionYear.HasValue)
-                {
-                    seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
-                }
+                    var refreshOptions = new MetadataRefreshOptions(_fileSystem);
+                    series = new Series();
+                    series.Id = Guid.NewGuid();
+                    series.Name = request.NewSeriesName;
+
+                    int year;
+                    if (int.TryParse(request.NewSeriesYear, out year))
+                    {
+                        series.ProductionYear = year;
+                    }
 
-                series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
+                    var seriesFolderName = series.Name;
+                    if (series.ProductionYear.HasValue)
+                    {
+                        seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
+                    }
 
-                series.ProviderIds = request.NewSeriesProviderIds;
+                    seriesFolderName = _fileSystem.GetValidFilename(seriesFolderName);
 
-                await series.RefreshMetadata(refreshOptions, cancellationToken);
-            }
+                    series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
 
-            if (series == null)
-            {
-                // Existing Series
-                series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
-            }
+                    series.ProviderIds = request.NewSeriesProviderIds;
 
-            await OrganizeEpisode(result.OriginalPath,
-                series,
-                request.SeasonNumber,
-                request.EpisodeNumber,
-                request.EndingEpisodeNumber,
-                null,
-                options,
-                true,
-                request.RememberCorrection,
-                result,
-                cancellationToken).ConfigureAwait(false);
+                    await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
+                }
+
+                if (series == null)
+                {
+                    // Existing Series
+                    series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
+                }
+
+                await OrganizeEpisode(result.OriginalPath,
+                    series,
+                    request.SeasonNumber,
+                    request.EpisodeNumber,
+                    request.EndingEpisodeNumber,
+                    null,
+                    options,
+                    true,
+                    request.RememberCorrection,
+                    result,
+                    cancellationToken).ConfigureAwait(false);
 
-            await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
+                await _organizationService.SaveResult(result, CancellationToken.None).ConfigureAwait(false);
             }
             catch (Exception ex)
             {
@@ -287,91 +289,91 @@ namespace Emby.Server.Implementations.FileOrganization
             {
                 throw new Exception("File is currently processed otherwise. Please try again later.");
             }
-            
-            try
-            {
-            // Proceed to sort the file
-            var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
-
-            if (string.IsNullOrEmpty(newPath))
-            {
-                var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
-                throw new Exception(msg);
-            }
-
-            _logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
-            result.TargetPath = newPath;
-
-            var fileExists = _fileSystem.FileExists(result.TargetPath);
-            var otherDuplicatePaths = GetOtherDuplicatePaths(result.TargetPath, series, seasonNumber, episodeNumber, endingEpiosdeNumber);
 
-            if (!overwriteExisting)
+            try
             {
-                if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
-                {
-                    var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath);
-                    _logger.Info(msg);
-                    result.Status = FileSortingStatus.SkippedExisting;
-                    result.StatusMessage = msg;
-                    return;
-                }
+                // Proceed to sort the file
+                var newPath = await GetNewPath(sourcePath, series, seasonNumber, episodeNumber, endingEpiosdeNumber, premiereDate, options.TvOptions, cancellationToken).ConfigureAwait(false);
 
-                if (fileExists)
+                if (string.IsNullOrEmpty(newPath))
                 {
-                    var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath);
-                    _logger.Info(msg);
-                    result.Status = FileSortingStatus.SkippedExisting;
-                    result.StatusMessage = msg;
-                    result.TargetPath = newPath;
-                    return;
+                    var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
+                    throw new Exception(msg);
                 }
 
-                if (otherDuplicatePaths.Count > 0)
-                {
-                    var msg = string.Format("File '{0}' already exists as these:'{1}'. Stopping organization", sourcePath, string.Join("', '", otherDuplicatePaths));
-                    _logger.Info(msg);
-                    result.Status = FileSortingStatus.SkippedExisting;
-                    result.StatusMessage = msg;
-                    result.DuplicatePaths = otherDuplicatePaths;
-                    return;
-                }
-            }
+                _logger.Info("Sorting file {0} to new path {1}", sourcePath, newPath);
+                result.TargetPath = newPath;
 
-            PerformFileSorting(options.TvOptions, result);
-
-            if (overwriteExisting)
-            {
-                var hasRenamedFiles = false;
+                var fileExists = _fileSystem.FileExists(result.TargetPath);
+                var otherDuplicatePaths = GetOtherDuplicatePaths(result.TargetPath, series, seasonNumber, episodeNumber, endingEpiosdeNumber);
 
-                foreach (var path in otherDuplicatePaths)
+                if (!overwriteExisting)
                 {
-                    _logger.Debug("Removing duplicate episode {0}", path);
-
-                    _libraryMonitor.ReportFileSystemChangeBeginning(path);
-
-                    var renameRelatedFiles = !hasRenamedFiles &&
-                        string.Equals(Path.GetDirectoryName(path), Path.GetDirectoryName(result.TargetPath), StringComparison.OrdinalIgnoreCase);
-
-                    if (renameRelatedFiles)
+                    if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
                     {
-                        hasRenamedFiles = true;
+                        var msg = string.Format("File '{0}' already copied to new path '{1}', stopping organization", sourcePath, newPath);
+                        _logger.Info(msg);
+                        result.Status = FileSortingStatus.SkippedExisting;
+                        result.StatusMessage = msg;
+                        return;
                     }
 
-                    try
+                    if (fileExists)
                     {
-                        DeleteLibraryFile(path, renameRelatedFiles, result.TargetPath);
+                        var msg = string.Format("File '{0}' already exists as '{1}', stopping organization", sourcePath, newPath);
+                        _logger.Info(msg);
+                        result.Status = FileSortingStatus.SkippedExisting;
+                        result.StatusMessage = msg;
+                        result.TargetPath = newPath;
+                        return;
                     }
-                    catch (IOException ex)
+
+                    if (otherDuplicatePaths.Count > 0)
                     {
-                        _logger.ErrorException("Error removing duplicate episode", ex, path);
+                        var msg = string.Format("File '{0}' already exists as these:'{1}'. Stopping organization", sourcePath, string.Join("', '", otherDuplicatePaths));
+                        _logger.Info(msg);
+                        result.Status = FileSortingStatus.SkippedExisting;
+                        result.StatusMessage = msg;
+                        result.DuplicatePaths = otherDuplicatePaths;
+                        return;
                     }
-                    finally
+                }
+
+                PerformFileSorting(options.TvOptions, result);
+
+                if (overwriteExisting)
+                {
+                    var hasRenamedFiles = false;
+
+                    foreach (var path in otherDuplicatePaths)
                     {
-                        _libraryMonitor.ReportFileSystemChangeComplete(path, true);
+                        _logger.Debug("Removing duplicate episode {0}", path);
+
+                        _libraryMonitor.ReportFileSystemChangeBeginning(path);
+
+                        var renameRelatedFiles = !hasRenamedFiles &&
+                            string.Equals(Path.GetDirectoryName(path), Path.GetDirectoryName(result.TargetPath), StringComparison.OrdinalIgnoreCase);
+
+                        if (renameRelatedFiles)
+                        {
+                            hasRenamedFiles = true;
+                        }
+
+                        try
+                        {
+                            DeleteLibraryFile(path, renameRelatedFiles, result.TargetPath);
+                        }
+                        catch (IOException ex)
+                        {
+                            _logger.ErrorException("Error removing duplicate episode", ex, path);
+                        }
+                        finally
+                        {
+                            _libraryMonitor.ReportFileSystemChangeComplete(path, true);
+                        }
                     }
                 }
             }
-            }
             catch (Exception ex)
             {
                 result.Status = FileSortingStatus.Failure;

+ 1 - 2
Emby.Server.Implementations/Intros/DefaultIntroProvider.cs

@@ -118,8 +118,7 @@ namespace Emby.Server.Implementations.Intros
 
                     // Account for duplicates by imdb id, since the database doesn't support this yet
                     Limit = config.TrailerLimit * 4,
-                    SourceTypes = sourceTypes.ToArray(),
-                    MinSimilarityScore = 0
+                    SourceTypes = sourceTypes.ToArray()
                 })
                 .Where(i => string.IsNullOrWhiteSpace(i.GetProviderId(MetadataProviders.Imdb)) || !string.Equals(i.GetProviderId(MetadataProviders.Imdb), item.GetProviderId(MetadataProviders.Imdb), StringComparison.OrdinalIgnoreCase))
                 .Where(i => i.IsVisibleStandalone(user))

+ 2 - 0
Emby.Server.Implementations/Library/MediaSourceManager.cs

@@ -199,6 +199,8 @@ namespace Emby.Server.Implementations.Library
 
                 foreach (var mediaSource in list)
                 {
+                    mediaSource.InferTotalBitrate();
+
                     SetKeyProperties(provider, mediaSource);
                 }
 

+ 2 - 0
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1064,6 +1064,8 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                 var isAudio = false;
                 await new LiveStreamHelper(_mediaEncoder, _logger).AddMediaInfoWithProbe(stream, isAudio, cancellationToken).ConfigureAwait(false);
 
+                stream.InferTotalBitrate();
+
                 return new List<MediaSourceInfo>
                 {
                     stream

+ 1 - 9
Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs

@@ -96,15 +96,7 @@ namespace Emby.Server.Implementations.LiveTv
             }
 
             // Try to estimate this
-            if (!mediaSource.Bitrate.HasValue)
-            {
-                var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
-
-                if (total > 0)
-                {
-                    mediaSource.Bitrate = total;
-                }
-            }
+            mediaSource.InferTotalBitrate();
         }
     }
 }

+ 1 - 9
Emby.Server.Implementations/LiveTv/LiveTvManager.cs

@@ -459,15 +459,7 @@ namespace Emby.Server.Implementations.LiveTv
             }
 
             // Set the total bitrate if not already supplied
-            if (!mediaSource.Bitrate.HasValue)
-            {
-                var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
-
-                if (total > 0)
-                {
-                    mediaSource.Bitrate = total;
-                }
-            }
+            mediaSource.InferTotalBitrate();
 
             if (!(service is EmbyTV.EmbyTV))
             {

+ 1 - 9
Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs

@@ -200,15 +200,7 @@ namespace Emby.Server.Implementations.LiveTv
             }
 
             // Try to estimate this
-            if (!mediaSource.Bitrate.HasValue)
-            {
-                var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
-
-                if (total > 0)
-                {
-                    mediaSource.Bitrate = total;
-                }
-            }
+            mediaSource.InferTotalBitrate();
         }
 
         public Task CloseMediaSource(string liveStreamId)

+ 2 - 0
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -431,6 +431,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 IsInfiniteStream = true
             };
 
+            mediaSource.InferTotalBitrate();
+
             return mediaSource;
         }
 

+ 0 - 1
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs

@@ -25,7 +25,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
         private readonly TaskCompletionSource<bool> _liveStreamTaskCompletionSource = new TaskCompletionSource<bool>();
         private readonly MulticastStream _multicastStream;
 
-
         public HdHomerunLiveStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost)
             : base(mediaSource)
         {

+ 2 - 0
Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs

@@ -164,6 +164,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
                     IsRemote = true
                 };
 
+                mediaSource.InferTotalBitrate();
+
                 return new List<MediaSourceInfo> { mediaSource };
             }
             return new List<MediaSourceInfo>();

+ 11 - 0
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -175,6 +175,15 @@ namespace MediaBrowser.Api.Playback
             return ToOptimizedResult(info);
         }
 
+        private T Clone<T>(T obj)
+        {
+            // Since we're going to be setting properties on MediaSourceInfos that come out of _mediaSourceManager, we should clone it
+            // Should we move this directly into MediaSourceManager?
+
+            var json = _json.SerializeToString(obj);
+            return _json.DeserializeFromString<T>(json);
+        }
+
         private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId, string[] supportedLiveMediaTypes, string mediaSourceId = null, string liveStreamId = null)
         {
             var result = new PlaybackInfoResponse();
@@ -217,6 +226,8 @@ namespace MediaBrowser.Api.Playback
             }
             else
             {
+                result.MediaSources = Clone(result.MediaSources);
+
                 result.PlaySessionId = Guid.NewGuid().ToString("N");
             }
 

+ 0 - 6
MediaBrowser.Common/IApplicationHost.cs

@@ -36,12 +36,6 @@ namespace MediaBrowser.Common
         /// </summary>
         event EventHandler<GenericEventArgs<PackageVersionInfo>> ApplicationUpdated;
 
-        /// <summary>
-        /// Gets a value indicating whether this instance is running as service.
-        /// </summary>
-        /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
-        bool IsRunningAsService { get; }
-
         /// <summary>
         /// Gets or sets a value indicating whether this instance has pending kernel reload.
         /// </summary>

+ 1 - 6
MediaBrowser.Controller/Channels/ChannelMediaInfo.cs

@@ -72,12 +72,7 @@ namespace MediaBrowser.Controller.Channels
                 IsRemote = true
             };
 
-            var bitrate = (AudioBitrate ?? 0) + (VideoBitrate ?? 0);
-
-            if (bitrate > 0)
-            {
-                source.Bitrate = bitrate;
-            }
+            source.InferTotalBitrate();
 
             return source;
         }

+ 2 - 9
MediaBrowser.Controller/Entities/Audio/Audio.cs

@@ -267,15 +267,8 @@ namespace MediaBrowser.Controller.Entities.Audio
                 }
             }
 
-            var bitrate = i.TotalBitrate ??
-                info.MediaStreams.Where(m => m.Type == MediaStreamType.Audio)
-                .Select(m => m.BitRate ?? 0)
-                .Sum();
-
-            if (bitrate > 0)
-            {
-                info.Bitrate = bitrate;
-            }
+            info.Bitrate = i.TotalBitrate;
+            info.InferTotalBitrate();
 
             return info;
         }

+ 1 - 1
MediaBrowser.Controller/Entities/InternalItemsQuery.cs

@@ -197,7 +197,7 @@ namespace MediaBrowser.Controller.Entities
 
         public InternalItemsQuery()
         {
-            MinSimilarityScore = 1;
+            MinSimilarityScore = 20;
 
             GroupByPresentationUniqueKey = true;
             EnableTotalRecordCount = true;

+ 2 - 16
MediaBrowser.Controller/Entities/Video.cs

@@ -649,22 +649,8 @@ namespace MediaBrowser.Controller.Entities
                 }
             }
 
-            try
-            {
-                var bitrate = i.TotalBitrate ??
-                    info.MediaStreams.Where(m => m.Type != MediaStreamType.Subtitle && !string.Equals(m.Codec, "mjpeg", StringComparison.OrdinalIgnoreCase))
-                    .Select(m => m.BitRate ?? 0)
-                    .Sum();
-
-                if (bitrate > 0)
-                {
-                    info.Bitrate = bitrate;
-                }
-            }
-            catch (OverflowException ex)
-            {
-                Logger.ErrorException("Error calculating total bitrate", ex);
-            }
+            info.Bitrate = i.TotalBitrate;
+            info.InferTotalBitrate();
 
             return info;
         }

+ 6 - 0
MediaBrowser.Controller/IServerApplicationHost.cs

@@ -21,6 +21,12 @@ namespace MediaBrowser.Controller
         /// <returns>SystemInfo.</returns>
         Task<SystemInfo> GetSystemInfo();
 
+        /// <summary>
+        /// Gets a value indicating whether this instance is running as service.
+        /// </summary>
+        /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
+        bool IsRunningAsService { get; }
+
         /// <summary>
         /// Gets a value indicating whether [supports automatic run at startup].
         /// </summary>

+ 28 - 2
MediaBrowser.Model/Dto/MediaSourceInfo.cs

@@ -1,8 +1,8 @@
-using System;
-using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Entities;
 using MediaBrowser.Model.Extensions;
 using MediaBrowser.Model.MediaInfo;
 using System.Collections.Generic;
+using System.Linq;
 using MediaBrowser.Model.Serialization;
 
 namespace MediaBrowser.Model.Dto
@@ -72,6 +72,32 @@ namespace MediaBrowser.Model.Dto
             SupportsProbing = true;
         }
 
+        public void InferTotalBitrate()
+        {
+            if (Bitrate.HasValue || MediaStreams == null)
+            {
+                return;
+            }
+
+            var internalStreams = MediaStreams
+                .Where(i => !i.IsExternal)
+                .ToList();
+
+            if (internalStreams.Count == 0)
+            {
+                return;
+            }
+
+            var bitrate = internalStreams
+                .Select(m => m.BitRate ?? 0)
+                .Sum();
+
+            if (bitrate > 0)
+            {
+                Bitrate = bitrate;
+            }
+        }
+
         public int? DefaultAudioStreamIndex { get; set; }
         public int? DefaultSubtitleStreamIndex { get; set; }
 

+ 0 - 6
MediaBrowser.Model/System/SystemInfo.cs

@@ -16,12 +16,6 @@ namespace MediaBrowser.Model.System
         /// <value>The display name of the operating system.</value>
         public string OperatingSystemDisplayName { get; set; }
 
-        /// <summary>
-        /// Gets or sets a value indicating whether this instance is running as service.
-        /// </summary>
-        /// <value><c>true</c> if this instance is running as service; otherwise, <c>false</c>.</value>
-        public bool IsRunningAsService { get; set; }
-
         /// <summary>
         /// Gets or sets a value indicating whether [supports running as service].
         /// </summary>

+ 19 - 16
MediaBrowser.Providers/Manager/ProviderManager.cs

@@ -237,17 +237,17 @@ namespace MediaBrowser.Providers.Manager
             });
         }
 
-		public IEnumerable<IImageProvider> GetImageProviders(IHasImages item, ImageRefreshOptions refreshOptions)
+        public IEnumerable<IImageProvider> GetImageProviders(IHasImages item, ImageRefreshOptions refreshOptions)
         {
             return GetImageProviders(item, GetMetadataOptions(item), refreshOptions, false);
         }
 
-		private IEnumerable<IImageProvider> GetImageProviders(IHasImages item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
+        private IEnumerable<IImageProvider> GetImageProviders(IHasImages item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
         {
             // Avoid implicitly captured closure
             var currentOptions = options;
 
-			return ImageProviders.Where(i => CanRefresh(i, item, options, refreshOptions, includeDisabled))
+            return ImageProviders.Where(i => CanRefresh(i, item, options, refreshOptions, includeDisabled))
             .OrderBy(i =>
             {
                 // See if there's a user-defined order
@@ -291,7 +291,7 @@ namespace MediaBrowser.Providers.Manager
         {
             var options = GetMetadataOptions(item);
 
-			return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType<IRemoteImageProvider>();
+            return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType<IRemoteImageProvider>();
         }
 
         private bool CanRefresh(IMetadataProvider provider, IHasMetadata item, MetadataOptions options, bool includeDisabled, bool forceEnableInternetMetadata, bool checkIsOwnedItem)
@@ -335,17 +335,17 @@ namespace MediaBrowser.Providers.Manager
             return true;
         }
 
-		private bool CanRefresh(IImageProvider provider, IHasImages item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
+        private bool CanRefresh(IImageProvider provider, IHasImages item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
         {
             if (!includeDisabled)
             {
                 // If locked only allow local providers
                 if (item.IsLocked && !(provider is ILocalImageProvider))
                 {
-					if (refreshOptions.ImageRefreshMode != ImageRefreshMode.FullRefresh) 
-					{
-						return false;
-					}
+                    if (refreshOptions.ImageRefreshMode != ImageRefreshMode.FullRefresh)
+                    {
+                        return false;
+                    }
                 }
 
                 if (provider is IRemoteImageProvider || provider is IDynamicImageProvider)
@@ -481,7 +481,7 @@ namespace MediaBrowser.Providers.Manager
                 ItemType = typeof(T).Name
             };
 
-			var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList();
+            var imageProviders = GetImageProviders(dummy, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), true).ToList();
 
             AddMetadataPlugins(summary.Plugins, dummy, options);
             AddImagePlugins(summary.Plugins, dummy, imageProviders);
@@ -578,7 +578,7 @@ namespace MediaBrowser.Providers.Manager
             return SaveMetadata(item, updateType, _savers.Where(i => savers.Contains(i.Name, StringComparer.OrdinalIgnoreCase)));
         }
 
-        private readonly SemaphoreSlim _saveLock = new SemaphoreSlim(1,1);
+        private readonly SemaphoreSlim _saveLock = new SemaphoreSlim(1, 1);
         /// <summary>
         /// Saves the metadata.
         /// </summary>
@@ -958,11 +958,14 @@ namespace MediaBrowser.Providers.Manager
         {
             var cancellationToken = CancellationToken.None;
 
-            var albums = _libraryManagerFactory().RootFolder
-                                        .GetRecursiveChildren()
-                                        .OfType<MusicAlbum>()
-                                        .Where(i => i.HasAnyArtist(item.Name))
-                                        .ToList();
+            var albums = _libraryManagerFactory()
+                .GetItemList(new InternalItemsQuery
+                {
+                    IncludeItemTypes = new[] { typeof(MusicAlbum).Name },
+                    ArtistIds = new[] { item.Id.ToString("N") }
+                })
+                .OfType<MusicAlbum>()
+                .ToList();
 
             var musicArtists = albums
                 .Select(i => i.MusicArtist)

+ 2 - 0
MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs

@@ -115,6 +115,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
                     RequiresClosing = false
                 };
 
+                mediaSource.InferTotalBitrate();
+
                 return new List<MediaSourceInfo> { mediaSource };
             }
             return new List<MediaSourceInfo>();