diff --git a/Emby.Common.Implementations/BaseApplicationHost.cs b/Emby.Common.Implementations/BaseApplicationHost.cs
index 9c9e14ec6b..87b97863bd 100644
--- a/Emby.Common.Implementations/BaseApplicationHost.cs
+++ b/Emby.Common.Implementations/BaseApplicationHost.cs
@@ -161,12 +161,6 @@ namespace Emby.Common.Implementations
/// The name.
public abstract string Name { get; }
- ///
- /// Gets a value indicating whether this instance is running as service.
- ///
- /// true if this instance is running as service; otherwise, false.
- public abstract bool IsRunningAsService { get; }
-
protected ICryptoProvider CryptographyProvider = new CryptographyProvider();
protected IEnvironmentInfo EnvironmentInfo { get; private set; }
diff --git a/Emby.Dlna/Profiles/LgTvProfile.cs b/Emby.Dlna/Profiles/LgTvProfile.cs
index f7cf7b9a19..71f684ec48 100644
--- a/Emby.Dlna/Profiles/LgTvProfile.cs
+++ b/Emby.Dlna/Profiles/LgTvProfile.cs
@@ -67,7 +67,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "aac,ac3,mp3,dca,dts",
Type = DlnaProfileType.Video
@@ -203,7 +203,15 @@ namespace Emby.Dlna.Profiles
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
index 4a4ecdc589..2b31ab55f0 100644
--- a/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
+++ b/Emby.Dlna/Profiles/LinksysDMA2100Profile.cs
@@ -26,12 +26,20 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "avi,mp4,mkv,ts",
+ Container = "avi,mp4,mkv,ts,m4v",
Type = DlnaProfileType.Video
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
index f3d7f59512..63c7e3a8e0 100644
--- a/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
+++ b/Emby.Dlna/Profiles/PanasonicVieraProfile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264",
AudioCodec = "aac,ac3,mp3,pcm",
Type = DlnaProfileType.Video
@@ -208,6 +208,12 @@ namespace Emby.Dlna.Profiles
Container = "ts",
OrgPn = "MPEG_TS_SD_EU,MPEG_TS_SD_NA,MPEG_TS_SD_KO",
MimeType = "video/vnd.dlna.mpeg-tts"
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/PopcornHourProfile.cs b/Emby.Dlna/Profiles/PopcornHourProfile.cs
index 0095c80a28..d13b5c6ade 100644
--- a/Emby.Dlna/Profiles/PopcornHourProfile.cs
+++ b/Emby.Dlna/Profiles/PopcornHourProfile.cs
@@ -38,7 +38,7 @@ namespace Emby.Dlna.Profiles
{
new DirectPlayProfile
{
- Container = "mp4,mov",
+ Container = "mp4,mov,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "aac"
@@ -201,7 +201,15 @@ namespace Emby.Dlna.Profiles
}
};
- ResponseProfiles = new ResponseProfile[] { };
+ ResponseProfiles = new ResponseProfile[]
+ {
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
+ }
+ };
}
}
}
diff --git a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
index b86e6ba568..c582cb52e3 100644
--- a/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
+++ b/Emby.Dlna/Profiles/SamsungSmartTvProfile.cs
@@ -77,7 +77,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "mp3,aac",
Type = DlnaProfileType.Video
@@ -335,6 +335,12 @@ namespace Emby.Dlna.Profiles
Container = "flac",
MimeType = "audio/x-flac",
Type = DlnaProfileType.Audio
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
index d1305d4246..c67bd85b27 100644
--- a/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
+++ b/Emby.Dlna/Profiles/SonyBlurayPlayerProfile.cs
@@ -83,7 +83,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "avi,mp4",
+ Container = "avi,mp4,m4v",
VideoCodec = "mpeg4,h264",
AudioCodec = "ac3,aac,mp3,pcm",
Type = DlnaProfileType.Video
@@ -248,6 +248,13 @@ namespace Emby.Dlna.Profiles
Type = DlnaProfileType.Video
},
+ new ResponseProfile
+ {
+ Container = "m4v",
+ MimeType = "video/mpeg",
+ Type = DlnaProfileType.Video
+ },
+
new ResponseProfile
{
Container = "mpeg",
diff --git a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
index c21022aa3a..427820a332 100644
--- a/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2011Profile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp3",
Type = DlnaProfileType.Video
@@ -211,6 +211,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
index 1bbd40e914..206ca554c3 100644
--- a/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2012Profile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -199,6 +199,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
index 019bbafcb4..c618c9990a 100644
--- a/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2013Profile.cs
@@ -79,7 +79,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,eac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -255,6 +255,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
index 910786b839..c30bcfc853 100644
--- a/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
+++ b/Emby.Dlna/Profiles/SonyBravia2014Profile.cs
@@ -79,7 +79,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4",
+ Container = "mp4,m4v",
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,eac3,aac,mp3,mp2",
Type = DlnaProfileType.Video
@@ -255,6 +255,12 @@ namespace Emby.Dlna.Profiles
MimeType = "video/mpeg",
OrgPn="MPEG_PS_NTSC,MPEG_PS_PAL",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
diff --git a/Emby.Dlna/Profiles/SonyPs4Profile.cs b/Emby.Dlna/Profiles/SonyPs4Profile.cs
index bcb47486cc..8327331846 100644
--- a/Emby.Dlna/Profiles/SonyPs4Profile.cs
+++ b/Emby.Dlna/Profiles/SonyPs4Profile.cs
@@ -63,7 +63,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4,mkv",
+ Container = "mp4,mkv,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "aac,ac3"
@@ -255,6 +255,13 @@ namespace Emby.Dlna.Profiles
Container = "wav",
MimeType = "audio/wav",
Type = DlnaProfileType.Audio
+ },
+
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/WdtvLiveProfile.cs b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
index e524816afe..6cef2d9659 100644
--- a/Emby.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/Emby.Dlna/Profiles/WdtvLiveProfile.cs
@@ -87,7 +87,7 @@ namespace Emby.Dlna.Profiles
new DirectPlayProfile
{
- Container = "mp4,mov",
+ Container = "mp4,mov,m4v",
Type = DlnaProfileType.Video,
VideoCodec = "h264,mpeg4",
AudioCodec = "ac3,aac,mp2,mp3,dca,dts"
diff --git a/Emby.Dlna/Profiles/XboxOneProfile.cs b/Emby.Dlna/Profiles/XboxOneProfile.cs
index 370534a676..8994082ad5 100644
--- a/Emby.Dlna/Profiles/XboxOneProfile.cs
+++ b/Emby.Dlna/Profiles/XboxOneProfile.cs
@@ -80,7 +80,7 @@ namespace Emby.Dlna.Profiles
},
new DirectPlayProfile
{
- Container = "mp4,mov,mkv",
+ Container = "mp4,mov,mkv,m4v",
VideoCodec = "h264,mpeg4,mpeg2video",
AudioCodec = "aac,ac3",
Type = DlnaProfileType.Video
@@ -349,6 +349,12 @@ namespace Emby.Dlna.Profiles
Container = "avi",
MimeType = "video/avi",
Type = DlnaProfileType.Video
+ },
+ new ResponseProfile
+ {
+ Container = "m4v",
+ Type = DlnaProfileType.Video,
+ MimeType = "video/mp4"
}
};
}
diff --git a/Emby.Dlna/Profiles/Xml/LG Smart TV.xml b/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
index dc0e977720..2963e5f383 100644
--- a/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/Emby.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -37,7 +37,7 @@
-
+
@@ -79,7 +79,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml b/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
index 862bede9b4..c9ea6daff3 100644
--- a/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
+++ b/Emby.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -34,7 +34,7 @@
-
+
@@ -43,7 +43,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml b/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
index d7b142d84e..b520b2b53a 100644
--- a/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/Emby.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -41,7 +41,7 @@
-
+
@@ -76,6 +76,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml b/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
index 9bc4c2e312..9fa49e94a5 100644
--- a/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
+++ b/Emby.Dlna/Profiles/Xml/Popcorn Hour.xml
@@ -29,7 +29,7 @@
false
-
+
@@ -81,7 +81,11 @@
-
+
+
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml b/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
index 8729a59c19..a3acea8296 100644
--- a/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/Emby.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -40,7 +40,7 @@
-
+
@@ -117,6 +117,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
index 154d9a68f7..ee113ef630 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -41,7 +41,7 @@
-
+
@@ -99,6 +99,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index 39d7674a1e..3b234ac36e 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -41,7 +41,7 @@
-
+
@@ -129,6 +129,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index 8b6e88702e..4748b8d2ad 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -41,7 +41,7 @@
-
+
@@ -105,6 +105,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index e76ca2c771..d0ec30a26f 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -41,7 +41,7 @@
-
+
@@ -104,6 +104,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml b/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
index ff4aa9cf8e..ba83490b4b 100644
--- a/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
+++ b/Emby.Dlna/Profiles/Xml/Sony Bravia (2014).xml
@@ -41,7 +41,7 @@
-
+
@@ -104,6 +104,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml b/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
index d4eeaf80d0..22131a502c 100644
--- a/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
+++ b/Emby.Dlna/Profiles/Xml/Sony PlayStation 4.xml
@@ -40,7 +40,7 @@
-
+
@@ -98,6 +98,9 @@
+
+
+
diff --git a/Emby.Dlna/Profiles/Xml/WDTV Live.xml b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
index 96d37e7fb0..1cf3ef5973 100644
--- a/Emby.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/Emby.Dlna/Profiles/Xml/WDTV Live.xml
@@ -40,7 +40,7 @@
-
+
diff --git a/Emby.Dlna/Profiles/Xml/Xbox One.xml b/Emby.Dlna/Profiles/Xml/Xbox One.xml
index 8c13ed8fda..6289847ca4 100644
--- a/Emby.Dlna/Profiles/Xml/Xbox One.xml
+++ b/Emby.Dlna/Profiles/Xml/Xbox One.xml
@@ -39,7 +39,7 @@
-
+
@@ -116,6 +116,9 @@
+
+
+
diff --git a/Emby.Server.Core/ApplicationHost.cs b/Emby.Server.Core/ApplicationHost.cs
index 70ce2b0533..92914b932d 100644
--- a/Emby.Server.Core/ApplicationHost.cs
+++ b/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,
diff --git a/Emby.Server.Implementations/Data/SqliteItemRepository.cs b/Emby.Server.Implementations/Data/SqliteItemRepository.cs
index 6bec6dce38..c158f2e513 100644
--- a/Emby.Server.Implementations/Data/SqliteItemRepository.cs
+++ b/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("SimilarityScore", SortOrder.Descending));
orderBy.Add(new Tuple(ItemSortBy.Random, SortOrder.Ascending));
+ orderBy.Add(new Tuple("SimilarityScore", SortOrder.Descending));
+ //orderBy.Add(new Tuple(ItemSortBy.Random, SortOrder.Ascending));
query.SortOrder = SortOrder.Descending;
enableOrderInversion = false;
}
diff --git a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs b/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
index 021ae47ec3..4ab6d32f35 100644
--- a/Emby.Server.Implementations/EntryPoints/SystemEvents.cs
+++ b/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;
diff --git a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs b/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
index 1b897ca299..9fbe06673f 100644
--- a/Emby.Server.Implementations/EntryPoints/UsageEntryPoint.cs
+++ b/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
///
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 _apps = new ConcurrentDictionary();
- 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;
diff --git a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs b/Emby.Server.Implementations/EntryPoints/UsageReporter.cs
index be848acb77..31254c6c26 100644
--- a/Emby.Server.Implementations/EntryPoints/UsageReporter.cs
+++ b/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;
diff --git a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs b/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
index 5bb21d02ac..f841b8b6b2 100644
--- a/Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs
+++ b/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;
- }
-
- var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
- var resolver = new EpisodeResolver(namingOptions, new NullLogger());
-
- var episodeInfo = resolver.Resolve(path, false) ??
- new MediaBrowser.Naming.TV.EpisodeInfo();
-
- var seriesName = episodeInfo.SeriesName;
-
- if (!string.IsNullOrEmpty(seriesName))
- {
- var seasonNumber = episodeInfo.SeasonNumber;
-
- result.ExtractedSeasonNumber = seasonNumber;
-
- // Passing in true will include a few extra regex's
- var episodeNumber = episodeInfo.EpisodeNumber;
-
- result.ExtractedEpisodeNumber = episodeNumber;
-
- 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 (_libraryMonitor.IsPathLocked(path))
{
- if (episodeInfo.IsByDate)
+ 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 episodeInfo = resolver.Resolve(path, false) ??
+ new MediaBrowser.Naming.TV.EpisodeInfo();
+
+ var seriesName = episodeInfo.SeriesName;
+
+ if (!string.IsNullOrEmpty(seriesName))
+ {
+ var seasonNumber = episodeInfo.SeasonNumber;
+
+ result.ExtractedSeasonNumber = seasonNumber;
+
+ // Passing in true will include a few extra regex's
+ var episodeNumber = episodeInfo.EpisodeNumber;
+
+ result.ExtractedEpisodeNumber = episodeNumber;
+
+ var premiereDate = episodeInfo.IsByDate ?
+ new DateTime(episodeInfo.Year.Value, episodeInfo.Month.Value, episodeInfo.Day.Value) :
+ (DateTime?)null;
+
+ 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;
+ Series series = null;
- 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))
+ if (request.NewSeriesProviderIds.Count > 0)
{
- series.ProductionYear = year;
+ // 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;
+
+ int year;
+ if (int.TryParse(request.NewSeriesYear, out year))
+ {
+ series.ProductionYear = year;
+ }
+
+ var seriesFolderName = series.Name;
+ if (series.ProductionYear.HasValue)
+ {
+ seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
+ }
+
+ seriesFolderName = _fileSystem.GetValidFilename(seriesFolderName);
+
+ series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
+
+ series.ProviderIds = request.NewSeriesProviderIds;
+
+ await series.RefreshMetadata(refreshOptions, cancellationToken).ConfigureAwait(false);
}
- var seriesFolderName = series.Name;
- if (series.ProductionYear.HasValue)
+ if (series == null)
{
- seriesFolderName = string.Format("{0} ({1})", seriesFolderName, series.ProductionYear);
+ // Existing Series
+ series = (Series)_libraryManager.GetItemById(new Guid(request.SeriesId));
}
- series.Path = Path.Combine(request.TargetFolder, seriesFolderName);
+ await OrganizeEpisode(result.OriginalPath,
+ series,
+ request.SeasonNumber,
+ request.EpisodeNumber,
+ request.EndingEpisodeNumber,
+ null,
+ options,
+ true,
+ request.RememberCorrection,
+ result,
+ cancellationToken).ConfigureAwait(false);
- series.ProviderIds = request.NewSeriesProviderIds;
-
- await series.RefreshMetadata(refreshOptions, cancellationToken);
- }
-
- 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);
+ // 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)
- {
- if (options.TvOptions.CopyOriginalFile && fileExists && IsSameEpisode(sourcePath, newPath))
+ if (string.IsNullOrEmpty(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;
+ var msg = string.Format("Unable to sort {0} because target path could not be determined.", sourcePath);
+ throw new Exception(msg);
}
- if (fileExists)
+ _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)
{
- 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;
+ 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;
+ }
+
+ if (fileExists)
+ {
+ 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;
+ }
+
+ 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;
+ }
}
- if (otherDuplicatePaths.Count > 0)
+ PerformFileSorting(options.TvOptions, result);
+
+ if (overwriteExisting)
{
- 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;
- }
- }
+ var hasRenamedFiles = false;
- PerformFileSorting(options.TvOptions, result);
-
- if (overwriteExisting)
- {
- var hasRenamedFiles = false;
-
- foreach (var path in otherDuplicatePaths)
- {
- _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)
+ foreach (var path in otherDuplicatePaths)
{
- hasRenamedFiles = true;
- }
+ _logger.Debug("Removing duplicate episode {0}", path);
- try
- {
- DeleteLibraryFile(path, renameRelatedFiles, result.TargetPath);
- }
- catch (IOException ex)
- {
- _logger.ErrorException("Error removing duplicate episode", ex, path);
- }
- finally
- {
- _libraryMonitor.ReportFileSystemChangeComplete(path, true);
+ _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;
diff --git a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs b/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
index 500d4b69b1..4d19a0e9b8 100644
--- a/Emby.Server.Implementations/Intros/DefaultIntroProvider.cs
+++ b/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))
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 93c406ebca..c1bd8fe915 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/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);
}
diff --git a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index d3eb357507..f792d8b65f 100644
--- a/Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/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
{
stream
diff --git a/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs b/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs
index a338ae23ae..78390f0843 100644
--- a/Emby.Server.Implementations/LiveTv/LiveStreamHelper.cs
+++ b/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();
}
}
}
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs b/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
index b77ca3f413..ff76f6bef4 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/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))
{
diff --git a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index e0a35686ec..dd95660c78 100644
--- a/Emby.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/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)
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
index c2abf1d34f..485596050a 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs
+++ b/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;
}
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
index 4852270d5e..625e4457df 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
@@ -25,7 +25,6 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly TaskCompletionSource _liveStreamTaskCompletionSource = new TaskCompletionSource();
private readonly MulticastStream _multicastStream;
-
public HdHomerunLiveStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost)
: base(mediaSource)
{
diff --git a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index 449a4104fb..352f4fe958 100644
--- a/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -164,6 +164,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
IsRemote = true
};
+ mediaSource.InferTotalBitrate();
+
return new List { mediaSource };
}
return new List();
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index a2ec747be0..fcb8c34f3e 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -175,6 +175,15 @@ namespace MediaBrowser.Api.Playback
return ToOptimizedResult(info);
}
+ private T Clone(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(json);
+ }
+
private async Task 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");
}
diff --git a/MediaBrowser.Common/IApplicationHost.cs b/MediaBrowser.Common/IApplicationHost.cs
index 8353eccdde..35d6dca3da 100644
--- a/MediaBrowser.Common/IApplicationHost.cs
+++ b/MediaBrowser.Common/IApplicationHost.cs
@@ -36,12 +36,6 @@ namespace MediaBrowser.Common
///
event EventHandler> ApplicationUpdated;
- ///
- /// Gets a value indicating whether this instance is running as service.
- ///
- /// true if this instance is running as service; otherwise, false.
- bool IsRunningAsService { get; }
-
///
/// Gets or sets a value indicating whether this instance has pending kernel reload.
///
diff --git a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
index eda6ee1af3..ba20395d1b 100644
--- a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
+++ b/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;
}
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 3a6a7765b1..4cc6a7c7e9 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/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;
}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 23dfb802c0..4cfea4c70e 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -1337,6 +1337,11 @@ namespace MediaBrowser.Controller.Entities
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
+ if (string.IsNullOrWhiteSpace(lang))
+ {
+ lang = LibraryManager.GetLibraryOptions(this).PreferredMetadataLanguage;
+ }
+
if (string.IsNullOrWhiteSpace(lang))
{
lang = ConfigurationManager.Configuration.PreferredMetadataLanguage;
@@ -1367,6 +1372,11 @@ namespace MediaBrowser.Controller.Entities
.FirstOrDefault(i => !string.IsNullOrWhiteSpace(i));
}
+ if (string.IsNullOrWhiteSpace(lang))
+ {
+ lang = LibraryManager.GetLibraryOptions(this).MetadataCountryCode;
+ }
+
if (string.IsNullOrWhiteSpace(lang))
{
lang = ConfigurationManager.Configuration.MetadataCountryCode;
diff --git a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
index 5cb9b9cee6..9c5730d05c 100644
--- a/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
+++ b/MediaBrowser.Controller/Entities/InternalItemsQuery.cs
@@ -197,7 +197,7 @@ namespace MediaBrowser.Controller.Entities
public InternalItemsQuery()
{
- MinSimilarityScore = 1;
+ MinSimilarityScore = 20;
GroupByPresentationUniqueKey = true;
EnableTotalRecordCount = true;
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index 47df12e1b6..fb9c3d2134 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/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;
}
diff --git a/MediaBrowser.Controller/IServerApplicationHost.cs b/MediaBrowser.Controller/IServerApplicationHost.cs
index 44c0031974..86b52bd775 100644
--- a/MediaBrowser.Controller/IServerApplicationHost.cs
+++ b/MediaBrowser.Controller/IServerApplicationHost.cs
@@ -21,6 +21,12 @@ namespace MediaBrowser.Controller
/// SystemInfo.
Task GetSystemInfo();
+ ///
+ /// Gets a value indicating whether this instance is running as service.
+ ///
+ /// true if this instance is running as service; otherwise, false.
+ bool IsRunningAsService { get; }
+
///
/// Gets a value indicating whether [supports automatic run at startup].
///
diff --git a/MediaBrowser.Model/Configuration/LibraryOptions.cs b/MediaBrowser.Model/Configuration/LibraryOptions.cs
index 8e344f76e6..24bc5dd117 100644
--- a/MediaBrowser.Model/Configuration/LibraryOptions.cs
+++ b/MediaBrowser.Model/Configuration/LibraryOptions.cs
@@ -15,6 +15,18 @@
public bool ImportMissingEpisodes { get; set; }
public bool EnableAutomaticSeriesGrouping { get; set; }
+ ///
+ /// Gets or sets the preferred metadata language.
+ ///
+ /// The preferred metadata language.
+ public string PreferredMetadataLanguage { get; set; }
+
+ ///
+ /// Gets or sets the metadata country code.
+ ///
+ /// The metadata country code.
+ public string MetadataCountryCode { get; set; }
+
public LibraryOptions()
{
EnablePhotos = true;
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index 4f93f476f3..250cbeb107 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/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; }
diff --git a/MediaBrowser.Model/System/SystemInfo.cs b/MediaBrowser.Model/System/SystemInfo.cs
index 6145c7b61f..4154093cba 100644
--- a/MediaBrowser.Model/System/SystemInfo.cs
+++ b/MediaBrowser.Model/System/SystemInfo.cs
@@ -16,12 +16,6 @@ namespace MediaBrowser.Model.System
/// The display name of the operating system.
public string OperatingSystemDisplayName { get; set; }
- ///
- /// Gets or sets a value indicating whether this instance is running as service.
- ///
- /// true if this instance is running as service; otherwise, false.
- public bool IsRunningAsService { get; set; }
-
///
/// Gets or sets a value indicating whether [supports running as service].
///
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index 4eab20e7ec..003e7b9fad 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -237,17 +237,17 @@ namespace MediaBrowser.Providers.Manager
});
}
- public IEnumerable GetImageProviders(IHasImages item, ImageRefreshOptions refreshOptions)
+ public IEnumerable GetImageProviders(IHasImages item, ImageRefreshOptions refreshOptions)
{
return GetImageProviders(item, GetMetadataOptions(item), refreshOptions, false);
}
- private IEnumerable GetImageProviders(IHasImages item, MetadataOptions options, ImageRefreshOptions refreshOptions, bool includeDisabled)
+ private IEnumerable 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();
+ return GetImageProviders(item, options, new ImageRefreshOptions(new DirectoryService(_logger, _fileSystem)), includeDisabled).OfType();
}
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);
///
/// Saves the metadata.
///
@@ -958,11 +958,14 @@ namespace MediaBrowser.Providers.Manager
{
var cancellationToken = CancellationToken.None;
- var albums = _libraryManagerFactory().RootFolder
- .GetRecursiveChildren()
- .OfType()
- .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()
+ .ToList();
var musicArtists = albums
.Select(i => i.MusicArtist)
diff --git a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
index 55101ce10f..5f0f28257f 100644
--- a/MediaBrowser.Server.Startup.Common/LiveTv/TunerHosts/SatIp/SatIpHost.cs
+++ b/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 { mediaSource };
}
return new List();
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index b238e1d8a0..e38d30dd9a 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -972,9 +972,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -1074,11 +1071,6 @@
PreserveNewest
-
-
- PreserveNewest
-
-
PreserveNewest
@@ -1175,11 +1167,6 @@
PreserveNewest
-
-
- PreserveNewest
-
-
PreserveNewest
@@ -1231,6 +1218,9 @@
+
+ PreserveNewest
+
PreserveNewest