diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index 16e8a434a1..78aa5e1657 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -245,12 +245,8 @@ namespace MediaBrowser.Api
item.OriginalTitle = string.IsNullOrWhiteSpace(request.OriginalTitle) ? null : request.OriginalTitle;
- var hasCriticRating = item as IHasCriticRating;
- if (hasCriticRating != null)
- {
- hasCriticRating.CriticRating = request.CriticRating;
- hasCriticRating.CriticRatingSummary = request.CriticRatingSummary;
- }
+ item.CriticRating = request.CriticRating;
+ item.CriticRatingSummary = request.CriticRatingSummary;
item.DisplayMediaType = request.DisplayMediaType;
item.CommunityRating = request.CommunityRating;
@@ -279,11 +275,7 @@ namespace MediaBrowser.Api
item.Tagline = request.Taglines.FirstOrDefault();
}
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null)
- {
- hasShortOverview.ShortOverview = request.ShortOverview;
- }
+ item.ShortOverview = request.ShortOverview;
item.Keywords = request.Keywords;
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index 4217cd6abe..90767b135b 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -19,6 +19,7 @@ using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Api.Playback.Progressive;
using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Server.Implementations.LiveTv.EmbyTV;
namespace MediaBrowser.Api.LiveTv
@@ -390,6 +391,7 @@ namespace MediaBrowser.Api.LiveTv
public bool? EnableUserData { get; set; }
public string SeriesTimerId { get; set; }
+ public string LibrarySeriesId { get; set; }
///
/// Fields to return within the items, in addition to basic information
@@ -990,6 +992,17 @@ namespace MediaBrowser.Api.LiveTv
query.SeriesTimerId = request.SeriesTimerId;
query.Genres = (request.Genres ?? String.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries);
+ if (!string.IsNullOrWhiteSpace(request.LibrarySeriesId))
+ {
+ query.IsSeries = true;
+
+ var series = _libraryManager.GetItemById(request.LibrarySeriesId) as Series;
+ if (series != null)
+ {
+ query.Name = series.Name;
+ }
+ }
+
var result = await _liveTvManager.GetPrograms(query, GetDtoOptions(request), CancellationToken.None).ConfigureAwait(false);
return ToOptimizedResult(result);
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index eb80ae89e6..dc26218a52 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -317,13 +317,32 @@ namespace MediaBrowser.Api.Playback
}
if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(encodingOptions.VaapiDevice))
{
- return GetAvailableEncoder("h264_vaapi", defaultEncoder);
+ if (IsVaapiSupported(state))
+ {
+ return GetAvailableEncoder("h264_vaapi", defaultEncoder);
+ }
}
}
return defaultEncoder;
}
+ private bool IsVaapiSupported(StreamState state)
+ {
+ var videoStream = state.VideoStream;
+
+ if (videoStream != null)
+ {
+ // vaapi will throw an error with this input
+ // [vaapi @ 0x7faed8000960] No VAAPI support for codec mpeg4 profile -99.
+ if (string.Equals(videoStream.Codec, "mpeg4", StringComparison.OrdinalIgnoreCase) && videoStream.Level == -99)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
private string GetAvailableEncoder(string preferredEncoder, string defaultEncoder)
{
if (MediaEncoder.SupportsEncoder(preferredEncoder))
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 270b068fd1..97b386d73b 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -887,7 +887,6 @@ namespace MediaBrowser.Api.Playback.Hls
var mapArgs = state.IsOutputVideo ? GetMapArgs(state) : string.Empty;
var enableSplittingOnNonKeyFrames = state.VideoRequest.EnableSplittingOnNonKeyFrames && string.Equals(state.OutputVideoCodec, "copy", StringComparison.OrdinalIgnoreCase);
enableSplittingOnNonKeyFrames = false;
-
// TODO: check libavformat version for 57 50.100 and use -hls_flags split_by_time
var hlsProtocolSupportsSplittingByTime = false;
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index 7fe7d5a21d..0611adea5f 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -125,7 +125,7 @@ namespace MediaBrowser.Api.Playback
SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate,
request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex,
- request.SubtitleStreamIndex, request.PlaySessionId, request.UserId);
+ request.SubtitleStreamIndex, request.MaxAudioChannels, request.PlaySessionId, request.UserId);
}
else
{
@@ -167,7 +167,7 @@ namespace MediaBrowser.Api.Playback
{
var mediaSourceId = request.MediaSourceId;
- SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.UserId);
+ SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.MaxAudioChannels, request.UserId);
}
return ToOptimizedResult(info);
@@ -230,13 +230,14 @@ namespace MediaBrowser.Api.Playback
string mediaSourceId,
int? audioStreamIndex,
int? subtitleStreamIndex,
+ int? maxAudioChannels,
string userId)
{
var item = _libraryManager.GetItemById(itemId);
foreach (var mediaSource in result.MediaSources)
{
- SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId, userId);
+ SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, maxAudioChannels, result.PlaySessionId, userId);
}
SortMediaSources(result, maxBitrate);
@@ -251,6 +252,7 @@ namespace MediaBrowser.Api.Playback
string mediaSourceId,
int? audioStreamIndex,
int? subtitleStreamIndex,
+ int? maxAudioChannels,
string playSessionId,
string userId)
{
@@ -262,7 +264,8 @@ namespace MediaBrowser.Api.Playback
Context = EncodingContext.Streaming,
DeviceId = auth.DeviceId,
ItemId = item.Id.ToString("N"),
- Profile = profile
+ Profile = profile,
+ MaxAudioChannels = maxAudioChannels
};
if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase))
diff --git a/MediaBrowser.Common.Implementations/Logging/NLogger.cs b/MediaBrowser.Common.Implementations/Logging/NLogger.cs
index 97bc437a0f..11f41261a2 100644
--- a/MediaBrowser.Common.Implementations/Logging/NLogger.cs
+++ b/MediaBrowser.Common.Implementations/Logging/NLogger.cs
@@ -127,7 +127,9 @@ namespace MediaBrowser.Common.Implementations.Logging
{
for (var i = 0; i < paramList.Length; i++)
{
- message = message.Replace("{" + i + "}", paramList[i].ToString());
+ var obj = paramList[i];
+
+ message = message.Replace("{" + i + "}", (obj == null ? "null" : obj.ToString()));
}
}
diff --git a/MediaBrowser.Controller/Dlna/ISsdpHandler.cs b/MediaBrowser.Controller/Dlna/ISsdpHandler.cs
deleted file mode 100644
index ec3a00aad7..0000000000
--- a/MediaBrowser.Controller/Dlna/ISsdpHandler.cs
+++ /dev/null
@@ -1,8 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Dlna
-{
- public interface ISsdpHandler
- {
- }
-}
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3ebefa2170..e1a7741c94 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -33,7 +33,7 @@ namespace MediaBrowser.Controller.Entities
///
/// Class BaseItem
///
- public abstract class BaseItem : IHasProviderIds, ILibraryItem, IHasImages, IHasUserData, IHasMetadata, IHasLookupInfo
+ public abstract class BaseItem : IHasProviderIds, IHasImages, IHasUserData, IHasMetadata, IHasLookupInfo
{
protected BaseItem()
{
diff --git a/MediaBrowser.Controller/Entities/BasePluginFolder.cs b/MediaBrowser.Controller/Entities/BasePluginFolder.cs
index 5a1ad6b157..bd109af7a7 100644
--- a/MediaBrowser.Controller/Entities/BasePluginFolder.cs
+++ b/MediaBrowser.Controller/Entities/BasePluginFolder.cs
@@ -7,7 +7,7 @@ namespace MediaBrowser.Controller.Entities
/// Plugins derive from and export this class to create a folder that will appear in the root along
/// with all the other actual physical folders in the system.
///
- public abstract class BasePluginFolder : Folder, ICollectionFolder, IByReferenceItem
+ public abstract class BasePluginFolder : Folder, ICollectionFolder
{
public virtual string CollectionType
{
diff --git a/MediaBrowser.Controller/Entities/IByReferenceItem.cs b/MediaBrowser.Controller/Entities/IByReferenceItem.cs
deleted file mode 100644
index b071473e11..0000000000
--- a/MediaBrowser.Controller/Entities/IByReferenceItem.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- ///
- /// This is a marker class that tells us that a particular item type may be physically resolved
- /// more than once within the library and we need to be sure to resolve them all to the same
- /// instance of that item.
- ///
- public interface IByReferenceItem
- {
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasCriticRating.cs b/MediaBrowser.Controller/Entities/IHasCriticRating.cs
deleted file mode 100644
index d2b93759d8..0000000000
--- a/MediaBrowser.Controller/Entities/IHasCriticRating.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-namespace MediaBrowser.Controller.Entities
-{
- ///
- /// Interface IHasCriticRating
- ///
- public interface IHasCriticRating
- {
- ///
- /// Gets or sets the critic rating.
- ///
- /// The critic rating.
- float? CriticRating { get; set; }
-
- ///
- /// Gets or sets the critic rating summary.
- ///
- /// The critic rating summary.
- string CriticRatingSummary { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/IHasShortOverview.cs b/MediaBrowser.Controller/Entities/IHasShortOverview.cs
deleted file mode 100644
index 437201faaf..0000000000
--- a/MediaBrowser.Controller/Entities/IHasShortOverview.cs
+++ /dev/null
@@ -1,12 +0,0 @@
-
-namespace MediaBrowser.Controller.Entities
-{
- public interface IHasShortOverview
- {
- ///
- /// Gets or sets the short overview.
- ///
- /// The short overview.
- string ShortOverview { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ILibraryItem.cs b/MediaBrowser.Controller/Entities/ILibraryItem.cs
deleted file mode 100644
index b2f39608f3..0000000000
--- a/MediaBrowser.Controller/Entities/ILibraryItem.cs
+++ /dev/null
@@ -1,28 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
- ///
- /// Interface ILibraryItem
- ///
- public interface ILibraryItem
- {
- ///
- /// Gets the name.
- ///
- /// The name.
- string Name { get; }
-
- ///
- /// Gets the id.
- ///
- /// The id.
- Guid Id { get; }
-
- ///
- /// Gets the path.
- ///
- /// The path.
- string Path { get; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/ImageSourceInfo.cs b/MediaBrowser.Controller/Entities/ImageSourceInfo.cs
deleted file mode 100644
index 6dc072431c..0000000000
--- a/MediaBrowser.Controller/Entities/ImageSourceInfo.cs
+++ /dev/null
@@ -1,10 +0,0 @@
-using System;
-
-namespace MediaBrowser.Controller.Entities
-{
- public class ImageSourceInfo
- {
- public Guid ImagePathMD5 { get; set; }
- public Guid ImageUrlMD5 { get; set; }
- }
-}
diff --git a/MediaBrowser.Controller/Entities/Movies/Movie.cs b/MediaBrowser.Controller/Entities/Movies/Movie.cs
index dea42c463a..f13adb21c7 100644
--- a/MediaBrowser.Controller/Entities/Movies/Movie.cs
+++ b/MediaBrowser.Controller/Entities/Movies/Movie.cs
@@ -15,7 +15,7 @@ namespace MediaBrowser.Controller.Entities.Movies
///
/// Class Movie
///
- public class Movie : Video, IHasCriticRating, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle
+ public class Movie : Video, IHasSpecialFeatures, IHasBudget, IHasTrailers, IHasAwards, IHasMetascore, IHasLookupInfo, ISupportsBoxSetGrouping, IHasOriginalTitle
{
public List SpecialFeatureIds { get; set; }
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index 62af141593..ce13f5fc5f 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -36,7 +36,7 @@ namespace MediaBrowser.Controller.Entities.TV
{
get
{
- return true;
+ return false;
}
}
diff --git a/MediaBrowser.Controller/Entities/Trailer.cs b/MediaBrowser.Controller/Entities/Trailer.cs
index 0bcd5c14e8..0780cfec5e 100644
--- a/MediaBrowser.Controller/Entities/Trailer.cs
+++ b/MediaBrowser.Controller/Entities/Trailer.cs
@@ -10,7 +10,7 @@ namespace MediaBrowser.Controller.Entities
///
/// Class Trailer
///
- public class Trailer : Video, IHasCriticRating, IHasBudget, IHasMetascore, IHasOriginalTitle, IHasLookupInfo
+ public class Trailer : Video, IHasBudget, IHasMetascore, IHasOriginalTitle, IHasLookupInfo
{
public Trailer()
{
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index 3b7e3c5d29..38397572e3 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -1668,16 +1668,7 @@ namespace MediaBrowser.Controller.Entities
{
var val = query.MinCriticRating.Value;
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null)
- {
- if (!(hasCriticRating.CriticRating.HasValue && hasCriticRating.CriticRating >= val))
- {
- return false;
- }
- }
- else
+ if (!(item.CriticRating.HasValue && item.CriticRating >= val))
{
return false;
}
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index e87b726b23..78d7a7fdd9 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -24,7 +24,6 @@ namespace MediaBrowser.Controller.Entities
IHasAspectRatio,
ISupportsPlaceHolders,
IHasMediaSources,
- IHasShortOverview,
IThemeMedia
{
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
index 610d4b6f8a..5e99d6fa3f 100644
--- a/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
+++ b/MediaBrowser.Controller/LiveTv/LiveTvChannel.cs
@@ -78,14 +78,17 @@ namespace MediaBrowser.Controller.LiveTv
protected override string CreateSortName()
{
- double number = 0;
-
if (!string.IsNullOrEmpty(Number))
{
- double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number);
+ double number = 0;
+
+ if (double.TryParse(Number, NumberStyles.Any, CultureInfo.InvariantCulture, out number))
+ {
+ return number.ToString("00000-") + (Name ?? string.Empty);
+ }
}
- return number.ToString("00000-") + (Name ?? string.Empty);
+ return Number + "-" + (Name ?? string.Empty);
}
[IgnoreDataMember]
diff --git a/MediaBrowser.Controller/MediaBrowser.Controller.csproj b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
index 11ed0f6741..36d59d3e44 100644
--- a/MediaBrowser.Controller/MediaBrowser.Controller.csproj
+++ b/MediaBrowser.Controller/MediaBrowser.Controller.csproj
@@ -111,7 +111,6 @@
-
@@ -132,10 +131,8 @@
-
-
@@ -146,15 +143,12 @@
-
-
-
diff --git a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
index 13d43eee67..931af293cc 100644
--- a/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
+++ b/MediaBrowser.Controller/Providers/BaseItemXmlParser.cs
@@ -185,14 +185,12 @@ namespace MediaBrowser.Controller.Providers
{
var text = reader.ReadElementContentAsString();
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null && !string.IsNullOrEmpty(text))
+ if (!string.IsNullOrEmpty(text))
{
float value;
if (float.TryParse(text, NumberStyles.Any, _usCulture, out value))
{
- hasCriticRating.CriticRating = value;
+ item.CriticRating = value;
}
}
@@ -292,12 +290,7 @@ namespace MediaBrowser.Controller.Providers
if (!string.IsNullOrWhiteSpace(val))
{
- var hasShortOverview = item as IHasShortOverview;
-
- if (hasShortOverview != null)
- {
- hasShortOverview.ShortOverview = val;
- }
+ item.ShortOverview = val;
}
break;
@@ -309,12 +302,7 @@ namespace MediaBrowser.Controller.Providers
if (!string.IsNullOrWhiteSpace(val))
{
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null)
- {
- hasCriticRating.CriticRatingSummary = val;
- }
+ item.CriticRatingSummary = val;
}
break;
diff --git a/MediaBrowser.Controller/Providers/DynamicImageResponse.cs b/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
index fdd1891ed6..d19a28a24c 100644
--- a/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
+++ b/MediaBrowser.Controller/Providers/DynamicImageResponse.cs
@@ -12,7 +12,6 @@ namespace MediaBrowser.Controller.Providers
public Stream Stream { get; set; }
public ImageFormat Format { get; set; }
public bool HasImage { get; set; }
- public string InternalCacheKey { get; set; }
public void SetFormatFromMimeType(string mimeType)
{
diff --git a/MediaBrowser.Controller/Providers/IProviderManager.cs b/MediaBrowser.Controller/Providers/IProviderManager.cs
index d3e5685bb1..428651ed5b 100644
--- a/MediaBrowser.Controller/Providers/IProviderManager.cs
+++ b/MediaBrowser.Controller/Providers/IProviderManager.cs
@@ -69,28 +69,8 @@ namespace MediaBrowser.Controller.Providers
///
/// Saves the image.
///
- /// The item.
- /// The source.
- /// Type of the MIME.
- /// The type.
- /// Index of the image.
- /// The internal cache key.
- /// The cancellation token.
/// Task.
- Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken);
-
- ///
- /// Saves the image.
- ///
- /// The item.
- /// The source.
- /// Type of the MIME.
- /// The type.
- /// Index of the image.
- /// The internal cache key.
- /// The cancellation token.
- /// Task.
- Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken);
+ Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken);
///
/// Adds the metadata providers.
diff --git a/MediaBrowser.Dlna/Didl/DidlBuilder.cs b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
index f53dec3bff..a5091bf01e 100644
--- a/MediaBrowser.Dlna/Didl/DidlBuilder.cs
+++ b/MediaBrowser.Dlna/Didl/DidlBuilder.cs
@@ -585,10 +585,9 @@ namespace MediaBrowser.Dlna.Didl
{
var desc = item.Overview;
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null && !string.IsNullOrEmpty(hasShortOverview.ShortOverview))
+ if (!string.IsNullOrEmpty(item.ShortOverview))
{
- desc = hasShortOverview.ShortOverview;
+ desc = item.ShortOverview;
}
if (!string.IsNullOrWhiteSpace(desc))
@@ -697,16 +696,36 @@ namespace MediaBrowser.Dlna.Didl
private void AddPeople(BaseItem item, XmlElement element)
{
- var types = new[] { PersonType.Director, PersonType.Writer, PersonType.Producer, PersonType.Composer, "Creator" };
+ var types = new[]
+ {
+ PersonType.Director,
+ PersonType.Writer,
+ PersonType.Producer,
+ PersonType.Composer,
+ "Creator"
+ };
var people = _libraryManager.GetPeople(item);
+ var index = 0;
+
+ // Seeing some LG models locking up due content with large lists of people
+ // The actual issue might just be due to processing a more metadata than it can handle
+ var limit = 10;
+
foreach (var actor in people)
{
var type = types.FirstOrDefault(i => string.Equals(i, actor.Type, StringComparison.OrdinalIgnoreCase) || string.Equals(i, actor.Role, StringComparison.OrdinalIgnoreCase))
?? PersonType.Actor;
AddValue(element, "upnp", type.ToLower(), actor.Name, NS_UPNP);
+
+ index++;
+
+ if (index >= limit)
+ {
+ break;
+ }
}
}
diff --git a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
index a8aedaed87..277f80b478 100644
--- a/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
+++ b/MediaBrowser.Dlna/Main/DlnaEntryPoint.cs
@@ -19,6 +19,7 @@ using System.Net;
using System.Threading.Tasks;
using MediaBrowser.Controller.MediaEncoding;
using Rssdp;
+using Rssdp.Infrastructure;
namespace MediaBrowser.Dlna.Main
{
@@ -154,8 +155,14 @@ namespace MediaBrowser.Dlna.Main
}
}
+ private void LogMessage(string msg)
+ {
+ //_logger.Debug(msg);
+ }
+
private void StartPublishing()
{
+ SsdpDevicePublisherBase.LogFunction = LogMessage;
_Publisher = new SsdpDevicePublisher();
}
@@ -235,48 +242,71 @@ namespace MediaBrowser.Dlna.Main
var addressString = address.ToString();
- var udn = (addressString).GetMD5().ToString("N");
+ var udn = CreateUuid(addressString);
- var services = new List
+ var fullService = "urn:schemas-upnp-org:device:MediaServer:1";
+
+ _logger.Info("Registering publisher for {0} on {1}", fullService, addressString);
+
+ var descriptorUri = "/dlna/" + udn + "/description.xml";
+ var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorUri);
+
+ var device = new SsdpRootDevice
+ {
+ CacheLifetime = TimeSpan.FromSeconds(cacheLength), //How long SSDP clients can cache this info.
+ Location = uri, // Must point to the URL that serves your devices UPnP description document.
+ FriendlyName = "Emby Server",
+ Manufacturer = "Emby",
+ ModelName = "Emby Server",
+ Uuid = udn
+ // This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
+ };
+
+ SetProperies(device, fullService);
+ _Publisher.AddDevice(device);
+
+ var embeddedDevices = new List
{
- "urn:schemas-upnp-org:device:MediaServer:1",
"urn:schemas-upnp-org:service:ContentDirectory:1",
"urn:schemas-upnp-org:service:ConnectionManager:1",
"urn:microsoft.com:service:X_MS_MediaReceiverRegistrar:1"
};
- foreach (var fullService in services)
+ foreach (var subDevice in embeddedDevices)
{
- _logger.Info("Registering publisher for {0} on {1}", fullService, addressString);
-
- var descriptorURI = "/dlna/" + udn + "/description.xml";
- var uri = new Uri(_appHost.GetLocalApiUrl(address) + descriptorURI);
-
- var service = fullService.Replace("urn:", string.Empty).Replace(":1", string.Empty);
-
- var serviceParts = service.Split(':');
-
- var deviceTypeNamespace = serviceParts[0].Replace('.', '-');
-
- var device = new SsdpRootDevice
+ var embeddedDevice = new SsdpEmbeddedDevice
{
- CacheLifetime = TimeSpan.FromSeconds(cacheLength), //How long SSDP clients can cache this info.
- Location = uri, // Must point to the URL that serves your devices UPnP description document.
- DeviceTypeNamespace = deviceTypeNamespace,
- DeviceClass = serviceParts[1],
- DeviceType = serviceParts[2],
- FriendlyName = "Emby Server",
- Manufacturer = "Emby",
- ModelName = "Emby Server",
+ FriendlyName = device.FriendlyName,
+ Manufacturer = device.Manufacturer,
+ ModelName = device.ModelName,
Uuid = udn
// This must be a globally unique value that survives reboots etc. Get from storage or embedded hardware etc.
};
- _Publisher.AddDevice(device);
+ SetProperies(embeddedDevice, subDevice);
+ device.AddDevice(embeddedDevice);
}
}
}
+ private string CreateUuid(string text)
+ {
+ return text.GetMD5().ToString("N");
+ }
+
+ private void SetProperies(SsdpDevice device, string fullDeviceType)
+ {
+ var service = fullDeviceType.Replace("urn:", string.Empty).Replace(":1", string.Empty);
+
+ var serviceParts = service.Split(':');
+
+ var deviceTypeNamespace = serviceParts[0].Replace('.', '-');
+
+ device.DeviceTypeNamespace = deviceTypeNamespace;
+ device.DeviceClass = serviceParts[1];
+ device.DeviceType = serviceParts[2];
+ }
+
private readonly object _syncLock = new object();
private void StartPlayToManager()
{
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index ef60be227f..ebffe6c575 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -108,7 +108,6 @@
-
@@ -130,7 +129,6 @@
-
@@ -160,8 +158,6 @@
-
-
diff --git a/MediaBrowser.Dlna/Ssdp/Datagram.cs b/MediaBrowser.Dlna/Ssdp/Datagram.cs
deleted file mode 100644
index 5901945344..0000000000
--- a/MediaBrowser.Dlna/Ssdp/Datagram.cs
+++ /dev/null
@@ -1,126 +0,0 @@
-using MediaBrowser.Model.Logging;
-using System;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
- public class Datagram
- {
- public EndPoint ToEndPoint { get; private set; }
- public EndPoint FromEndPoint { get; private set; }
- public string Message { get; private set; }
- public bool IsBroadcast { get; private set; }
- public bool EnableDebugLogging { get; private set; }
-
- private readonly ILogger _logger;
-
- public Datagram(EndPoint toEndPoint, EndPoint fromEndPoint, ILogger logger, string message, bool isBroadcast, bool enableDebugLogging)
- {
- Message = message;
- _logger = logger;
- EnableDebugLogging = enableDebugLogging;
- IsBroadcast = isBroadcast;
- FromEndPoint = fromEndPoint;
- ToEndPoint = toEndPoint;
- }
-
- public void Send()
- {
- var msg = Encoding.ASCII.GetBytes(Message);
-
- var socket = CreateSocket();
-
- if (socket == null)
- {
- return;
- }
-
- if (FromEndPoint != null)
- {
- try
- {
- socket.Bind(FromEndPoint);
- }
- catch (Exception ex)
- {
- if (EnableDebugLogging)
- {
- _logger.ErrorException("Error binding datagram socket", ex);
- }
-
- if (IsBroadcast)
- {
- CloseSocket(socket, false);
- return;
- }
- }
- }
-
- try
- {
- socket.BeginSendTo(msg, 0, msg.Length, SocketFlags.None, ToEndPoint, result =>
- {
- try
- {
- socket.EndSend(result);
- }
- catch (Exception ex)
- {
- if (EnableDebugLogging)
- {
- _logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString());
- }
- }
- finally
- {
- CloseSocket(socket, true);
- }
- }, null);
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString());
- CloseSocket(socket, false);
- }
- }
-
- private void CloseSocket(Socket socket, bool logError)
- {
- try
- {
- socket.Close();
- }
- catch (Exception ex)
- {
- if (logError && EnableDebugLogging)
- {
- _logger.ErrorException("Error closing datagram socket", ex);
- }
- }
- }
-
- private Socket CreateSocket()
- {
- try
- {
- var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
-
- if (IsBroadcast)
- {
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
- }
-
- return socket;
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error creating socket", ex);
- return null;
- }
- }
- }
-}
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscoveryInfo.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscoveryInfo.cs
deleted file mode 100644
index e9de45522b..0000000000
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscoveryInfo.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using MediaBrowser.Dlna.PlayTo;
-using System;
-using System.Net;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
- public class DeviceDiscoveryInfo
- {
- public Device Device { get; set; }
-
- ///
- /// The server's ip address that the device responded to
- ///
- public IPAddress LocalIpAddress { get; set; }
-
- public Uri Uri { get; set; }
-
- public string Usn { get; set; }
- public string Nt { get; set; }
- }
-}
diff --git a/MediaBrowser.Dlna/Ssdp/Extensions.cs b/MediaBrowser.Dlna/Ssdp/Extensions.cs
index 12589e80fe..17ebcc7ead 100644
--- a/MediaBrowser.Dlna/Ssdp/Extensions.cs
+++ b/MediaBrowser.Dlna/Ssdp/Extensions.cs
@@ -9,30 +9,6 @@ namespace MediaBrowser.Dlna.Ssdp
{
public static class Extensions
{
- public static Task ReceiveAsync(this Socket socket, byte[] buffer, int offset, int size)
- {
- var tcs = new TaskCompletionSource(socket);
- var remoteip = new IPEndPoint(IPAddress.Any, 0);
- var endpoint = (EndPoint)remoteip;
-
- socket.BeginReceiveFrom(buffer, offset, size, SocketFlags.None, ref endpoint, iar =>
- {
- var result = (TaskCompletionSource)iar.AsyncState;
- var iarSocket = (Socket)result.Task.AsyncState;
-
- try
- {
- result.TrySetResult(iarSocket.EndReceive(iar));
- }
- catch (Exception exc)
- {
- result.TrySetException(exc);
- }
- }, tcs);
-
- return tcs.Task;
- }
-
public static string GetValue(this XElement container, XName name)
{
var node = container.Element(name);
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
deleted file mode 100644
index 0d0ca98a28..0000000000
--- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
+++ /dev/null
@@ -1,328 +0,0 @@
-using MediaBrowser.Common;
-using MediaBrowser.Common.Configuration;
-using MediaBrowser.Common.Events;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Dlna;
-using MediaBrowser.Dlna.Server;
-using MediaBrowser.Model.Logging;
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.Linq;
-using System.Net;
-using System.Net.Sockets;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Microsoft.Win32;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
- public class SsdpHandler : IDisposable, ISsdpHandler
- {
- private Socket _multicastSocket;
-
- private readonly ILogger _logger;
- private readonly IServerConfigurationManager _config;
-
- const string SSDPAddr = "239.255.255.250";
- const int SSDPPort = 1900;
- private readonly string _serverSignature;
-
- private readonly IPAddress _ssdpIp = IPAddress.Parse(SSDPAddr);
- private readonly IPEndPoint _ssdpEndp = new IPEndPoint(IPAddress.Parse(SSDPAddr), SSDPPort);
-
- private Timer _notificationTimer;
-
- private bool _isDisposed;
- private readonly Dictionary> _devices = new Dictionary>();
-
- private readonly IApplicationHost _appHost;
-
- private readonly int _unicastPort = 1901;
- private UdpClient _unicastClient;
-
- public SsdpHandler(ILogger logger, IServerConfigurationManager config, IApplicationHost appHost)
- {
- _logger = logger;
- _config = config;
- _appHost = appHost;
-
- _config.NamedConfigurationUpdated += _config_ConfigurationUpdated;
- _serverSignature = GenerateServerSignature();
- }
-
- private string GenerateServerSignature()
- {
- var os = Environment.OSVersion;
- var pstring = os.Platform.ToString();
- switch (os.Platform)
- {
- case PlatformID.Win32NT:
- case PlatformID.Win32S:
- case PlatformID.Win32Windows:
- pstring = "WIN";
- break;
- }
-
- return String.Format(
- "{0}{1}/{2}.{3} UPnP/1.0 DLNADOC/1.5 Emby/{4}",
- pstring,
- IntPtr.Size * 8,
- os.Version.Major,
- os.Version.Minor,
- _appHost.ApplicationVersion
- );
- }
-
- void _config_ConfigurationUpdated(object sender, ConfigurationUpdateEventArgs e)
- {
- if (string.Equals(e.Key, "dlna", StringComparison.OrdinalIgnoreCase))
- {
- ReloadAliveNotifier();
- }
- }
-
- public IEnumerable RegisteredDevices
- {
- get
- {
- lock (_devices)
- {
- var devices = _devices.ToList();
-
- return devices.SelectMany(i => i.Value).ToList();
- }
- }
- }
-
- public void Start()
- {
- DisposeSocket();
- StopAliveNotifier();
-
- RestartSocketListener();
- ReloadAliveNotifier();
-
- SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
- SystemEvents.PowerModeChanged += SystemEvents_PowerModeChanged;
- }
-
- void SystemEvents_PowerModeChanged(object sender, PowerModeChangedEventArgs e)
- {
- if (e.Mode == PowerModes.Resume)
- {
- Start();
- }
- }
-
- public async void SendDatagram(string msg,
- EndPoint endpoint,
- EndPoint localAddress,
- bool isBroadcast,
- int sendCount = 3)
- {
- var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
-
- for (var i = 0; i < sendCount; i++)
- {
- if (i > 0)
- {
- await Task.Delay(500).ConfigureAwait(false);
- }
-
- var dgram = new Datagram(endpoint, localAddress, _logger, msg, isBroadcast, enableDebugLogging);
- dgram.Send();
- }
- }
-
- private void RestartSocketListener()
- {
- if (_isDisposed)
- {
- return;
- }
-
- try
- {
- _multicastSocket = CreateMulticastSocket();
-
- _logger.Info("MultiCast socket created");
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error creating MultiCast socket", ex);
- //StartSocketRetryTimer();
- }
- }
-
- public void Dispose()
- {
- _config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
- SystemEvents.PowerModeChanged -= SystemEvents_PowerModeChanged;
-
- _isDisposed = true;
-
- DisposeSocket();
- StopAliveNotifier();
- }
-
- private void DisposeSocket()
- {
- if (_multicastSocket != null)
- {
- _multicastSocket.Close();
- _multicastSocket.Dispose();
- _multicastSocket = null;
- }
- }
-
- private Socket CreateMulticastSocket()
- {
- var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Broadcast, true);
- socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, 4);
- socket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(_ssdpIp, 0));
-
- socket.Bind(new IPEndPoint(IPAddress.Any, SSDPPort));
-
- return socket;
- }
-
- private void NotifyAll()
- {
- var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLog;
-
- if (enableDebugLogging)
- {
- _logger.Debug("Sending alive notifications");
- }
- foreach (var d in RegisteredDevices)
- {
- NotifyDevice(d, "alive", enableDebugLogging);
- }
- }
-
- private void NotifyDevice(UpnpDevice dev, string type, bool logMessage)
- {
- const string header = "NOTIFY * HTTP/1.1";
-
- var values = new Dictionary(StringComparer.OrdinalIgnoreCase);
-
- // If needed later for non-server devices, these headers will need to be dynamic
- values["HOST"] = "239.255.255.250:1900";
- values["CACHE-CONTROL"] = "max-age = 600";
- values["LOCATION"] = dev.Descriptor.ToString();
- values["SERVER"] = _serverSignature;
- values["NTS"] = "ssdp:" + type;
- values["NT"] = dev.Type;
- values["USN"] = dev.USN;
-
- if (logMessage)
- {
- _logger.Debug("{0} said {1}", dev.USN, type);
- }
-
- var msg = new SsdpMessageBuilder().BuildMessage(header, values);
-
- SendDatagram(msg, _ssdpEndp, new IPEndPoint(dev.Address, 0), true, 2);
- //SendUnicastRequest(msg, 1);
- }
-
- public void RegisterNotification(string uuid, Uri descriptionUri, IPAddress address, IEnumerable services)
- {
- lock (_devices)
- {
- List list;
- List dl;
- if (_devices.TryGetValue(uuid, out dl))
- {
- list = dl;
- }
- else
- {
- list = new List();
- _devices[uuid] = list;
- }
-
- list.AddRange(services.Select(i => new UpnpDevice(uuid, i, descriptionUri, address)));
-
- NotifyAll();
- _logger.Debug("Registered mount {0} at {1}", uuid, descriptionUri);
- }
- }
-
- public void UnregisterNotification(string uuid)
- {
- lock (_devices)
- {
- List dl;
- if (_devices.TryGetValue(uuid, out dl))
- {
- _devices.Remove(uuid);
- foreach (var d in dl.ToList())
- {
- NotifyDevice(d, "byebye", true);
- }
-
- _logger.Debug("Unregistered mount {0}", uuid);
- }
- }
- }
-
- private readonly object _notificationTimerSyncLock = new object();
- private int _aliveNotifierIntervalMs;
- private void ReloadAliveNotifier()
- {
- var config = _config.GetDlnaConfiguration();
-
- if (!config.BlastAliveMessages)
- {
- StopAliveNotifier();
- return;
- }
-
- var intervalMs = config.BlastAliveMessageIntervalSeconds * 1000;
-
- if (_notificationTimer == null || _aliveNotifierIntervalMs != intervalMs)
- {
- lock (_notificationTimerSyncLock)
- {
- if (_notificationTimer == null)
- {
- _logger.Debug("Starting alive notifier");
- const int initialDelayMs = 3000;
- _notificationTimer = new Timer(state => NotifyAll(), null, initialDelayMs, intervalMs);
- }
- else
- {
- _logger.Debug("Updating alive notifier");
- _notificationTimer.Change(intervalMs, intervalMs);
- }
-
- _aliveNotifierIntervalMs = intervalMs;
- }
- }
- }
-
- private void StopAliveNotifier()
- {
- lock (_notificationTimerSyncLock)
- {
- if (_notificationTimer != null)
- {
- _logger.Debug("Stopping alive notifier");
- _notificationTimer.Dispose();
- _notificationTimer = null;
- }
- }
- }
-
- public class UdpState
- {
- public UdpClient UdpClient;
- public IPEndPoint EndPoint;
- }
- }
-}
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpMessageBuilder.cs b/MediaBrowser.Dlna/Ssdp/SsdpMessageBuilder.cs
deleted file mode 100644
index e479ca19a5..0000000000
--- a/MediaBrowser.Dlna/Ssdp/SsdpMessageBuilder.cs
+++ /dev/null
@@ -1,26 +0,0 @@
-using System.Collections.Generic;
-using System.Text;
-
-namespace MediaBrowser.Dlna.Ssdp
-{
- public class SsdpMessageBuilder
- {
- public string BuildMessage(string header, Dictionary values)
- {
- var builder = new StringBuilder();
-
- const string argFormat = "{0}: {1}\r\n";
-
- builder.AppendFormat("{0}\r\n", header);
-
- foreach (var pair in values)
- {
- builder.AppendFormat(argFormat, pair.Key, pair.Value);
- }
-
- builder.Append("\r\n");
-
- return builder.ToString();
- }
- }
-}
diff --git a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
index c9810b0423..3148405583 100644
--- a/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
+++ b/MediaBrowser.LocalMetadata/Savers/XmlSaverHelpers.cs
@@ -258,18 +258,14 @@ namespace MediaBrowser.LocalMetadata.Savers
builder.Append("" + SecurityElement.Escape(item.DisplayMediaType) + "");
}
- var hasCriticRating = item as IHasCriticRating;
- if (hasCriticRating != null)
+ if (item.CriticRating.HasValue)
{
- if (hasCriticRating.CriticRating.HasValue)
- {
- builder.Append("" + SecurityElement.Escape(hasCriticRating.CriticRating.Value.ToString(UsCulture)) + "");
- }
+ builder.Append("" + SecurityElement.Escape(item.CriticRating.Value.ToString(UsCulture)) + "");
+ }
- if (!string.IsNullOrEmpty(hasCriticRating.CriticRatingSummary))
- {
- builder.Append("");
- }
+ if (!string.IsNullOrEmpty(item.CriticRatingSummary))
+ {
+ builder.Append("");
}
if (!string.IsNullOrEmpty(item.Overview))
@@ -285,14 +281,10 @@ namespace MediaBrowser.LocalMetadata.Savers
builder.Append("" + SecurityElement.Escape(hasOriginalTitle.OriginalTitle) + "");
}
}
-
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null)
+
+ if (!string.IsNullOrEmpty(item.ShortOverview))
{
- if (!string.IsNullOrEmpty(hasShortOverview.ShortOverview))
- {
- builder.Append("");
- }
+ builder.Append("");
}
if (!string.IsNullOrEmpty(item.CustomRating))
diff --git a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
index b66a3ed96d..f811a8d48a 100644
--- a/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/EncodingJobFactory.cs
@@ -588,13 +588,32 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
if (string.Equals(hwType, "vaapi", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(options.VaapiDevice))
{
- return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder);
+ if (IsVaapiSupported(state))
+ {
+ return GetAvailableEncoder(mediaEncoder, "h264_vaapi", defaultEncoder);
+ }
}
}
return defaultEncoder;
}
+ private static bool IsVaapiSupported(EncodingJob state)
+ {
+ var videoStream = state.VideoStream;
+
+ if (videoStream != null)
+ {
+ // vaapi will throw an error with this input
+ // [vaapi @ 0x7faed8000960] No VAAPI support for codec mpeg4 profile -99.
+ if (string.Equals(videoStream.Codec, "mpeg4", StringComparison.OrdinalIgnoreCase) && videoStream.Level == -99)
+ {
+ return false;
+ }
+ }
+ return true;
+ }
+
internal static bool CanStreamCopyVideo(EncodingJobOptions request, MediaStream videoStream)
{
if (videoStream.IsInterlaced)
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index 8149e3ff5e..0b047f9e8f 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
@@ -31,6 +31,7 @@ namespace MediaBrowser.Model.Dto
public bool RequiresOpening { get; set; }
public string OpenToken { get; set; }
public bool RequiresClosing { get; set; }
+ public bool SupportsProbing { get; set; }
public string LiveStreamId { get; set; }
public int? BufferMs { get; set; }
@@ -63,6 +64,7 @@ namespace MediaBrowser.Model.Dto
SupportsTranscoding = true;
SupportsDirectStream = true;
SupportsDirectPlay = true;
+ SupportsProbing = true;
}
public int? DefaultAudioStreamIndex { get; set; }
diff --git a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
index ee7dd8b985..e19bddeee4 100644
--- a/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
+++ b/MediaBrowser.Model/LiveTv/LiveTvOptions.cs
@@ -16,6 +16,7 @@ namespace MediaBrowser.Model.LiveTv
public string RecordingEncodingFormat { get; set; }
public bool EnableRecordingSubfolders { get; set; }
public bool EnableOriginalAudioWithEncodedRecordings { get; set; }
+ public bool EnableOriginalVideoWithEncodedRecordings { get; set; }
public List TunerHosts { get; set; }
public List ListingProviders { get; set; }
diff --git a/MediaBrowser.Model/LiveTv/ProgramQuery.cs b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
index ad57d14732..1fd9957600 100644
--- a/MediaBrowser.Model/LiveTv/ProgramQuery.cs
+++ b/MediaBrowser.Model/LiveTv/ProgramQuery.cs
@@ -42,6 +42,7 @@ namespace MediaBrowser.Model.LiveTv
/// The user identifier.
public string UserId { get; set; }
public string SeriesTimerId { get; set; }
+ public string Name { get; set; }
///
/// The earliest date for which a program starts to return
diff --git a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
index 3affbbcc34..b6e2a96aa0 100644
--- a/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
+++ b/MediaBrowser.Model/MediaInfo/LiveStreamRequest.cs
@@ -11,6 +11,7 @@ namespace MediaBrowser.Model.MediaInfo
public long? StartTimeTicks { get; set; }
public int? AudioStreamIndex { get; set; }
public int? SubtitleStreamIndex { get; set; }
+ public int? MaxAudioChannels { get; set; }
public string ItemId { get; set; }
public DeviceProfile DeviceProfile { get; set; }
@@ -24,6 +25,7 @@ namespace MediaBrowser.Model.MediaInfo
MaxStreamingBitrate = options.MaxBitrate;
ItemId = options.ItemId;
DeviceProfile = options.Profile;
+ MaxAudioChannels = options.MaxAudioChannels;
VideoOptions videoOptions = options as VideoOptions;
if (videoOptions != null)
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
index 124739073a..a2b85d121e 100644
--- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
@@ -16,6 +16,8 @@ namespace MediaBrowser.Model.MediaInfo
public int? SubtitleStreamIndex { get; set; }
+ public int? MaxAudioChannels { get; set; }
+
public string MediaSourceId { get; set; }
public string LiveStreamId { get; set; }
diff --git a/MediaBrowser.Model/Net/MimeTypes.cs b/MediaBrowser.Model/Net/MimeTypes.cs
index 8bf0703be9..2c059c8600 100644
--- a/MediaBrowser.Model/Net/MimeTypes.cs
+++ b/MediaBrowser.Model/Net/MimeTypes.cs
@@ -100,6 +100,7 @@ namespace MediaBrowser.Model.Net
.ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase);
dict["image/jpg"] = ".jpg";
+ dict["image/x-png"] = ".png";
return dict;
}
diff --git a/MediaBrowser.Providers/Manager/ImageSaver.cs b/MediaBrowser.Providers/Manager/ImageSaver.cs
index 5203adc9d1..767c034ee6 100644
--- a/MediaBrowser.Providers/Manager/ImageSaver.cs
+++ b/MediaBrowser.Providers/Manager/ImageSaver.cs
@@ -72,7 +72,7 @@ namespace MediaBrowser.Providers.Manager
return SaveImage(item, source, mimeType, type, imageIndex, null, cancellationToken);
}
- public async Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
+ public async Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken)
{
if (string.IsNullOrEmpty(mimeType))
{
@@ -109,9 +109,9 @@ namespace MediaBrowser.Providers.Manager
}
}
}
- if (!string.IsNullOrEmpty(internalCacheKey))
+ if (saveLocallyWithMedia.HasValue && !saveLocallyWithMedia.Value)
{
- saveLocally = false;
+ saveLocally = saveLocallyWithMedia.Value;
}
if (!imageIndex.HasValue && item.AllowsMultipleImages(type))
@@ -356,6 +356,11 @@ namespace MediaBrowser.Providers.Manager
var season = item as Season;
var extension = MimeTypes.ToExtension(mimeType);
+ if (string.IsNullOrWhiteSpace(extension))
+ {
+ throw new ArgumentException(string.Format("Unable to determine image file extension from mime type {0}", mimeType));
+ }
+
if (type == ImageType.Thumb && saveLocally)
{
if (season != null && season.IndexNumber.HasValue)
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index 87da835dcc..898fa522df 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -156,14 +156,14 @@ namespace MediaBrowser.Providers.Manager
var stream = _fileSystem.GetFileStream(response.Path, FileMode.Open, FileAccess.Read, FileShare.Read, true);
- await _providerManager.SaveImage(item, stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false);
+ await _providerManager.SaveImage(item, stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
}
}
else
{
var mimeType = "image/" + response.Format.ToString().ToLower();
- await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, response.InternalCacheKey, cancellationToken).ConfigureAwait(false);
+ await _providerManager.SaveImage(item, response.Stream, mimeType, imageType, null, cancellationToken).ConfigureAwait(false);
}
downloadedImages.Add(imageType);
diff --git a/MediaBrowser.Providers/Manager/MetadataService.cs b/MediaBrowser.Providers/Manager/MetadataService.cs
index c470f55f2b..41cacbe0a8 100644
--- a/MediaBrowser.Providers/Manager/MetadataService.cs
+++ b/MediaBrowser.Providers/Manager/MetadataService.cs
@@ -353,19 +353,16 @@ namespace MediaBrowser.Providers.Manager
{
var updateType = ItemUpdateType.None;
- if (isFullRefresh || currentUpdateType > ItemUpdateType.None)
+ var folder = item as Folder;
+ if (folder != null && folder.SupportsDateLastMediaAdded)
{
- var folder = item as Folder;
- if (folder != null && folder.SupportsDateLastMediaAdded)
- {
- var items = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.DateCreated).ToList();
- var date = items.Count == 0 ? (DateTime?)null : items.Max();
+ var items = folder.GetRecursiveChildren(i => !i.IsFolder).Select(i => i.DateCreated).ToList();
+ var date = items.Count == 0 ? (DateTime?)null : items.Max();
- if ((!folder.DateLastMediaAdded.HasValue && date.HasValue) || folder.DateLastMediaAdded != date)
- {
- folder.DateLastMediaAdded = date;
- updateType = ItemUpdateType.MetadataEdit;
- }
+ if ((!folder.DateLastMediaAdded.HasValue && date.HasValue) || folder.DateLastMediaAdded != date)
+ {
+ folder.DateLastMediaAdded = date;
+ updateType = ItemUpdateType.MetadataImport;
}
}
diff --git a/MediaBrowser.Providers/Manager/ProviderManager.cs b/MediaBrowser.Providers/Manager/ProviderManager.cs
index ae1d60eb9f..dfeceed7d4 100644
--- a/MediaBrowser.Providers/Manager/ProviderManager.cs
+++ b/MediaBrowser.Providers/Manager/ProviderManager.cs
@@ -140,12 +140,7 @@ namespace MediaBrowser.Providers.Manager
return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, cancellationToken);
}
- public Task SaveImage(IHasImages item, Stream source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
- {
- return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, source, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
- }
-
- public Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, string internalCacheKey, CancellationToken cancellationToken)
+ public Task SaveImage(IHasImages item, string source, string mimeType, ImageType type, int? imageIndex, bool? saveLocallyWithMedia, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(source))
{
@@ -154,7 +149,7 @@ namespace MediaBrowser.Providers.Manager
var fileStream = _fileSystem.GetFileStream(source, FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true);
- return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, fileStream, mimeType, type, imageIndex, internalCacheKey, cancellationToken);
+ return new ImageSaver(ConfigurationManager, _libraryMonitor, _fileSystem, _logger, _memoryStreamProvider).SaveImage(item, fileStream, mimeType, type, imageIndex, saveLocallyWithMedia, cancellationToken);
}
public async Task> GetAvailableRemoteImages(IHasImages item, RemoteImageQuery query, CancellationToken cancellationToken)
diff --git a/MediaBrowser.Providers/Manager/ProviderUtils.cs b/MediaBrowser.Providers/Manager/ProviderUtils.cs
index fabe08f334..178e861a30 100644
--- a/MediaBrowser.Providers/Manager/ProviderUtils.cs
+++ b/MediaBrowser.Providers/Manager/ProviderUtils.cs
@@ -236,15 +236,9 @@ namespace MediaBrowser.Providers.Manager
private static void MergeShortOverview(BaseItem source, BaseItem target, List lockedFields, bool replaceData)
{
- var sourceHasShortOverview = source as IHasShortOverview;
- var targetHasShortOverview = target as IHasShortOverview;
-
- if (sourceHasShortOverview != null && targetHasShortOverview != null)
+ if (replaceData || string.IsNullOrEmpty(target.ShortOverview))
{
- if (replaceData || string.IsNullOrEmpty(targetHasShortOverview.ShortOverview))
- {
- targetHasShortOverview.ShortOverview = sourceHasShortOverview.ShortOverview;
- }
+ target.ShortOverview = source.ShortOverview;
}
}
@@ -311,20 +305,14 @@ namespace MediaBrowser.Providers.Manager
private static void MergeCriticRating(BaseItem source, BaseItem target, List lockedFields, bool replaceData)
{
- var sourceCast = source as IHasCriticRating;
- var targetCast = target as IHasCriticRating;
-
- if (sourceCast != null && targetCast != null)
+ if (replaceData || !target.CriticRating.HasValue)
{
- if (replaceData || !targetCast.CriticRating.HasValue)
- {
- targetCast.CriticRating = sourceCast.CriticRating;
- }
+ target.CriticRating = source.CriticRating;
+ }
- if (replaceData || string.IsNullOrEmpty(targetCast.CriticRatingSummary))
- {
- targetCast.CriticRatingSummary = sourceCast.CriticRatingSummary;
- }
+ if (replaceData || string.IsNullOrEmpty(target.CriticRatingSummary))
+ {
+ target.CriticRatingSummary = source.CriticRatingSummary;
}
}
diff --git a/MediaBrowser.Providers/Omdb/OmdbProvider.cs b/MediaBrowser.Providers/Omdb/OmdbProvider.cs
index f3766f007b..8fb4d8fccf 100644
--- a/MediaBrowser.Providers/Omdb/OmdbProvider.cs
+++ b/MediaBrowser.Providers/Omdb/OmdbProvider.cs
@@ -66,28 +66,24 @@ namespace MediaBrowser.Providers.Omdb
item.ProductionYear = year;
}
- var hasCriticRating = item as IHasCriticRating;
- if (hasCriticRating != null)
- {
- // Seeing some bogus RT data on omdb for series, so filter it out here
- // RT doesn't even have tv series
- int tomatoMeter;
+ // Seeing some bogus RT data on omdb for series, so filter it out here
+ // RT doesn't even have tv series
+ int tomatoMeter;
- if (!string.IsNullOrEmpty(result.tomatoMeter)
- && int.TryParse(result.tomatoMeter, NumberStyles.Integer, _usCulture, out tomatoMeter)
- && tomatoMeter >= 0)
- {
- hasCriticRating.CriticRating = tomatoMeter;
- }
+ if (!string.IsNullOrEmpty(result.tomatoMeter)
+ && int.TryParse(result.tomatoMeter, NumberStyles.Integer, _usCulture, out tomatoMeter)
+ && tomatoMeter >= 0)
+ {
+ item.CriticRating = tomatoMeter;
+ }
- if (!string.IsNullOrEmpty(result.tomatoConsensus)
- && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase))
- {
- hasCriticRating.CriticRatingSummary = WebUtility.HtmlDecode(result.tomatoConsensus);
- }
- }
+ if (!string.IsNullOrEmpty(result.tomatoConsensus)
+ && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase))
+ {
+ item.CriticRatingSummary = WebUtility.HtmlDecode(result.tomatoConsensus);
+ }
- int voteCount;
+ int voteCount;
if (!string.IsNullOrEmpty(result.imdbVotes)
&& int.TryParse(result.imdbVotes, NumberStyles.Number, _usCulture, out voteCount)
@@ -167,25 +163,21 @@ namespace MediaBrowser.Providers.Omdb
item.ProductionYear = year;
}
- var hasCriticRating = item as IHasCriticRating;
- if (hasCriticRating != null)
+ // Seeing some bogus RT data on omdb for series, so filter it out here
+ // RT doesn't even have tv series
+ int tomatoMeter;
+
+ if (!string.IsNullOrEmpty(result.tomatoMeter)
+ && int.TryParse(result.tomatoMeter, NumberStyles.Integer, _usCulture, out tomatoMeter)
+ && tomatoMeter >= 0)
{
- // Seeing some bogus RT data on omdb for series, so filter it out here
- // RT doesn't even have tv series
- int tomatoMeter;
+ item.CriticRating = tomatoMeter;
+ }
- if (!string.IsNullOrEmpty(result.tomatoMeter)
- && int.TryParse(result.tomatoMeter, NumberStyles.Integer, _usCulture, out tomatoMeter)
- && tomatoMeter >= 0)
- {
- hasCriticRating.CriticRating = tomatoMeter;
- }
-
- if (!string.IsNullOrEmpty(result.tomatoConsensus)
- && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase))
- {
- hasCriticRating.CriticRatingSummary = WebUtility.HtmlDecode(result.tomatoConsensus);
- }
+ if (!string.IsNullOrEmpty(result.tomatoConsensus)
+ && !string.Equals(result.tomatoConsensus, "No consensus yet.", StringComparison.OrdinalIgnoreCase))
+ {
+ item.CriticRatingSummary = WebUtility.HtmlDecode(result.tomatoConsensus);
}
int voteCount;
@@ -420,12 +412,8 @@ namespace MediaBrowser.Providers.Omdb
hasAwards.AwardSummary = WebUtility.HtmlDecode(result.Awards);
}
- var hasShortOverview = item as IHasShortOverview;
- if (hasShortOverview != null)
- {
- // Imdb plots are usually pretty short
- hasShortOverview.ShortOverview = result.Plot;
- }
+ // Imdb plots are usually pretty short
+ item.ShortOverview = result.Plot;
//if (!string.IsNullOrWhiteSpace(result.Director))
//{
diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
index 3df7a03d4c..c2c776c2bb 100644
--- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
+++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
@@ -45,6 +45,11 @@ namespace MediaBrowser.Server.Implementations.IO
private void AddAffectedPath(string path)
{
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
if (!_affectedPaths.Contains(path, StringComparer.Ordinal))
{
_affectedPaths.Add(path);
@@ -53,6 +58,11 @@ namespace MediaBrowser.Server.Implementations.IO
public void AddPath(string path)
{
+ if (string.IsNullOrWhiteSpace(path))
+ {
+ throw new ArgumentNullException("path");
+ }
+
lock (_timerLock)
{
AddAffectedPath(path);
diff --git a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
index b2302cf867..64abcc0440 100644
--- a/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/LibraryManager.cs
@@ -2838,9 +2838,13 @@ namespace MediaBrowser.Server.Implementations.Library
private bool ValidateNetworkPath(string path)
{
- if (Environment.OSVersion.Platform == PlatformID.Win32NT || !path.StartsWith("\\\\", StringComparison.OrdinalIgnoreCase))
+ if (Environment.OSVersion.Platform == PlatformID.Win32NT)
{
- return Directory.Exists(path);
+ // We can't validate protocol-based paths, so just allow them
+ if (path.IndexOf("://", StringComparison.OrdinalIgnoreCase) == -1)
+ {
+ return Directory.Exists(path);
+ }
}
// Without native support for unc, we cannot validate this when running under mono
diff --git a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
index 716d627a93..e7bfe56f2e 100644
--- a/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/MediaSourceManager.cs
@@ -360,7 +360,6 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task OpenLiveStream(LiveStreamRequest request, bool enableAutoClose, CancellationToken cancellationToken)
{
- enableAutoClose = false;
await _liveStreamSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
try
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index c3d5f34412..5f41995647 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -207,14 +207,18 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
// Find movies with their own folders
if (args.IsDirectory)
{
+ var files = args.FileSystemChildren
+ .Where(i => !LibraryManager.IgnoreFile(i, args.Parent))
+ .ToList();
+
if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase))
{
- return null;
+ return FindMovie(args.Path, args.Parent, files, args.DirectoryService, collectionType, false);
}
if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase))
{
- return null;
+ return FindMovie
///
- /// The path.
- /// The parent.
- /// The file system entries.
- /// The directory service.
- /// Type of the collection.
/// Movie.
- private T FindMovie(string path, Folder parent, List fileSystemEntries, IDirectoryService directoryService, string collectionType)
+ private T FindMovie(string path, Folder parent, List fileSystemEntries, IDirectoryService directoryService, string collectionType, bool allowFilesAsFolders)
where T : Video, new()
{
var multiDiscFolders = new List();
@@ -413,23 +405,27 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
}
}
- var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
- !string.Equals(collectionType, CollectionType.Photos) &&
- !string.Equals(collectionType, CollectionType.MusicVideos);
-
- var result = ResolveVideos(parent, fileSystemEntries, directoryService, supportsMultiVersion);
-
- if (result.Items.Count == 1)
+ if (allowFilesAsFolders)
{
- var movie = (T)result.Items[0];
- movie.IsInMixedFolder = false;
- movie.Name = Path.GetFileName(movie.ContainingFolderPath);
- return movie;
- }
+ // TODO: Allow GetMultiDiscMovie in here
+ var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) &&
+ !string.Equals(collectionType, CollectionType.Photos) &&
+ !string.Equals(collectionType, CollectionType.MusicVideos);
- if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
- {
- return GetMultiDiscMovie(multiDiscFolders, directoryService);
+ var result = ResolveVideos(parent, fileSystemEntries, directoryService, supportsMultiVersion);
+
+ if (result.Items.Count == 1)
+ {
+ var movie = (T)result.Items[0];
+ movie.IsInMixedFolder = false;
+ movie.Name = Path.GetFileName(movie.ContainingFolderPath);
+ return movie;
+ }
+
+ if (result.Items.Count == 0 && multiDiscFolders.Count > 0)
+ {
+ return GetMultiDiscMovie(multiDiscFolders, directoryService);
+ }
}
return null;
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
index 9b69b84d36..214bb87169 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs
@@ -1021,7 +1021,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var stream = new MediaSourceInfo
{
- Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
+ Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveRecordings/" + recordingId + "/stream",
Id = recordingId,
SupportsDirectPlay = false,
SupportsDirectStream = true,
@@ -1854,23 +1854,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
ParentIndexNumber = program.SeasonNumber.Value,
IndexNumber = program.EpisodeNumber.Value,
AncestorIds = seriesIds,
- ExcludeLocationTypes = new[] { LocationType.Virtual }
- });
-
- if (result.TotalRecordCount > 0)
- {
- return true;
- }
- }
-
- if (!string.IsNullOrWhiteSpace(program.EpisodeTitle))
- {
- var result = _libraryManager.GetItemsResult(new InternalItemsQuery
- {
- IncludeItemTypes = new[] { typeof(Episode).Name },
- Name = program.EpisodeTitle,
- AncestorIds = seriesIds,
- ExcludeLocationTypes = new[] { LocationType.Virtual }
+ IsVirtualItem = false
});
if (result.TotalRecordCount > 0)
diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
index 3e9d186e3f..cdf8e75974 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EncodedRecorder.cs
@@ -52,7 +52,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
{
var format = _liveTvOptions.RecordingEncodingFormat;
- if (string.Equals(format, "mkv", StringComparison.OrdinalIgnoreCase))
+ if (string.Equals(format, "mkv", StringComparison.OrdinalIgnoreCase) || _liveTvOptions.EnableOriginalVideoWithEncodedRecordings)
{
return "mkv";
}
@@ -204,6 +204,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
private bool EncodeVideo(MediaSourceInfo mediaSource)
{
+ if (_liveTvOptions.EnableOriginalAudioWithEncodedRecordings)
+ {
+ return false;
+ }
+
var mediaStreams = mediaSource.MediaStreams ?? new List();
return !mediaStreams.Any(i => i.Type == MediaStreamType.Video && string.Equals(i.Codec, "h264", StringComparison.OrdinalIgnoreCase) && !i.IsInterlaced);
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
index 8c46b45972..c7a2d295d9 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvDtoService.cs
@@ -72,7 +72,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
{
dto.ProgramInfo = _dtoService.GetBaseItemDto(program, new DtoOptions());
- dto.ProgramInfo.TimerId = dto.Id;
+ if (info.Status != RecordingStatus.Cancelled && info.Status != RecordingStatus.Error)
+ {
+ dto.ProgramInfo.TimerId = dto.Id;
+ dto.ProgramInfo.Status = info.Status.ToString();
+ }
dto.ProgramInfo.SeriesTimerId = dto.SeriesTimerId;
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index aa404b37ca..902afb2003 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -877,6 +877,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
SortOrder = query.SortOrder ?? SortOrder.Ascending,
EnableTotalRecordCount = query.EnableTotalRecordCount,
TopParentIds = new[] { topFolder.Id.ToString("N") },
+ Name = query.Name,
DtoOptions = options
};
@@ -1946,7 +1947,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
}
else
{
- timers = timers.Where(i => !(i.Item1.Status == RecordingStatus.New));
+ timers = timers.Where(i => i.Item1.Status != RecordingStatus.New);
}
}
@@ -2304,7 +2305,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var info = await service.GetNewTimerDefaultsAsync(cancellationToken, programInfo).ConfigureAwait(false);
- info.RecordAnyChannel = true;
info.RecordAnyTime = true;
info.Days = new List
{
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
index a62796036d..393708fb7d 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvMediaSourceProvider.cs
@@ -140,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
try
{
- if (stream.MediaStreams.Any(i => i.Index != -1))
+ if (!stream.SupportsProbing || stream.MediaStreams.Any(i => i.Index != -1))
{
await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
index 60222415c0..91f0ee832f 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunLiveStream.cs
@@ -60,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
//OpenedMediaSource.Path = tempFile;
//OpenedMediaSource.ReadAtNativeFramerate = true;
- OpenedMediaSource.Path = _appHost.GetLocalApiUrl("localhost") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
+ OpenedMediaSource.Path = _appHost.GetLocalApiUrl("127.0.0.1") + "/LiveTv/LiveStreamFiles/" + UniqueId + "/stream.ts";
OpenedMediaSource.Protocol = MediaProtocol.Http;
OpenedMediaSource.SupportsDirectPlay = false;
OpenedMediaSource.SupportsDirectStream = true;
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
index cedaf7ad86..48117f2251 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs
@@ -13,6 +13,7 @@ using System.Threading;
using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Serialization;
@@ -24,12 +25,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
- public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
+ public M3UTunerHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_fileSystem = fileSystem;
_httpClient = httpClient;
+ _appHost = appHost;
}
public override string Type
@@ -46,7 +49,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
protected override async Task> GetChannelsInternal(TunerHostInfo info, CancellationToken cancellationToken)
{
- return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
+ return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(info.Url, ChannelIdPrefix, info.Id, cancellationToken).ConfigureAwait(false);
}
public Task> GetTunerInfos(CancellationToken cancellationToken)
@@ -75,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
public async Task Validate(TunerHostInfo info)
{
- using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
+ using (var stream = await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).GetListingsStream(info.Url, CancellationToken.None).ConfigureAwait(false))
{
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
index 38eb9bdd11..454abddddb 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/M3uParser.cs
@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using CommonIO;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Model.Logging;
@@ -18,12 +19,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
private readonly ILogger _logger;
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
- public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient)
+ public M3uParser(ILogger logger, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
{
_logger = logger;
_fileSystem = fileSystem;
_httpClient = httpClient;
+ _appHost = appHost;
}
public async Task> Parse(string url, string channelIdPrefix, string tunerHostId, CancellationToken cancellationToken)
@@ -41,7 +44,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
{
if (url.StartsWith("http", StringComparison.OrdinalIgnoreCase))
{
- return _httpClient.Get(url, cancellationToken);
+ return _httpClient.Get(new HttpRequestOptions
+ {
+ Url = url,
+ CancellationToken = cancellationToken,
+ // Some data providers will require a user agent
+ UserAgent = _appHost.FriendlyName + "/" + _appHost.ApplicationVersion
+ });
}
return Task.FromResult(_fileSystem.OpenRead(url));
}
@@ -111,15 +120,31 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
channel.Number = "0";
}
- channel.ImageUrl = FindProperty("tvg-logo", extInf, null);
- channel.Number = FindProperty("channel-id", extInf, channel.Number);
- channel.Number = FindProperty("tvg-id", extInf, channel.Number);
- channel.Name = FindProperty("tvg-id", extInf, channel.Name);
- channel.Name = FindProperty("tvg-name", extInf, channel.Name);
+ channel.ImageUrl = FindProperty("tvg-logo", extInf);
+
+ var name = FindProperty("tvg-name", extInf);
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ name = FindProperty("tvg-id", extInf);
+ }
+
+ channel.Name = name;
+
+ var numberString = FindProperty("tvg-id", extInf);
+ if (string.IsNullOrWhiteSpace(numberString))
+ {
+ numberString = FindProperty("channel-id", extInf);
+ }
+
+ if (!string.IsNullOrWhiteSpace(numberString))
+ {
+ channel.Number = numberString;
+ }
+
return channel;
}
- private string FindProperty(string property, string properties, string defaultResult = "")
+ private string FindProperty(string property, string properties)
{
var reg = new Regex(@"([a-z0-9\-_]+)=\""([^""]+)\""", RegexOptions.IgnoreCase);
var matches = reg.Matches(properties);
@@ -130,7 +155,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
return match.Groups[2].Value;
}
}
- return defaultResult;
+ return null;
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
index 81deb29959..1fe767e521 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/TunerHosts/SatIp/SatIpHost.cs
@@ -8,6 +8,7 @@ using CommonIO;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
+using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
@@ -25,12 +26,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
private readonly IFileSystem _fileSystem;
private readonly IHttpClient _httpClient;
+ private readonly IServerApplicationHost _appHost;
- public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient)
+ public SatIpHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IHttpClient httpClient, IServerApplicationHost appHost)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_fileSystem = fileSystem;
_httpClient = httpClient;
+ _appHost = appHost;
}
private const string ChannelIdPrefix = "sat_";
@@ -39,7 +42,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.SatIp
{
if (!string.IsNullOrWhiteSpace(tuner.M3UUrl))
{
- return await new M3uParser(Logger, _fileSystem, _httpClient).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
+ return await new M3uParser(Logger, _fileSystem, _httpClient, _appHost).Parse(tuner.M3UUrl, ChannelIdPrefix, tuner.Id, cancellationToken).ConfigureAwait(false);
}
var channels = await new ChannelScan(Logger).Scan(tuner, cancellationToken).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
index abf0f34255..22d7ba3bec 100644
--- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
@@ -144,7 +144,7 @@ namespace MediaBrowser.Server.Implementations.Photos
return ItemUpdateType.None;
}
- await ProviderManager.SaveImage(item, outputPath, "image/png", imageType, null, Guid.NewGuid().ToString("N"), cancellationToken).ConfigureAwait(false);
+ await ProviderManager.SaveImage(item, outputPath, "image/png", imageType, null, false, cancellationToken).ConfigureAwait(false);
return ItemUpdateType.ImageUpdate;
}
diff --git a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs
index d01f7ed1b3..9484130cbc 100644
--- a/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs
+++ b/MediaBrowser.Server.Implementations/Sorting/CriticRatingComparer.cs
@@ -22,9 +22,7 @@ namespace MediaBrowser.Server.Implementations.Sorting
private float GetValue(BaseItem x)
{
- var hasCriticRating = x as IHasCriticRating;
-
- return hasCriticRating == null ? 0 : hasCriticRating.CriticRating ?? 0;
+ return x.CriticRating ?? 0;
}
///
diff --git a/MediaBrowser.ServerApplication/MainStartup.cs b/MediaBrowser.ServerApplication/MainStartup.cs
index d1972a938b..b2c7445e23 100644
--- a/MediaBrowser.ServerApplication/MainStartup.cs
+++ b/MediaBrowser.ServerApplication/MainStartup.cs
@@ -71,7 +71,7 @@ namespace MediaBrowser.ServerApplication
if (_isRunningAsService)
{
- _canRestartService = CanRestartWindowsService();
+ //_canRestartService = CanRestartWindowsService();
}
var currentProcess = Process.GetCurrentProcess();
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 36dd12651c..a561a48afc 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -986,9 +986,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
@@ -1034,9 +1031,6 @@
PreserveNewest
-
- PreserveNewest
-
PreserveNewest
diff --git a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
index 8c45b8001d..59f6e87220 100644
--- a/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
+++ b/MediaBrowser.XbmcMetadata/Parsers/BaseNfoParser.cs
@@ -294,14 +294,12 @@ namespace MediaBrowser.XbmcMetadata.Parsers
{
var text = reader.ReadElementContentAsString();
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null && !string.IsNullOrEmpty(text))
+ if (!string.IsNullOrEmpty(text))
{
float value;
if (float.TryParse(text, NumberStyles.Any, _usCulture, out value))
{
- hasCriticRating.CriticRating = value;
+ item.CriticRating = value;
}
}
@@ -388,12 +386,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
if (!string.IsNullOrWhiteSpace(val))
{
- var hasShortOverview = item as IHasShortOverview;
-
- if (hasShortOverview != null)
- {
- hasShortOverview.ShortOverview = val;
- }
+ item.ShortOverview = val;
}
break;
}
@@ -418,12 +411,7 @@ namespace MediaBrowser.XbmcMetadata.Parsers
if (!string.IsNullOrWhiteSpace(val))
{
- var hasCriticRating = item as IHasCriticRating;
-
- if (hasCriticRating != null)
- {
- hasCriticRating.CriticRatingSummary = val;
- }
+ item.CriticRatingSummary = val;
}
break;
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 31d946691b..aba4913f33 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common.Internal
- 3.0.663
+ 3.0.665
MediaBrowser.Common.Internal
Luke
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains common components shared by Emby Theater and Emby Server. Not intended for plugin developer consumption.
Copyright © Emby 2013
-
+
diff --git a/Nuget/MediaBrowser.Common.nuspec b/Nuget/MediaBrowser.Common.nuspec
index 86524c2b66..cd79701275 100644
--- a/Nuget/MediaBrowser.Common.nuspec
+++ b/Nuget/MediaBrowser.Common.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Common
- 3.0.663
+ 3.0.665
MediaBrowser.Common
Emby Team
ebr,Luke,scottisafool
diff --git a/Nuget/MediaBrowser.Server.Core.nuspec b/Nuget/MediaBrowser.Server.Core.nuspec
index 860a19436b..b0dd3ae4fe 100644
--- a/Nuget/MediaBrowser.Server.Core.nuspec
+++ b/Nuget/MediaBrowser.Server.Core.nuspec
@@ -2,7 +2,7 @@
MediaBrowser.Server.Core
- 3.0.663
+ 3.0.665
Media Browser.Server.Core
Emby Team
ebr,Luke,scottisafool
@@ -12,7 +12,7 @@
Contains core components required to build plugins for Emby Server.
Copyright © Emby 2013
-
+