aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTavares André <tavares_and@hotmail.com>2015-05-07 19:12:56 +0200
committerTavares André <tavares_and@hotmail.com>2015-05-07 19:12:56 +0200
commit48e7ca87254969f98abbedcfc46985fc1ea955c0 (patch)
treec1084f29f6529d4bf5524fdab7a723686a379b2d
parentf2b800181252b6fd0bb3b51925d1dcb0623f21d2 (diff)
parent63dc2512c5d272dbc3cb1515beb175e9b3572440 (diff)
Merge branch 'dev' of https://github.com/MediaBrowser/MediaBrowser into dev
Conflicts: MediaBrowser.Server.Implementations/Localization/Server/server.json
-rw-r--r--MediaBrowser.Api/Images/ImageService.cs4
-rw-r--r--MediaBrowser.Api/Library/LibraryService.cs53
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs35
-rw-r--r--MediaBrowser.Api/Playback/Dash/MpegDashService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Hls/BaseHlsService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Hls/VideoHlsService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Progressive/AudioService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs3
-rw-r--r--MediaBrowser.Api/Playback/Progressive/VideoService.cs3
-rw-r--r--MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj7
-rw-r--r--MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs43
-rw-r--r--MediaBrowser.Common.Implementations/packages.config2
-rw-r--r--MediaBrowser.Controller/Entities/Audio/Audio.cs38
-rw-r--r--MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs47
-rw-r--r--MediaBrowser.Controller/Entities/BaseItem.cs32
-rw-r--r--MediaBrowser.Controller/Entities/TV/Episode.cs23
-rw-r--r--MediaBrowser.Controller/Entities/TV/Season.cs44
-rw-r--r--MediaBrowser.Controller/Entities/TV/Series.cs13
-rw-r--r--MediaBrowser.Dlna/DlnaManager.cs4
-rw-r--r--MediaBrowser.Dlna/MediaBrowser.Dlna.csproj6
-rw-r--r--MediaBrowser.Dlna/PlayTo/Device.cs16
-rw-r--r--MediaBrowser.Dlna/PlayTo/PlayToController.cs5
-rw-r--r--MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs14
-rw-r--r--MediaBrowser.Dlna/Profiles/BubbleUpnpProfile.cs76
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs7
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs7
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs7
-rw-r--r--MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs7
-rw-r--r--MediaBrowser.Dlna/Profiles/VlcProfile.cs76
-rw-r--r--MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml50
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Default.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Generic Device.xml43
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml4
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Vlc.xml50
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml1
-rw-r--r--MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml1
-rw-r--r--MediaBrowser.Dlna/Service/BaseControlHandler.cs6
-rw-r--r--MediaBrowser.Dlna/Ssdp/Datagram.cs19
-rw-r--r--MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs25
-rw-r--r--MediaBrowser.Dlna/Ssdp/SsdpHandler.cs108
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs28
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs296
-rw-r--r--MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs2
-rw-r--r--MediaBrowser.Model/Configuration/ServerConfiguration.cs6
-rw-r--r--MediaBrowser.Model/Dlna/CodecProfile.cs27
-rw-r--r--MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs3
-rw-r--r--MediaBrowser.Model/Dlna/DeviceProfile.cs1
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs12
-rw-r--r--MediaBrowser.Providers/Manager/ItemImageProvider.cs30
-rw-r--r--MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs2
-rw-r--r--MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs15
-rw-r--r--MediaBrowser.Server.Implementations/Dto/DtoService.cs11
-rw-r--r--MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json1
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json9
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json21
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj7
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs56
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs96
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs82
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs10
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs13
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs80
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteShrinkMemoryTimer.cs84
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs104
-rw-r--r--MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs99
-rw-r--r--MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs31
-rw-r--r--MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Session/SessionManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs6
-rw-r--r--MediaBrowser.Server.Implementations/packages.config4
-rw-r--r--MediaBrowser.Server.Startup.Common/ApplicationHost.cs8
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs27
-rw-r--r--MediaBrowser.WebDashboard/Api/PackageCreator.cs78
-rw-r--r--MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj14
-rw-r--r--Nuget/MediaBrowser.Common.Internal.nuspec2
97 files changed, 1071 insertions, 1145 deletions
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 7da11a405..639c1f54b 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -648,10 +648,8 @@ namespace MediaBrowser.Api.Images
var serverFormats = _imageProcessor.GetSupportedImageOutputFormats();
- var clientFormats = GetClientSupportedFormats();
-
if (serverFormats.Contains(ImageFormat.Webp) &&
- clientFormats.Contains(ImageFormat.Webp))
+ GetClientSupportedFormats().Contains(ImageFormat.Webp))
{
return ImageFormat.Webp;
}
diff --git a/MediaBrowser.Api/Library/LibraryService.cs b/MediaBrowser.Api/Library/LibraryService.cs
index f89a70340..269f4cb20 100644
--- a/MediaBrowser.Api/Library/LibraryService.cs
+++ b/MediaBrowser.Api/Library/LibraryService.cs
@@ -617,36 +617,14 @@ namespace MediaBrowser.Api.Library
: (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id);
- var originalItem = item;
-
while (GetThemeSongIds(item).Count == 0 && request.InheritFromParent && item.Parent != null)
{
item = item.Parent;
}
- var themeSongIds = GetThemeSongIds(item);
-
- if (themeSongIds.Count == 0 && request.InheritFromParent)
- {
- var album = originalItem as MusicAlbum;
-
- if (album != null)
- {
- var linkedItemWithThemes = album.SoundtrackIds
- .Select(i => _libraryManager.GetItemById(i))
- .FirstOrDefault(i => GetThemeSongIds(i).Count > 0);
-
- if (linkedItemWithThemes != null)
- {
- themeSongIds = GetThemeSongIds(linkedItemWithThemes);
- item = linkedItemWithThemes;
- }
- }
- }
-
var dtoOptions = GetDtoOptions(request);
- var dtos = themeSongIds.Select(_libraryManager.GetItemById)
+ var dtos = GetThemeSongIds(item).Select(_libraryManager.GetItemById)
.OrderBy(i => i.SortName)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
@@ -682,41 +660,14 @@ namespace MediaBrowser.Api.Library
: (Folder)_libraryManager.RootFolder)
: _libraryManager.GetItemById(request.Id);
- var originalItem = item;
-
while (GetThemeVideoIds(item).Count == 0 && request.InheritFromParent && item.Parent != null)
{
item = item.Parent;
}
- var themeVideoIds = GetThemeVideoIds(item);
-
- if (themeVideoIds.Count == 0 && request.InheritFromParent)
- {
- var album = originalItem as MusicAlbum;
-
- if (album == null)
- {
- album = originalItem.Parents.OfType<MusicAlbum>().FirstOrDefault();
- }
-
- if (album != null)
- {
- var linkedItemWithThemes = album.SoundtrackIds
- .Select(i => _libraryManager.GetItemById(i))
- .FirstOrDefault(i => GetThemeVideoIds(i).Count > 0);
-
- if (linkedItemWithThemes != null)
- {
- themeVideoIds = GetThemeVideoIds(linkedItemWithThemes);
- item = linkedItemWithThemes;
- }
- }
- }
-
var dtoOptions = GetDtoOptions(request);
- var dtos = themeVideoIds.Select(_libraryManager.GetItemById)
+ var dtos = GetThemeVideoIds(item).Select(_libraryManager.GetItemById)
.OrderBy(i => i.SortName)
.Select(i => _dtoService.GetBaseItemDto(i, dtoOptions, user, item));
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index db94e37f4..34fb29b94 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -23,6 +23,7 @@ using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Api.Playback
{
@@ -68,12 +69,14 @@ namespace MediaBrowser.Api.Playback
protected ISubtitleEncoder SubtitleEncoder { get; private set; }
protected IMediaSourceManager MediaSourceManager { get; private set; }
protected IZipClient ZipClient { get; private set; }
+ protected IJsonSerializer JsonSerializer { get; private set; }
/// <summary>
/// Initializes a new instance of the <see cref="BaseStreamingService" /> class.
/// </summary>
- protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient)
+ protected BaseStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer)
{
+ JsonSerializer = jsonSerializer;
ZipClient = zipClient;
MediaSourceManager = mediaSourceManager;
DeviceManager = deviceManager;
@@ -598,7 +601,7 @@ namespace MediaBrowser.Api.Playback
var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(min(iw\\,{0})/2)*2:trunc(min((iw/dar)\\,{1})/2)*2", maxWidthParam, maxHeightParam));
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
}
// If a fixed width was requested
@@ -618,7 +621,7 @@ namespace MediaBrowser.Api.Playback
}
// If a max width was requested
- else if (request.MaxWidth.HasValue && (!request.MaxHeight.HasValue || state.VideoStream == null))
+ else if (request.MaxWidth.HasValue)
{
var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
@@ -626,35 +629,13 @@ namespace MediaBrowser.Api.Playback
}
// If a max height was requested
- else if (request.MaxHeight.HasValue && (!request.MaxWidth.HasValue || state.VideoStream == null))
+ else if (request.MaxHeight.HasValue)
{
var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
filters.Add(string.Format("scale=trunc(oh*a*2)/2:min(ih\\,{0})", maxHeightParam));
}
- else if (request.MaxWidth.HasValue ||
- request.MaxHeight.HasValue ||
- request.Width.HasValue ||
- request.Height.HasValue)
- {
- if (state.VideoStream != null)
- {
- // Need to perform calculations manually
-
- // Try to account for bad media info
- var currentHeight = state.VideoStream.Height ?? request.MaxHeight ?? request.Height ?? 0;
- var currentWidth = state.VideoStream.Width ?? request.MaxWidth ?? request.Width ?? 0;
-
- var outputSize = DrawingUtils.Resize(currentWidth, currentHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
-
- var manualWidthParam = outputSize.Width.ToString(UsCulture);
- var manualHeightParam = outputSize.Height.ToString(UsCulture);
-
- filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", manualWidthParam, manualHeightParam));
- }
- }
-
if (string.Equals(outputVideoCodec, "h264_qsv", StringComparison.OrdinalIgnoreCase))
{
filters[filters.Count - 1] += ":flags=fast_bilinear";
@@ -1027,7 +1008,7 @@ namespace MediaBrowser.Api.Playback
// FFMpeg writes debug/error info to stderr. This is useful when debugging so let's put it in the log directory.
state.LogFileStream = FileSystem.GetFileStream(logFilePath, FileMode.Create, FileAccess.Write, FileShare.Read, true);
- var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(Request.AbsoluteUri + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
+ var commandLineLogMessageBytes = Encoding.UTF8.GetBytes(Request.AbsoluteUri + Environment.NewLine + Environment.NewLine + JsonSerializer.SerializeToString(state.MediaSource) + Environment.NewLine + Environment.NewLine + commandLineLogMessage + Environment.NewLine + Environment.NewLine);
await state.LogFileStream.WriteAsync(commandLineLogMessageBytes, 0, commandLineLogMessageBytes.Length, cancellationTokenSource.Token).ConfigureAwait(false);
process.Exited += (sender, args) => OnFfMpegProcessExited(process, transcodingJob, state);
diff --git a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs
index 0692c4863..1a90dbb53 100644
--- a/MediaBrowser.Api/Playback/Dash/MpegDashService.cs
+++ b/MediaBrowser.Api/Playback/Dash/MpegDashService.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using ServiceStack;
using System;
using System.Collections.Generic;
@@ -53,7 +54,7 @@ namespace MediaBrowser.Api.Playback.Dash
public class MpegDashService : BaseHlsService
{
- public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient)
+ public MpegDashService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
{
NetworkManager = networkManager;
}
diff --git a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
index 78dee4c44..b10c02e17 100644
--- a/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/BaseHlsService.cs
@@ -13,6 +13,7 @@ using System.IO;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using MediaBrowser.Model.Serialization;
namespace MediaBrowser.Api.Playback.Hls
{
@@ -21,7 +22,7 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public abstract class BaseHlsService : BaseStreamingService
{
- protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient)
+ protected BaseHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
{
}
diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
index 4f938dc41..1f6bc242d 100644
--- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using ServiceStack;
using System;
using System.Collections.Generic;
@@ -61,7 +62,7 @@ namespace MediaBrowser.Api.Playback.Hls
public class DynamicHlsService : BaseHlsService
{
- public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient)
+ public DynamicHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, INetworkManager networkManager) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
{
NetworkManager = networkManager;
}
diff --git a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
index 8e2854c5e..626df59f2 100644
--- a/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
+++ b/MediaBrowser.Api/Playback/Hls/VideoHlsService.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Dlna;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using ServiceStack;
using System;
@@ -40,7 +41,7 @@ namespace MediaBrowser.Api.Playback.Hls
/// </summary>
public class VideoHlsService : BaseHlsService
{
- public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient)
+ public VideoHlsService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
{
}
diff --git a/MediaBrowser.Api/Playback/Progressive/AudioService.cs b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
index fee501159..67a9cab58 100644
--- a/MediaBrowser.Api/Playback/Progressive/AudioService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/AudioService.cs
@@ -8,6 +8,7 @@ using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using ServiceStack;
using System.Collections.Generic;
@@ -31,7 +32,7 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public class AudioService : BaseProgressiveStreamingService
{
- public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, imageProcessor, httpClient)
+ public AudioService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
{
}
diff --git a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
index 8ed17ca17..835f3357e 100644
--- a/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/BaseProgressiveStreamingService.cs
@@ -10,6 +10,7 @@ using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.IO;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Serialization;
using ServiceStack.Web;
using System;
using System.Collections.Generic;
@@ -27,7 +28,7 @@ namespace MediaBrowser.Api.Playback.Progressive
protected readonly IImageProcessor ImageProcessor;
protected readonly IHttpClient HttpClient;
- protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient)
+ protected BaseProgressiveStreamingService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer)
{
ImageProcessor = imageProcessor;
HttpClient = httpClient;
diff --git a/MediaBrowser.Api/Playback/Progressive/VideoService.cs b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
index 0ded108b1..27482c50c 100644
--- a/MediaBrowser.Api/Playback/Progressive/VideoService.cs
+++ b/MediaBrowser.Api/Playback/Progressive/VideoService.cs
@@ -7,6 +7,7 @@ using MediaBrowser.Controller.Drawing;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.IO;
+using MediaBrowser.Model.Serialization;
using ServiceStack;
using System;
using System.IO;
@@ -61,7 +62,7 @@ namespace MediaBrowser.Api.Playback.Progressive
/// </summary>
public class VideoService : BaseProgressiveStreamingService
{
- public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, imageProcessor, httpClient)
+ public VideoService(IServerConfigurationManager serverConfig, IUserManager userManager, ILibraryManager libraryManager, IIsoManager isoManager, IMediaEncoder mediaEncoder, IFileSystem fileSystem, IDlnaManager dlnaManager, ISubtitleEncoder subtitleEncoder, IDeviceManager deviceManager, IMediaSourceManager mediaSourceManager, IZipClient zipClient, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, imageProcessor, httpClient)
{
}
diff --git a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
index 967cf54a6..e603ea373 100644
--- a/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
+++ b/MediaBrowser.Common.Implementations/MediaBrowser.Common.Implementations.csproj
@@ -58,11 +58,8 @@
</Reference>
<Reference Include="SimpleInjector, Version=2.7.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\SimpleInjector.2.7.0\lib\net45\SimpleInjector.dll</HintPath>
- </Reference>
- <Reference Include="SimpleInjector.Diagnostics, Version=2.7.0.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\SimpleInjector.2.7.0\lib\net45\SimpleInjector.Diagnostics.dll</HintPath>
+ <HintPath>..\packages\SimpleInjector.2.8.0\lib\net45\SimpleInjector.dll</HintPath>
+ <Private>True</Private>
</Reference>
<Reference Include="System" />
<Reference Include="System.Core" />
diff --git a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
index 0fd4e2787..c27dfd68d 100644
--- a/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
+++ b/MediaBrowser.Common.Implementations/Networking/BaseNetworkManager.cs
@@ -6,16 +6,29 @@ using System.Linq;
using System.Net;
using System.Net.NetworkInformation;
using System.Net.Sockets;
+using System.Threading;
namespace MediaBrowser.Common.Implementations.Networking
{
public abstract class BaseNetworkManager
{
protected ILogger Logger { get; private set; }
+ private Timer _clearCacheTimer;
protected BaseNetworkManager(ILogger logger)
{
Logger = logger;
+
+ // Can't use network change events due to a crash in Linux
+ _clearCacheTimer = new Timer(ClearCacheTimerCallback, null, TimeSpan.FromMinutes(1), TimeSpan.FromMinutes(1));
+ }
+
+ private void ClearCacheTimerCallback(object state)
+ {
+ lock (_localIpAddressSyncLock)
+ {
+ _localIpAddresses = null;
+ }
}
private volatile List<string> _localIpAddresses;
@@ -36,7 +49,6 @@ namespace MediaBrowser.Common.Implementations.Networking
var addresses = GetLocalIpAddressesInternal().ToList();
_localIpAddresses = addresses;
- BindEvents();
return addresses;
}
@@ -46,35 +58,6 @@ namespace MediaBrowser.Common.Implementations.Networking
return _localIpAddresses;
}
- private void BindEvents()
- {
- NetworkChange.NetworkAddressChanged -= NetworkChange_NetworkAddressChanged;
- NetworkChange.NetworkAvailabilityChanged -= NetworkChange_NetworkAvailabilityChanged;
-
- NetworkChange.NetworkAddressChanged += NetworkChange_NetworkAddressChanged;
- NetworkChange.NetworkAvailabilityChanged += NetworkChange_NetworkAvailabilityChanged;
- }
-
- void NetworkChange_NetworkAvailabilityChanged(object sender, NetworkAvailabilityEventArgs e)
- {
- Logger.Debug("NetworkAvailabilityChanged fired. Resetting cached network info.");
-
- lock (_localIpAddressSyncLock)
- {
- _localIpAddresses = null;
- }
- }
-
- void NetworkChange_NetworkAddressChanged(object sender, EventArgs e)
- {
- Logger.Debug("NetworkAddressChanged fired. Resetting cached network info.");
-
- lock (_localIpAddressSyncLock)
- {
- _localIpAddresses = null;
- }
- }
-
private IEnumerable<string> GetLocalIpAddressesInternal()
{
var list = GetIPsDefault()
diff --git a/MediaBrowser.Common.Implementations/packages.config b/MediaBrowser.Common.Implementations/packages.config
index 56cb78031..e57c874f2 100644
--- a/MediaBrowser.Common.Implementations/packages.config
+++ b/MediaBrowser.Common.Implementations/packages.config
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="NLog" version="3.2.1" targetFramework="net45" />
- <package id="SimpleInjector" version="2.7.0" targetFramework="net45" />
+ <package id="SimpleInjector" version="2.8.0" targetFramework="net45" />
</packages>
diff --git a/MediaBrowser.Controller/Entities/Audio/Audio.cs b/MediaBrowser.Controller/Entities/Audio/Audio.cs
index 100633d7f..623329ca6 100644
--- a/MediaBrowser.Controller/Entities/Audio/Audio.cs
+++ b/MediaBrowser.Controller/Entities/Audio/Audio.cs
@@ -52,34 +52,6 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <value><c>true</c> if this instance has embedded image; otherwise, <c>false</c>.</value>
public bool HasEmbeddedImage { get; set; }
- /// <summary>
- /// Override this to true if class should be grouped under a container in indicies
- /// The container class should be defined via IndexContainer
- /// </summary>
- /// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool GroupInIndex
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Override this to return the folder that should be used to construct a container
- /// for this item in an index. GroupInIndex should be true as well.
- /// </summary>
- /// <value>The index container.</value>
- [IgnoreDataMember]
- public override Folder IndexContainer
- {
- get
- {
- return LatestItemsIndexContainer ?? new MusicAlbum { Name = "Unknown Album" };
- }
- }
-
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{
@@ -94,7 +66,7 @@ namespace MediaBrowser.Controller.Entities.Audio
{
get
{
- return Parents.OfType<MusicAlbum>().FirstOrDefault();
+ return AlbumEntity;
}
}
@@ -148,6 +120,12 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <value>The album.</value>
public string Album { get; set; }
+ [IgnoreDataMember]
+ public MusicAlbum AlbumEntity
+ {
+ get { return FindParent<MusicAlbum>(); }
+ }
+
/// <summary>
/// Gets the type of the media.
/// </summary>
@@ -177,7 +155,7 @@ namespace MediaBrowser.Controller.Entities.Audio
/// <returns>System.String.</returns>
protected override string CreateUserDataKey()
{
- var parent = FindParent<MusicAlbum>();
+ var parent = AlbumEntity;
if (parent != null)
{
diff --git a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
index dc3f13b01..c060f53a6 100644
--- a/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
+++ b/MediaBrowser.Controller/Entities/Audio/MusicAlbum.cs
@@ -2,7 +2,6 @@
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Users;
-using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
@@ -14,11 +13,8 @@ namespace MediaBrowser.Controller.Entities.Audio
/// </summary>
public class MusicAlbum : Folder, IHasAlbumArtist, IHasArtist, IHasMusicGenres, IHasLookupInfo<AlbumInfo>
{
- public List<Guid> SoundtrackIds { get; set; }
-
public MusicAlbum()
{
- SoundtrackIds = new List<Guid>();
Artists = new List<string>();
AlbumArtists = new List<string>();
}
@@ -77,49 +73,6 @@ namespace MediaBrowser.Controller.Entities.Audio
return Tracks;
}
- /// <summary>
- /// Songs will group into us so don't also include us in the index
- /// </summary>
- /// <value><c>true</c> if [include in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IncludeInIndex
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
- /// Override this to true if class should be grouped under a container in indicies
- /// The container class should be defined via IndexContainer
- /// </summary>
- /// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool GroupInIndex
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// The unknwon artist
- /// </summary>
- private static readonly MusicArtist UnknwonArtist = new MusicArtist { Name = "<Unknown>" };
-
- /// <summary>
- /// Override this to return the folder that should be used to construct a container
- /// for this item in an index. GroupInIndex should be true as well.
- /// </summary>
- /// <value>The index container.</value>
- [IgnoreDataMember]
- public override Folder IndexContainer
- {
- get { return Parent as MusicArtist ?? UnknwonArtist; }
- }
-
public List<string> Artists { get; set; }
/// <summary>
diff --git a/MediaBrowser.Controller/Entities/BaseItem.cs b/MediaBrowser.Controller/Entities/BaseItem.cs
index 3313f45fd..8b6cbdc93 100644
--- a/MediaBrowser.Controller/Entities/BaseItem.cs
+++ b/MediaBrowser.Controller/Entities/BaseItem.cs
@@ -906,38 +906,6 @@ namespace MediaBrowser.Controller.Entities
/// <value>The provider ids.</value>
public Dictionary<string, string> ProviderIds { get; set; }
- /// <summary>
- /// Override this to false if class should be ignored for indexing purposes
- /// </summary>
- /// <value><c>true</c> if [include in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public virtual bool IncludeInIndex
- {
- get { return true; }
- }
-
- /// <summary>
- /// Override this to true if class should be grouped under a container in indicies
- /// The container class should be defined via IndexContainer
- /// </summary>
- /// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public virtual bool GroupInIndex
- {
- get { return false; }
- }
-
- /// <summary>
- /// Override this to return the folder that should be used to construct a container
- /// for this item in an index. GroupInIndex should be true as well.
- /// </summary>
- /// <value>The index container.</value>
- [IgnoreDataMember]
- public virtual Folder IndexContainer
- {
- get { return null; }
- }
-
[IgnoreDataMember]
public virtual Folder LatestItemsIndexContainer
{
diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs
index c8408365d..8f5b8f6cf 100644
--- a/MediaBrowser.Controller/Entities/TV/Episode.cs
+++ b/MediaBrowser.Controller/Entities/TV/Episode.cs
@@ -45,16 +45,6 @@ namespace MediaBrowser.Controller.Entities.TV
/// <value>The index number.</value>
public int? IndexNumberEnd { get; set; }
- /// <summary>
- /// We want to group into series not show individually in an index
- /// </summary>
- /// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool GroupInIndex
- {
- get { return true; }
- }
-
[IgnoreDataMember]
protected override bool SupportsOwnedItems
{
@@ -91,19 +81,6 @@ namespace MediaBrowser.Controller.Entities.TV
}
}
- /// <summary>
- /// We roll up into series
- /// </summary>
- /// <value>The index container.</value>
- [IgnoreDataMember]
- public override Folder IndexContainer
- {
- get
- {
- return Season;
- }
- }
-
[IgnoreDataMember]
public override Folder LatestItemsIndexContainer
{
diff --git a/MediaBrowser.Controller/Entities/TV/Season.cs b/MediaBrowser.Controller/Entities/TV/Season.cs
index a99b8c659..cfd6b46e0 100644
--- a/MediaBrowser.Controller/Entities/TV/Season.cs
+++ b/MediaBrowser.Controller/Entities/TV/Season.cs
@@ -1,5 +1,4 @@
-using MediaBrowser.Controller.Localization;
-using MediaBrowser.Controller.Providers;
+using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
using MediaBrowser.Model.Users;
@@ -15,20 +14,6 @@ namespace MediaBrowser.Controller.Entities.TV
/// </summary>
public class Season : Folder, IHasSeries, IHasLookupInfo<SeasonInfo>
{
-
- /// <summary>
- /// Seasons are just containers
- /// </summary>
- /// <value><c>true</c> if [include in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IncludeInIndex
- {
- get
- {
- return false;
- }
- }
-
[IgnoreDataMember]
public override bool SupportsAddingToPlaylist
{
@@ -50,33 +35,6 @@ namespace MediaBrowser.Controller.Entities.TV
get { return Series ?? Parent; }
}
- /// <summary>
- /// We want to group into our Series
- /// </summary>
- /// <value><c>true</c> if [group in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool GroupInIndex
- {
- get
- {
- return true;
- }
- }
-
- /// <summary>
- /// Override this to return the folder that should be used to construct a container
- /// for this item in an index. GroupInIndex should be true as well.
- /// </summary>
- /// <value>The index container.</value>
- [IgnoreDataMember]
- public override Folder IndexContainer
- {
- get
- {
- return Series;
- }
- }
-
// Genre, Rating and Stuido will all be the same
protected override IEnumerable<string> GetIndexByOptions()
{
diff --git a/MediaBrowser.Controller/Entities/TV/Series.cs b/MediaBrowser.Controller/Entities/TV/Series.cs
index 4696afeb6..2663d19e8 100644
--- a/MediaBrowser.Controller/Entities/TV/Series.cs
+++ b/MediaBrowser.Controller/Entities/TV/Series.cs
@@ -95,19 +95,6 @@ namespace MediaBrowser.Controller.Entities.TV
}
/// <summary>
- /// Series aren't included directly in indices - Their Episodes will roll up to them
- /// </summary>
- /// <value><c>true</c> if [include in index]; otherwise, <c>false</c>.</value>
- [IgnoreDataMember]
- public override bool IncludeInIndex
- {
- get
- {
- return false;
- }
- }
-
- /// <summary>
/// Gets the user data key.
/// </summary>
/// <returns>System.String.</returns>
diff --git a/MediaBrowser.Dlna/DlnaManager.cs b/MediaBrowser.Dlna/DlnaManager.cs
index bdc8beb98..62756e4c4 100644
--- a/MediaBrowser.Dlna/DlnaManager.cs
+++ b/MediaBrowser.Dlna/DlnaManager.cs
@@ -544,7 +544,9 @@ namespace MediaBrowser.Dlna
new DirectTvProfile(),
new DishHopperJoeyProfile(),
new DefaultProfile(),
- new PopcornHourProfile()
+ new PopcornHourProfile(),
+ new VlcProfile(),
+ new BubbleUpnpProfile()
};
foreach (var item in list)
diff --git a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
index b4e93ed68..204872e7b 100644
--- a/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
+++ b/MediaBrowser.Dlna/MediaBrowser.Dlna.csproj
@@ -77,10 +77,12 @@
<Compile Include="Common\DeviceService.cs" />
<Compile Include="Didl\DidlBuilder.cs" />
<Compile Include="PlayTo\PlayToController.cs" />
+ <Compile Include="Profiles\BubbleUpnpProfile.cs" />
<Compile Include="Profiles\DefaultProfile.cs" />
<Compile Include="Profiles\DirectTvProfile.cs" />
<Compile Include="Profiles\DishHopperJoeyProfile.cs" />
<Compile Include="Profiles\PopcornHourProfile.cs" />
+ <Compile Include="Profiles\VlcProfile.cs" />
<Compile Include="Ssdp\DeviceDiscoveryInfo.cs" />
<Compile Include="Ssdp\Extensions.cs" />
<Compile Include="PlayTo\PlaybackProgressEventArgs.cs" />
@@ -204,6 +206,10 @@
<EmbeddedResource Include="Images\people480.jpg" />
<EmbeddedResource Include="Images\people480.png" />
</ItemGroup>
+ <ItemGroup>
+ <EmbeddedResource Include="Profiles\Xml\BubbleUPnp.xml" />
+ <EmbeddedResource Include="Profiles\Xml\Vlc.xml" />
+ </ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
diff --git a/MediaBrowser.Dlna/PlayTo/Device.cs b/MediaBrowser.Dlna/PlayTo/Device.cs
index 00cb34be3..c41aa73a9 100644
--- a/MediaBrowser.Dlna/PlayTo/Device.cs
+++ b/MediaBrowser.Dlna/PlayTo/Device.cs
@@ -296,7 +296,7 @@ namespace MediaBrowser.Dlna.PlayTo
}
var post = AvCommands.BuildPost(command, service.ServiceType, url, dictionary);
- await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header)
+ await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, post, header: header)
.ConfigureAwait(false);
await Task.Delay(50).ConfigureAwait(false);
@@ -463,10 +463,10 @@ namespace MediaBrowser.Dlna.PlayTo
if (service == null)
{
- throw new InvalidOperationException("Unable to find service");
+ return;
}
- var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType), true)
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -496,10 +496,10 @@ namespace MediaBrowser.Dlna.PlayTo
if (service == null)
{
- throw new InvalidOperationException("Unable to find service");
+ return;
}
- var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType), true)
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -521,7 +521,7 @@ namespace MediaBrowser.Dlna.PlayTo
if (service == null)
return null;
- var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, AvCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -558,7 +558,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false);
if (result == null || result.Document == null)
@@ -589,7 +589,7 @@ namespace MediaBrowser.Dlna.PlayTo
throw new InvalidOperationException("Unable to find service");
}
- var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType))
+ var result = await new SsdpHttpClient(_httpClient, _config).SendCommandAsync(Properties.BaseUrl, service, command.Name, RendererCommands.BuildPost(command, service.ServiceType), false)
.ConfigureAwait(false);
if (result == null || result.Document == null)
diff --git a/MediaBrowser.Dlna/PlayTo/PlayToController.cs b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
index 5aa8c1f9c..cf21211f4 100644
--- a/MediaBrowser.Dlna/PlayTo/PlayToController.cs
+++ b/MediaBrowser.Dlna/PlayTo/PlayToController.cs
@@ -768,8 +768,11 @@ namespace MediaBrowser.Dlna.PlayTo
await _device.SetAvTransport(newItem.StreamUrl, GetDlnaHeaders(newItem), newItem.Didl).ConfigureAwait(false);
- if (newItem.StreamInfo.IsDirectStream)
+ if (newItem.StreamInfo.IsDirectStream && newPosition > 0)
{
+ // This is rather arbitrary, but give the player time to start playing
+ await Task.Delay(2000).ConfigureAwait(false);
+
await _device.Seek(TimeSpan.FromTicks(newPosition)).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
index f0689751c..39d3a8d07 100644
--- a/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
+++ b/MediaBrowser.Dlna/PlayTo/SsdpHttpClient.cs
@@ -1,7 +1,7 @@
-using System;
-using MediaBrowser.Common.Net;
+using MediaBrowser.Common.Net;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Dlna.Common;
+using System;
using System.Globalization;
using System.IO;
using System.Text;
@@ -28,9 +28,10 @@ namespace MediaBrowser.Dlna.PlayTo
DeviceService service,
string command,
string postData,
+ bool logRequest = true,
string header = null)
{
- var response = await PostSoapDataAsync(NormalizeServiceUrl(baseUrl, service.ControlUrl), "\"" + service.ServiceType + "#" + command + "\"", postData, header)
+ var response = await PostSoapDataAsync(NormalizeServiceUrl(baseUrl, service.ControlUrl), "\"" + service.ServiceType + "#" + command + "\"", postData, header, logRequest)
.ConfigureAwait(false);
using (var stream = response.Content)
@@ -69,7 +70,6 @@ namespace MediaBrowser.Dlna.PlayTo
{
Url = url,
UserAgent = USERAGENT,
- LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging,
LogErrorResponseBody = true
};
@@ -87,7 +87,6 @@ namespace MediaBrowser.Dlna.PlayTo
{
Url = url,
UserAgent = USERAGENT,
- LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging,
LogErrorResponseBody = true
};
@@ -105,7 +104,8 @@ namespace MediaBrowser.Dlna.PlayTo
private Task<HttpResponseInfo> PostSoapDataAsync(string url,
string soapAction,
string postData,
- string header = null)
+ string header,
+ bool logRequest)
{
if (!soapAction.StartsWith("\""))
soapAction = "\"" + soapAction + "\"";
@@ -114,7 +114,7 @@ namespace MediaBrowser.Dlna.PlayTo
{
Url = url,
UserAgent = USERAGENT,
- LogRequest = _config.GetDlnaConfiguration().EnableDebugLogging,
+ LogRequest = logRequest || _config.GetDlnaConfiguration().EnableDebugLogging,
LogErrorResponseBody = true
};
diff --git a/MediaBrowser.Dlna/Profiles/BubbleUpnpProfile.cs b/MediaBrowser.Dlna/Profiles/BubbleUpnpProfile.cs
new file mode 100644
index 000000000..a9af85346
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/BubbleUpnpProfile.cs
@@ -0,0 +1,76 @@
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.Profiles
+{
+ [XmlRoot("Profile")]
+ public class BubbleUpnpProfile : DefaultProfile
+ {
+ public BubbleUpnpProfile()
+ {
+ Name = "BubbleUPnp";
+
+ TimelineOffsetSeconds = 5;
+
+ Identification = new DeviceIdentification
+ {
+ ModelName = "BubbleUPnp",
+
+ Headers = new[]
+ {
+ new HttpHeaderInfo {Name = "User-Agent", Value = "BubbleUPnp", Match = HeaderMatchType.Substring}
+ }
+ };
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio,
+ AudioCodec = "mp3"
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video,
+ VideoCodec = "h264",
+ AudioCodec = "aac"
+ },
+ new TranscodingProfile
+ {
+ Container = "jpeg",
+ Type = DlnaProfileType.Photo
+ }
+ };
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Container = "avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "mp3,flac,asf,off,oga,aac",
+ Type = DlnaProfileType.Audio
+ },
+
+ new DirectPlayProfile
+ {
+ Type = DlnaProfileType.Photo,
+
+ Container = "jpeg,png,gif,bmp,tiff"
+ }
+ };
+
+ ResponseProfiles = new ResponseProfile[] { };
+
+ ContainerProfiles = new ContainerProfile[] { };
+
+ CodecProfiles = new CodecProfile[] { };
+ }
+ }
+}
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
index 71f877232..3bd425cb3 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
@@ -47,6 +47,7 @@ namespace MediaBrowser.Dlna.Profiles
"http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=81500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=81500000000000000000000000000000";
EnableSingleAlbumArtLimit = true;
+ EnableAlbumArtInDidl = true;
TranscodingProfiles = new[]
{
@@ -293,6 +294,12 @@ namespace MediaBrowser.Dlna.Profiles
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.Height,
Value = "1080"
+ },
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.LessThanEqual,
+ Property = ProfileConditionValue.VideoFramerate,
+ Value = "30"
}
}
},
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
index 0b157ae33..de4f1d2b6 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
@@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true;
+ EnableAlbumArtInDidl = true;
TranscodingProfiles = new[]
{
@@ -310,6 +311,12 @@ namespace MediaBrowser.Dlna.Profiles
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.Height,
Value = "1080"
+ },
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.LessThanEqual,
+ Property = ProfileConditionValue.VideoFramerate,
+ Value = "30"
}
}
},
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
index 0d974cbc0..5a5fb9e94 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
@@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true;
+ EnableAlbumArtInDidl = true;
TranscodingProfiles = new[]
{
@@ -250,6 +251,12 @@ namespace MediaBrowser.Dlna.Profiles
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.Height,
Value = "1080"
+ },
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.LessThanEqual,
+ Property = ProfileConditionValue.VideoFramerate,
+ Value = "30"
}
}
},
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
index ac4cb2131..74a07f389 100644
--- a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
+++ b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
@@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true;
+ EnableAlbumArtInDidl = true;
TranscodingProfiles = new[]
{
@@ -284,6 +285,12 @@ namespace MediaBrowser.Dlna.Profiles
Condition = ProfileConditionType.LessThanEqual,
Property = ProfileConditionValue.Height,
Value = "1080"
+ },
+ new ProfileCondition
+ {
+ Condition = ProfileConditionType.LessThanEqual,
+ Property = ProfileConditionValue.VideoFramerate,
+ Value = "30"
}
}
}
diff --git a/MediaBrowser.Dlna/Profiles/VlcProfile.cs b/MediaBrowser.Dlna/Profiles/VlcProfile.cs
new file mode 100644
index 000000000..5b3f7c0d1
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/VlcProfile.cs
@@ -0,0 +1,76 @@
+using System.Xml.Serialization;
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Dlna.Profiles
+{
+ [XmlRoot("Profile")]
+ public class VlcProfile : DefaultProfile
+ {
+ public VlcProfile()
+ {
+ Name = "Vlc";
+
+ TimelineOffsetSeconds = 5;
+
+ Identification = new DeviceIdentification
+ {
+ ModelName = "Vlc",
+
+ Headers = new[]
+ {
+ new HttpHeaderInfo {Name = "User-Agent", Value = "vlc", Match = HeaderMatchType.Substring}
+ }
+ };
+
+ TranscodingProfiles = new[]
+ {
+ new TranscodingProfile
+ {
+ Container = "mp3",
+ Type = DlnaProfileType.Audio,
+ AudioCodec = "mp3"
+ },
+ new TranscodingProfile
+ {
+ Container = "ts",
+ Type = DlnaProfileType.Video,
+ VideoCodec = "h264",
+ AudioCodec = "aac"
+ },
+ new TranscodingProfile
+ {
+ Container = "jpeg",
+ Type = DlnaProfileType.Photo
+ }
+ };
+
+ DirectPlayProfiles = new[]
+ {
+ new DirectPlayProfile
+ {
+ Container = "avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso",
+ Type = DlnaProfileType.Video
+ },
+
+ new DirectPlayProfile
+ {
+ Container = "mp3,flac,asf,off,oga,aac",
+ Type = DlnaProfileType.Audio
+ },
+
+ new DirectPlayProfile
+ {
+ Type = DlnaProfileType.Photo,
+
+ Container = "jpeg,png,gif,bmp,tiff"
+ }
+ };
+
+ ResponseProfiles = new ResponseProfile[] { };
+
+ ContainerProfiles = new ContainerProfile[] { };
+
+ CodecProfiles = new CodecProfile[] { };
+ }
+ }
+}
diff --git a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
index a26c43911..ab8d5ea72 100644
--- a/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
+++ b/MediaBrowser.Dlna/Profiles/WdtvLiveProfile.cs
@@ -11,7 +11,6 @@ namespace MediaBrowser.Dlna.Profiles
Name = "WDTV Live";
TimelineOffsetSeconds = 5;
- IgnoreTranscodeByteRangeRequests = true;
Identification = new DeviceIdentification
{
diff --git a/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
new file mode 100644
index 000000000..d65b55f2e
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/BubbleUPnp.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>BubbleUPnp</Name>
+ <Identification>
+ <ModelName>BubbleUPnp</ModelName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="BubbleUPnp" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Emby</FriendlyName>
+ <Manufacturer>Emby</Manufacturer>
+ <ManufacturerUrl>http://emby.media/</ManufacturerUrl>
+ <ModelName>Emby</ModelName>
+ <ModelDescription>Emby</ModelDescription>
+ <ModelNumber>Emby</ModelNumber>
+ <ModelUrl>http://emby.media/</ModelUrl>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <AlbumArtPn>JPEG_SM</AlbumArtPn>
+ <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
+ <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
+ <MaxIconWidth>48</MaxIconWidth>
+ <MaxIconHeight>48</MaxIconHeight>
+ <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>8000000</MaxStaticBitrate>
+ <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
+ <MusicSyncBitrate>128000</MusicSyncBitrate>
+ <XDlnaDoc>DMS-1.50</XDlnaDoc>
+ <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
+ <TimelineOffsetSeconds>5</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar>
+ <XmlRootAttributes />
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso" type="Video" />
+ <DirectPlayProfile container="mp3,flac,asf,off,oga,aac" type="Audio" />
+ <DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles />
+ <ResponseProfiles />
+ <SubtitleProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Default.xml b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
index 3c1fbfb1b..1c611d47a 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Default.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Default.xml
@@ -8,7 +8,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
index 2fde80008..4f8a0eac5 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Denon AVR.xml
@@ -13,7 +13,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
index 7876ccc7c..4595b57e0 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/DirecTV HD-DVR.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
index 21f2b1ad5..50bc43f7c 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Dish Hopper-Joey.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Generic Device.xml b/MediaBrowser.Dlna/Profiles/Xml/Generic Device.xml
new file mode 100644
index 000000000..1c611d47a
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Generic Device.xml
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Generic Device</Name>
+ <FriendlyName>Emby</FriendlyName>
+ <Manufacturer>Emby</Manufacturer>
+ <ManufacturerUrl>http://emby.media/</ManufacturerUrl>
+ <ModelName>Emby</ModelName>
+ <ModelDescription>Emby</ModelDescription>
+ <ModelNumber>Emby</ModelNumber>
+ <ModelUrl>http://emby.media/</ModelUrl>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <AlbumArtPn>JPEG_SM</AlbumArtPn>
+ <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
+ <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
+ <MaxIconWidth>48</MaxIconWidth>
+ <MaxIconHeight>48</MaxIconHeight>
+ <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>8000000</MaxStaticBitrate>
+ <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
+ <MusicSyncBitrate>128000</MusicSyncBitrate>
+ <XDlnaDoc>DMS-1.50</XDlnaDoc>
+ <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
+ <TimelineOffsetSeconds>0</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar>
+ <XmlRootAttributes />
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="mp3,wma" type="Audio" />
+ <DirectPlayProfile container="avi,mp4" type="Video" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles />
+ <ResponseProfiles />
+ <SubtitleProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
index a2fc002e5..919fa5a40 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/LG Smart TV.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
index a273586bd..1dc942873 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Linksys DMA2100.xml
@@ -12,7 +12,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
index e92b99830..4896402a0 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/MediaMonkey.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
index dcc06abb3..a2203e4ce 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Panasonic Viera.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
index 2df2da98b..b02f37986 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Popcorn Hour.xml
@@ -8,7 +8,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
index d8d2a0b2b..91c2325cf 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Samsung Smart TV.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
index e4959c0c7..f5ec1a31e 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player 2013.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
index b46b94c1d..6a732f869 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Blu-ray Player.xml
@@ -16,7 +16,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
index 19cb5670a..7afc8183d 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
@@ -15,8 +15,7 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn>
@@ -79,6 +78,7 @@
<Conditions>
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
</Conditions>
</CodecProfile>
<CodecProfile type="VideoAudio" codec="ac3">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index 78c99d366..7400600e2 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -15,8 +15,7 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn>
@@ -82,6 +81,7 @@
<Conditions>
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
</Conditions>
</CodecProfile>
<CodecProfile type="VideoAudio" codec="ac3">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index 4f849b731..b8e3d6d30 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -15,8 +15,7 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn>
@@ -67,6 +66,7 @@
<Conditions>
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
</Conditions>
</CodecProfile>
<CodecProfile type="VideoAudio" codec="ac3">
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index e074b8389..5733d9d0b 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -15,8 +15,7 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
- <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn>
@@ -72,6 +71,7 @@
<Conditions>
<ProfileCondition condition="LessThanEqual" property="Width" value="1920" isRequired="true" />
<ProfileCondition condition="LessThanEqual" property="Height" value="1080" isRequired="true" />
+ <ProfileCondition condition="LessThanEqual" property="VideoFramerate" value="30" isRequired="true" />
</Conditions>
</CodecProfile>
</CodecProfiles>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
index e90d1bc0f..4b21dc195 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony PlayStation 3.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
new file mode 100644
index 000000000..fd4b77f55
--- /dev/null
+++ b/MediaBrowser.Dlna/Profiles/Xml/Vlc.xml
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+<Profile xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+ <Name>Vlc</Name>
+ <Identification>
+ <ModelName>Vlc</ModelName>
+ <Headers>
+ <HttpHeaderInfo name="User-Agent" value="vlc" match="Substring" />
+ </Headers>
+ </Identification>
+ <FriendlyName>Emby</FriendlyName>
+ <Manufacturer>Emby</Manufacturer>
+ <ManufacturerUrl>http://emby.media/</ManufacturerUrl>
+ <ModelName>Emby</ModelName>
+ <ModelDescription>Emby</ModelDescription>
+ <ModelNumber>Emby</ModelNumber>
+ <ModelUrl>http://emby.media/</ModelUrl>
+ <EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
+ <EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
+ <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
+ <AlbumArtPn>JPEG_SM</AlbumArtPn>
+ <MaxAlbumArtWidth>480</MaxAlbumArtWidth>
+ <MaxAlbumArtHeight>480</MaxAlbumArtHeight>
+ <MaxIconWidth>48</MaxIconWidth>
+ <MaxIconHeight>48</MaxIconHeight>
+ <MaxStreamingBitrate>8000000</MaxStreamingBitrate>
+ <MaxStaticBitrate>8000000</MaxStaticBitrate>
+ <MusicStreamingTranscodingBitrate>128000</MusicStreamingTranscodingBitrate>
+ <MusicSyncBitrate>128000</MusicSyncBitrate>
+ <XDlnaDoc>DMS-1.50</XDlnaDoc>
+ <ProtocolInfo>http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_AC3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_HD_50_AC3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/mpeg:DLNA.ORG_PN=MP3;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=44100;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=1:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/L16;rate=48000;channels=2:DLNA.ORG_PN=LPCM;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_BASE;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:audio/x-ms-wma:DLNA.ORG_PN=WMA_FULL;DLNA.ORG_OP=01;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_SM;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_MED;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_LRG;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:image/jpeg:DLNA.ORG_PN=JPEG_TN;DLNA.ORG_OP=00;DLNA.ORG_FLAGS=00D00000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG1;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_PAL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_PS_NTSC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_EU_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_EU_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_NA_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_NA_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=MPEG_TS_SD_KO_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=MPEG_TS_SD_KO_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-msvideo:DLNA.ORG_PN=AVI;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-matroska:DLNA.ORG_PN=MATROSKA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_SD_AC3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_720p_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_MP_HD_1080i_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_HP_HD_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=AVC_MP4_LPCM;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_ASP_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_SP_L6_AAC;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mp4:DLNA.ORG_PN=MPEG4_P2_MP4_NDSD;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_SD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_AAC_MULT5_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/mpeg:DLNA.ORG_PN=AVC_TS_MP_HD_MPEG1_L3_ISO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/vnd.dlna.mpeg-tts:DLNA.ORG_PN=AVC_TS_HD_50_LPCM_T;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_BASE;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_FULL;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVMED_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-wmv:DLNA.ORG_PN=WMVHIGH_PRO;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L1_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L2_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000,http-get:*:video/x-ms-asf:DLNA.ORG_PN=VC1_ASF_AP_L3_WMA;DLNA.ORG_OP=11;DLNA.ORG_FLAGS=01500000000000000000000000000000</ProtocolInfo>
+ <TimelineOffsetSeconds>5</TimelineOffsetSeconds>
+ <RequiresPlainVideoItems>false</RequiresPlainVideoItems>
+ <RequiresPlainFolders>false</RequiresPlainFolders>
+ <EnableMSMediaReceiverRegistrar>false</EnableMSMediaReceiverRegistrar>
+ <XmlRootAttributes />
+ <DirectPlayProfiles>
+ <DirectPlayProfile container="avi,mpeg,mkv,ts,mp4,mov,m4v,asf,webm,ogg,ogv,iso" type="Video" />
+ <DirectPlayProfile container="mp3,flac,asf,off,oga,aac" type="Audio" />
+ <DirectPlayProfile container="jpeg,png,gif,bmp,tiff" type="Photo" />
+ </DirectPlayProfiles>
+ <TranscodingProfiles>
+ <TranscodingProfile container="mp3" type="Audio" audioCodec="mp3" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="ts" type="Video" videoCodec="h264" audioCodec="aac" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ <TranscodingProfile container="jpeg" type="Photo" estimateContentLength="false" enableMpegtsM2TsMode="false" transcodeSeekInfo="Auto" context="Streaming" />
+ </TranscodingProfiles>
+ <ContainerProfiles />
+ <CodecProfiles />
+ <ResponseProfiles />
+ <SubtitleProfiles />
+</Profile> \ No newline at end of file
diff --git a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
index 3d7e745f8..a2ab33b4e 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/WDTV Live.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>true</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
index ae0f53edb..69d091e47 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox 360.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>12.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
index d22356646..1aa2b9198 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Xbox One.xml
@@ -15,7 +15,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
index 1418e63bd..c2095cf83 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/foobar2000.xml
@@ -14,7 +14,6 @@
<ModelDescription>Emby</ModelDescription>
<ModelNumber>Emby</ModelNumber>
<ModelUrl>http://emby.media/</ModelUrl>
- <IgnoreTranscodeByteRangeRequests>false</IgnoreTranscodeByteRangeRequests>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>false</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio</SupportedMediaTypes>
diff --git a/MediaBrowser.Dlna/Service/BaseControlHandler.cs b/MediaBrowser.Dlna/Service/BaseControlHandler.cs
index a17182a7e..a65520d65 100644
--- a/MediaBrowser.Dlna/Service/BaseControlHandler.cs
+++ b/MediaBrowser.Dlna/Service/BaseControlHandler.cs
@@ -27,14 +27,16 @@ namespace MediaBrowser.Dlna.Service
{
try
{
- if (Config.GetDlnaConfiguration().EnableDebugLogging)
+ var enableDebugLogging = Config.GetDlnaConfiguration().EnableDebugLogging;
+
+ if (enableDebugLogging)
{
LogRequest(request);
}
var response = ProcessControlRequestInternal(request);
- if (Config.GetDlnaConfiguration().EnableDebugLogging)
+ if (enableDebugLogging)
{
LogResponse(response);
}
diff --git a/MediaBrowser.Dlna/Ssdp/Datagram.cs b/MediaBrowser.Dlna/Ssdp/Datagram.cs
index ae79ab44f..4a0bb6f48 100644
--- a/MediaBrowser.Dlna/Ssdp/Datagram.cs
+++ b/MediaBrowser.Dlna/Ssdp/Datagram.cs
@@ -12,13 +12,15 @@ namespace MediaBrowser.Dlna.Ssdp
public EndPoint FromEndPoint { get; private set; }
public string Message { get; private set; }
public bool IgnoreBindFailure { get; private set; }
+ public bool EnableDebugLogging { get; private set; }
private readonly ILogger _logger;
- public Datagram(EndPoint toEndPoint, EndPoint fromEndPoint, ILogger logger, string message, bool ignoreBindFailure)
+ public Datagram(EndPoint toEndPoint, EndPoint fromEndPoint, ILogger logger, string message, bool ignoreBindFailure, bool enableDebugLogging)
{
Message = message;
_logger = logger;
+ EnableDebugLogging = enableDebugLogging;
IgnoreBindFailure = ignoreBindFailure;
FromEndPoint = fromEndPoint;
ToEndPoint = toEndPoint;
@@ -37,8 +39,13 @@ namespace MediaBrowser.Dlna.Ssdp
{
client.Bind(FromEndPoint);
}
- catch
+ catch (Exception ex)
{
+ if (EnableDebugLogging)
+ {
+ _logger.ErrorException("Error binding datagram socket", ex);
+ }
+
if (!IgnoreBindFailure) throw;
}
}
@@ -51,7 +58,7 @@ namespace MediaBrowser.Dlna.Ssdp
}
catch (Exception ex)
{
- if (!IgnoreBindFailure)
+ if (!IgnoreBindFailure || EnableDebugLogging)
{
_logger.ErrorException("Error sending Datagram to {0} from {1}: " + Message, ex, ToEndPoint, FromEndPoint == null ? "" : FromEndPoint.ToString());
}
@@ -62,8 +69,12 @@ namespace MediaBrowser.Dlna.Ssdp
{
client.Close();
}
- catch (Exception)
+ catch (Exception ex)
{
+ if (EnableDebugLogging)
+ {
+ _logger.ErrorException("Error closing datagram socket", ex);
+ }
}
}
}, null);
diff --git a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
index 3dd482e64..94342bf31 100644
--- a/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
+++ b/MediaBrowser.Dlna/Ssdp/DeviceDiscovery.cs
@@ -1,5 +1,4 @@
using MediaBrowser.Common.Events;
-using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Dlna;
@@ -143,7 +142,10 @@ namespace MediaBrowser.Dlna.Ssdp
args.EndPoint = endPoint;
args.LocalIp = localIp;
- TryCreateDevice(args);
+ if (!_ssdpHandler.IsSelfNotification(args))
+ {
+ TryCreateDevice(args);
+ }
}
}
@@ -203,18 +205,25 @@ namespace MediaBrowser.Dlna.Ssdp
string nts;
args.Headers.TryGetValue("NTS", out nts);
+ if (String.Equals(nts, "ssdp:byebye", StringComparison.OrdinalIgnoreCase))
+ {
+ if (String.Equals(args.Method, "NOTIFY", StringComparison.OrdinalIgnoreCase))
+ {
+ if (!_disposed)
+ {
+ EventHelper.FireEventIfNotNull(DeviceLeft, this, args, _logger);
+ }
+ }
+
+ return;
+ }
+
string usn;
if (!args.Headers.TryGetValue("USN", out usn)) usn = string.Empty;
string nt;
if (!args.Headers.TryGetValue("NT", out nt)) nt = string.Empty;
- // Ignore when a device is indicating it's shutting down
- if (string.Equals(nts, "ssdp:byebye", StringComparison.OrdinalIgnoreCase))
- {
- return;
- }
-
// Need to be able to download device description
string location;
if (!args.Headers.TryGetValue("Location", out location) ||
diff --git a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
index 5b3746aeb..28ea5ad6c 100644
--- a/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
+++ b/MediaBrowser.Dlna/Ssdp/SsdpHandler.cs
@@ -67,7 +67,7 @@ namespace MediaBrowser.Dlna.Ssdp
}
return String.Format(
- "{0}{1}/{2}.{3} UPnP/1.0 DLNADOC/1.5 MediaBrowser/{4}",
+ "{0}{1}/{2}.{3} UPnP/1.0 DLNADOC/1.5 Emby/{4}",
pstring,
IntPtr.Size * 8,
os.Version.Major,
@@ -88,24 +88,21 @@ namespace MediaBrowser.Dlna.Ssdp
private async void OnMessageReceived(SsdpMessageEventArgs args)
{
- if (string.Equals(args.Method, "M-SEARCH", StringComparison.OrdinalIgnoreCase))
- {
- var headers = args.Headers;
+ var headers = args.Headers;
+ string st;
+ if (string.Equals(args.Method, "M-SEARCH", StringComparison.OrdinalIgnoreCase) && headers.TryGetValue("st", out st))
+ {
TimeSpan delay = GetSearchDelay(headers);
-
+
if (_config.GetDlnaConfiguration().EnableDebugLogging)
{
_logger.Debug("Delaying search response by {0} seconds", delay.TotalSeconds);
}
-
+
await Task.Delay(delay).ConfigureAwait(false);
- string st;
- if (headers.TryGetValue("st", out st))
- {
- RespondToSearch(args.EndPoint, st);
- }
+ RespondToSearch(args.EndPoint, st);
}
EventHelper.FireEventIfNotNull(MessageReceived, this, args, _logger);
@@ -166,9 +163,11 @@ namespace MediaBrowser.Dlna.Ssdp
var msg = new SsdpMessageBuilder().BuildMessage(header, values);
var queued = false;
+ var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLogging;
+
for (var i = 0; i < sendCount; i++)
{
- var dgram = new Datagram(endpoint, localAddress, _logger, msg, ignoreBindFailure);
+ var dgram = new Datagram(endpoint, localAddress, _logger, msg, ignoreBindFailure, enableDebugLogging);
if (_messageQueue.Count == 0)
{
@@ -212,10 +211,9 @@ namespace MediaBrowser.Dlna.Ssdp
private void RespondToSearch(EndPoint endpoint, string deviceType)
{
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
- {
- _logger.Debug("RespondToSearch");
- }
+ var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLogging;
+
+ var isLogged = false;
const string header = "HTTP/1.1 200 OK";
@@ -224,6 +222,15 @@ namespace MediaBrowser.Dlna.Ssdp
if (string.Equals(deviceType, "ssdp:all", StringComparison.OrdinalIgnoreCase) ||
string.Equals(deviceType, d.Type, StringComparison.OrdinalIgnoreCase))
{
+ if (!isLogged)
+ {
+ if (enableDebugLogging)
+ {
+ _logger.Debug("Responding to search from {0} for {1}", endpoint, deviceType);
+ }
+ isLogged = true;
+ }
+
var values = new Dictionary<string, string>(StringComparer.OrdinalIgnoreCase);
values["CACHE-CONTROL"] = "max-age = 600";
@@ -238,7 +245,7 @@ namespace MediaBrowser.Dlna.Ssdp
SendDatagram(header, values, endpoint, new IPEndPoint(d.Address, 0), true, 1);
//SendDatagram(header, values, endpoint, null, true);
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
+ if (enableDebugLogging)
{
_logger.Debug("{1} - Responded to a {0} request to {2}", d.Type, endpoint, d.Address.ToString());
}
@@ -316,7 +323,9 @@ namespace MediaBrowser.Dlna.Ssdp
var received = (byte[])result.AsyncState;
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
+ var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLogging;
+
+ if (enableDebugLogging)
{
_logger.Debug(Encoding.ASCII.GetString(received));
}
@@ -324,7 +333,12 @@ namespace MediaBrowser.Dlna.Ssdp
var args = SsdpHelper.ParseSsdpResponse(received);
args.EndPoint = endpoint;
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
+ if (IsSelfNotification(args))
+ {
+ return;
+ }
+
+ if (enableDebugLogging)
{
var headerTexts = args.Headers.Select(i => string.Format("{0}={1}", i.Key, i.Value));
var headerText = string.Join(",", headerTexts.ToArray());
@@ -345,6 +359,44 @@ namespace MediaBrowser.Dlna.Ssdp
}
}
+ internal bool IsSelfNotification(SsdpMessageEventArgs args)
+ {
+ // Avoid responding to self search messages
+ //string serverId;
+ //if (args.Headers.TryGetValue("X-EMBYSERVERID", out serverId) &&
+ // string.Equals(serverId, _appHost.SystemId, StringComparison.OrdinalIgnoreCase))
+ //{
+ // return true;
+ //}
+
+ string server;
+ args.Headers.TryGetValue("SERVER", out server);
+
+ if (string.Equals(server, _serverSignature, StringComparison.OrdinalIgnoreCase))
+ {
+ return true;
+ }
+ return false;
+ //string usn;
+ //args.Headers.TryGetValue("USN", out usn);
+
+ //if (string.IsNullOrWhiteSpace(usn))
+ //{
+ // return false;
+ //}
+
+ //_logger.Debug("IsSelfNotification test: " + usn);
+
+ //return RegisteredDevices.Any(i =>
+ //{
+ // var isSameDevice = string.Equals(usn, i.USN, StringComparison.OrdinalIgnoreCase) ||
+ // i.USN.IndexOf(usn, StringComparison.OrdinalIgnoreCase) != 1 ||
+ // usn.IndexOf(i.USN, StringComparison.OrdinalIgnoreCase) != 1;
+
+ // return isSameDevice;
+ //});
+ }
+
public void Dispose()
{
_config.NamedConfigurationUpdated -= _config_ConfigurationUpdated;
@@ -399,17 +451,19 @@ namespace MediaBrowser.Dlna.Ssdp
private void NotifyAll()
{
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
+ var enableDebugLogging = _config.GetDlnaConfiguration().EnableDebugLogging;
+
+ if (enableDebugLogging)
{
_logger.Debug("Sending alive notifications");
}
foreach (var d in RegisteredDevices)
{
- NotifyDevice(d, "alive", 1);
+ NotifyDevice(d, "alive", 1, enableDebugLogging);
}
}
- private void NotifyDevice(UpnpDevice dev, string type, int sendCount)
+ private void NotifyDevice(UpnpDevice dev, string type, int sendCount, bool logMessage)
{
const string header = "NOTIFY * HTTP/1.1";
@@ -424,7 +478,7 @@ namespace MediaBrowser.Dlna.Ssdp
values["NT"] = dev.Type;
values["USN"] = dev.USN;
- if (_config.GetDlnaConfiguration().EnableDebugLogging)
+ if (logMessage)
{
_logger.Debug("{0} said {1}", dev.USN, type);
}
@@ -457,7 +511,7 @@ namespace MediaBrowser.Dlna.Ssdp
foreach (var d in dl.ToList())
{
- NotifyDevice(d, "byebye", 2);
+ NotifyDevice(d, "byebye", 2, true);
}
_logger.Debug("Unregistered mount {0}", uuid);
@@ -468,13 +522,15 @@ namespace MediaBrowser.Dlna.Ssdp
private int _aliveNotifierIntervalMs;
private void ReloadAliveNotifier()
{
- if (!_config.GetDlnaConfiguration().BlastAliveMessages)
+ var config = _config.GetDlnaConfiguration();
+
+ if (!config.BlastAliveMessages)
{
DisposeNotificationTimer();
return;
}
- var intervalMs = _config.GetDlnaConfiguration().BlastAliveMessageIntervalSeconds * 1000;
+ var intervalMs = config.BlastAliveMessageIntervalSeconds * 1000;
if (_notificationTimer == null || _aliveNotifierIntervalMs != intervalMs)
{
diff --git a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
index c30ceb62d..e25537362 100644
--- a/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/BaseEncoder.cs
@@ -840,7 +840,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
- filters.Add(string.Format("scale=trunc(min(iw\\,{0})/2)*2:trunc(min((iw/dar)\\,{1})/2)*2", maxWidthParam, maxHeightParam));
+ filters.Add(string.Format("scale=trunc(min(max(iw\\,ih*dar)\\,min({0}\\,{1}*dar))/2)*2:trunc(min(max(iw/dar\\,ih)\\,min({0}/dar\\,{1}))/2)*2", maxWidthParam, maxHeightParam));
}
// If a fixed width was requested
@@ -860,7 +860,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
// If a max width was requested
- else if (request.MaxWidth.HasValue && (!request.MaxHeight.HasValue || state.VideoStream == null))
+ else if (request.MaxWidth.HasValue)
{
var maxWidthParam = request.MaxWidth.Value.ToString(UsCulture);
@@ -868,35 +868,13 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
// If a max height was requested
- else if (request.MaxHeight.HasValue && (!request.MaxWidth.HasValue || state.VideoStream == null))
+ else if (request.MaxHeight.HasValue)
{
var maxHeightParam = request.MaxHeight.Value.ToString(UsCulture);
filters.Add(string.Format("scale=trunc(oh*a*2)/2:min(ih\\,{0})", maxHeightParam));
}
- else if (request.MaxWidth.HasValue ||
- request.MaxHeight.HasValue ||
- request.Width.HasValue ||
- request.Height.HasValue)
- {
- if (state.VideoStream != null)
- {
- // Need to perform calculations manually
-
- // Try to account for bad media info
- var currentHeight = state.VideoStream.Height ?? request.MaxHeight ?? request.Height ?? 0;
- var currentWidth = state.VideoStream.Width ?? request.MaxWidth ?? request.Width ?? 0;
-
- var outputSize = DrawingUtils.Resize(currentWidth, currentHeight, request.Width, request.Height, request.MaxWidth, request.MaxHeight);
-
- var manualWidthParam = outputSize.Width.ToString(UsCulture);
- var manualHeightParam = outputSize.Height.ToString(UsCulture);
-
- filters.Add(string.Format("scale=trunc({0}/2)*2:trunc({1}/2)*2", manualWidthParam, manualHeightParam));
- }
- }
-
var output = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream)
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index a01f37f91..4d5b669e2 100644
--- a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
@@ -199,82 +199,83 @@ namespace MediaBrowser.MediaEncoding.Encoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
- var processWrapper = new ProcessWrapper(process, this);
-
- try
- {
- StartProcess(processWrapper);
- }
- catch (Exception ex)
+ using (var processWrapper = new ProcessWrapper(process, this))
{
- _ffProbeResourcePool.Release();
+ try
+ {
+ StartProcess(processWrapper);
+ }
+ catch (Exception ex)
+ {
+ _ffProbeResourcePool.Release();
- _logger.ErrorException("Error starting ffprobe", ex);
+ _logger.ErrorException("Error starting ffprobe", ex);
- throw;
- }
+ throw;
+ }
- try
- {
- process.BeginErrorReadLine();
+ try
+ {
+ process.BeginErrorReadLine();
- var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
+ var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
- if (result != null)
- {
- if (result.streams != null)
+ if (result != null)
{
- // Normalize aspect ratio if invalid
- foreach (var stream in result.streams)
+ if (result.streams != null)
{
- if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
- {
- stream.display_aspect_ratio = string.Empty;
- }
- if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
+ // Normalize aspect ratio if invalid
+ foreach (var stream in result.streams)
{
- stream.sample_aspect_ratio = string.Empty;
+ if (string.Equals(stream.display_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
+ {
+ stream.display_aspect_ratio = string.Empty;
+ }
+ if (string.Equals(stream.sample_aspect_ratio, "0:1", StringComparison.OrdinalIgnoreCase))
+ {
+ stream.sample_aspect_ratio = string.Empty;
+ }
}
}
- }
- var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol);
+ var mediaInfo = new ProbeResultNormalizer(_logger, FileSystem).GetMediaInfo(result, videoType, isAudio, primaryPath, protocol);
- if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue)
- {
- foreach (var stream in mediaInfo.MediaStreams)
+ if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue)
{
- if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase))
+ foreach (var stream in mediaInfo.MediaStreams)
{
- try
- {
- //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken)
- // .ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
-
- }
- catch (Exception ex)
+ if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase))
{
- _logger.ErrorException("Error getting key frame interval", ex);
+ try
+ {
+ //stream.KeyFrames = await GetKeyFrames(inputPath, stream.Index, cancellationToken)
+ // .ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
+ {
+
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error getting key frame interval", ex);
+ }
}
}
}
- }
- return mediaInfo;
+ return mediaInfo;
+ }
}
- }
- catch
- {
- StopProcess(processWrapper, 100, true);
+ catch
+ {
+ StopProcess(processWrapper, 100, true);
- throw;
- }
- finally
- {
- _ffProbeResourcePool.Release();
+ throw;
+ }
+ finally
+ {
+ _ffProbeResourcePool.Release();
+ }
}
throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath));
@@ -307,31 +308,32 @@ namespace MediaBrowser.MediaEncoding.Encoder
_logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
- var processWrapper = new ProcessWrapper(process, this);
-
- StartProcess(processWrapper);
+ using (var processWrapper = new ProcessWrapper(process, this))
+ {
+ StartProcess(processWrapper);
- var lines = new List<int>();
+ var lines = new List<int>();
- try
- {
- process.BeginErrorReadLine();
+ try
+ {
+ process.BeginErrorReadLine();
- await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false);
- }
- catch (OperationCanceledException)
- {
- if (cancellationToken.IsCancellationRequested)
+ await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false);
+ }
+ catch (OperationCanceledException)
{
- throw;
+ if (cancellationToken.IsCancellationRequested)
+ {
+ throw;
+ }
+ }
+ finally
+ {
+ StopProcess(processWrapper, 100, true);
}
- }
- finally
- {
- StopProcess(processWrapper, 100, true);
- }
- return lines;
+ return lines;
+ }
}
private async Task StartReadingOutput(Stream source, List<int> lines, int timeoutMs, CancellationToken cancellationToken)
@@ -490,51 +492,53 @@ namespace MediaBrowser.MediaEncoding.Encoder
await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
- var processWrapper = new ProcessWrapper(process, this);
- bool ranToCompletion;
+ using (var processWrapper = new ProcessWrapper(process, this))
+ {
+ bool ranToCompletion;
- var memoryStream = new MemoryStream();
+ var memoryStream = new MemoryStream();
- try
- {
- StartProcess(processWrapper);
+ try
+ {
+ StartProcess(processWrapper);
#pragma warning disable 4014
- // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
- process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
+ // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
+ process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
#pragma warning restore 4014
- // MUST read both stdout and stderr asynchronously or a deadlock may occurr
- process.BeginErrorReadLine();
+ // MUST read both stdout and stderr asynchronously or a deadlock may occurr
+ process.BeginErrorReadLine();
- ranToCompletion = process.WaitForExit(10000);
+ ranToCompletion = process.WaitForExit(10000);
- if (!ranToCompletion)
+ if (!ranToCompletion)
+ {
+ StopProcess(processWrapper, 1000, false);
+ }
+
+ }
+ finally
{
- StopProcess(processWrapper, 1000, false);
+ resourcePool.Release();
}
- }
- finally
- {
- resourcePool.Release();
- }
+ var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
- var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
+ if (exitCode == -1 || memoryStream.Length == 0)
+ {
+ memoryStream.Dispose();
- if (exitCode == -1 || memoryStream.Length == 0)
- {
- memoryStream.Dispose();
+ var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath);
- var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath);
+ _logger.Error(msg);
- _logger.Error(msg);
+ throw new ApplicationException(msg);
+ }
- throw new ApplicationException(msg);
+ memoryStream.Position = 0;
+ return memoryStream;
}
-
- memoryStream.Position = 0;
- return memoryStream;
}
public string GetTimeParameter(long ticks)
@@ -603,55 +607,56 @@ namespace MediaBrowser.MediaEncoding.Encoder
bool ranToCompletion = false;
- var processWrapper = new ProcessWrapper(process, this);
-
- try
+ using (var processWrapper = new ProcessWrapper(process, this))
{
- StartProcess(processWrapper);
+ try
+ {
+ StartProcess(processWrapper);
- // Need to give ffmpeg enough time to make all the thumbnails, which could be a while,
- // but we still need to detect if the process hangs.
- // Making the assumption that as long as new jpegs are showing up, everything is good.
+ // Need to give ffmpeg enough time to make all the thumbnails, which could be a while,
+ // but we still need to detect if the process hangs.
+ // Making the assumption that as long as new jpegs are showing up, everything is good.
- bool isResponsive = true;
- int lastCount = 0;
+ bool isResponsive = true;
+ int lastCount = 0;
- while (isResponsive)
- {
- if (process.WaitForExit(30000))
+ while (isResponsive)
{
- ranToCompletion = true;
- break;
- }
+ if (process.WaitForExit(30000))
+ {
+ ranToCompletion = true;
+ break;
+ }
+
+ cancellationToken.ThrowIfCancellationRequested();
- cancellationToken.ThrowIfCancellationRequested();
+ var jpegCount = Directory.GetFiles(targetDirectory)
+ .Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase));
- var jpegCount = Directory.GetFiles(targetDirectory)
- .Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase));
+ isResponsive = (jpegCount > lastCount);
+ lastCount = jpegCount;
+ }
- isResponsive = (jpegCount > lastCount);
- lastCount = jpegCount;
+ if (!ranToCompletion)
+ {
+ StopProcess(processWrapper, 1000, false);
+ }
}
-
- if (!ranToCompletion)
+ finally
{
- StopProcess(processWrapper, 1000, false);
+ resourcePool.Release();
}
- }
- finally
- {
- resourcePool.Release();
- }
- var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
+ var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
- if (exitCode == -1)
- {
- var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument);
+ if (exitCode == -1)
+ {
+ var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument);
- _logger.Error(msg);
+ _logger.Error(msg);
- throw new ApplicationException(msg);
+ throw new ApplicationException(msg);
+ }
}
}
@@ -781,7 +786,7 @@ namespace MediaBrowser.MediaEncoding.Encoder
}
}
- private class ProcessWrapper
+ private class ProcessWrapper : IDisposable
{
public readonly Process Process;
public bool HasExited;
@@ -810,6 +815,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
process.Dispose();
}
+
+ private bool _disposed;
+ private readonly object _syncLock = new object();
+ public void Dispose()
+ {
+ lock (_syncLock)
+ {
+ if (!_disposed)
+ {
+ if (Process != null)
+ {
+ Process.Exited -= Process_Exited;
+ Process.Dispose();
+ }
+ }
+
+ _disposed = true;
+ }
+ }
}
}
}
diff --git a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
index 26d4a7650..49eed9ee5 100644
--- a/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Encoder/VideoEncoder.cs
@@ -1,8 +1,6 @@
using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Channels;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Library;
-using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Controller.Session;
using MediaBrowser.Model.Dlna;
diff --git a/MediaBrowser.Model/Configuration/ServerConfiguration.cs b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
index 8a3a2a3e4..2833e7167 100644
--- a/MediaBrowser.Model/Configuration/ServerConfiguration.cs
+++ b/MediaBrowser.Model/Configuration/ServerConfiguration.cs
@@ -158,7 +158,7 @@ namespace MediaBrowser.Model.Configuration
/// different directories and files.
/// </summary>
/// <value>The file watcher delay.</value>
- public int RealtimeMonitorDelay { get; set; }
+ public int RealtimeLibraryMonitorDelay { get; set; }
/// <summary>
/// Gets or sets a value indicating whether [enable dashboard response caching].
@@ -233,7 +233,7 @@ namespace MediaBrowser.Model.Configuration
// 5 minutes
MinResumeDurationSeconds = 300;
- RealtimeMonitorDelay = 30;
+ RealtimeLibraryMonitorDelay = 40;
EnableInternetProviders = true;
FindInternetTrailers = true;
@@ -261,8 +261,6 @@ namespace MediaBrowser.Model.Configuration
"Chromecast",
"iOS",
"Unknown app",
- "MediaPortal",
- "Media Portal",
"iPad",
"iPhone",
"Windows Phone"
diff --git a/MediaBrowser.Model/Dlna/CodecProfile.cs b/MediaBrowser.Model/Dlna/CodecProfile.cs
index c2d36dc79..7200f648c 100644
--- a/MediaBrowser.Model/Dlna/CodecProfile.cs
+++ b/MediaBrowser.Model/Dlna/CodecProfile.cs
@@ -14,6 +14,9 @@ namespace MediaBrowser.Model.Dlna
[XmlAttribute("codec")]
public string Codec { get; set; }
+ [XmlAttribute("container")]
+ public string Container { get; set; }
+
public CodecProfile()
{
Conditions = new ProfileCondition[] {};
@@ -29,8 +32,30 @@ namespace MediaBrowser.Model.Dlna
return list;
}
- public bool ContainsCodec(string codec)
+ public List<string> GetContainers()
+ {
+ List<string> list = new List<string>();
+ foreach (string i in (Container ?? string.Empty).Split(','))
+ {
+ if (!string.IsNullOrEmpty(i)) list.Add(i);
+ }
+ return list;
+ }
+
+ private bool ContainsContainer(string container)
+ {
+ List<string> containers = GetContainers();
+
+ return containers.Count == 0 || ListHelper.ContainsIgnoreCase(containers, container ?? string.Empty);
+ }
+
+ public bool ContainsCodec(string codec, string container)
{
+ if (!ContainsContainer(container))
+ {
+ return false;
+ }
+
List<string> codecs = GetCodecs();
return codecs.Count == 0 || ListHelper.ContainsIgnoreCase(codecs, codec);
diff --git a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index 3a798e3fe..62463d196 100644
--- a/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
+++ b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
@@ -1,4 +1,5 @@
using MediaBrowser.Model.MediaInfo;
+using System;
using System.Collections.Generic;
namespace MediaBrowser.Model.Dlna
@@ -164,7 +165,7 @@ namespace MediaBrowser.Model.Dlna
if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn))
{
- orgPnValues.Add(mediaProfile.OrgPn);
+ orgPnValues.AddRange(mediaProfile.OrgPn.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
}
else
{
diff --git a/MediaBrowser.Model/Dlna/DeviceProfile.cs b/MediaBrowser.Model/Dlna/DeviceProfile.cs
index a78724bf2..752b4d179 100644
--- a/MediaBrowser.Model/Dlna/DeviceProfile.cs
+++ b/MediaBrowser.Model/Dlna/DeviceProfile.cs
@@ -34,7 +34,6 @@ namespace MediaBrowser.Model.Dlna
public string ModelNumber { get; set; }
public string ModelUrl { get; set; }
public string SerialNumber { get; set; }
- public bool IgnoreTranscodeByteRangeRequests { get; set; }
public bool EnableAlbumArtInDidl { get; set; }
public bool EnableSingleAlbumArtLimit { get; set; }
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 715752d05..8400b204f 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -131,7 +131,7 @@ namespace MediaBrowser.Model.Dlna
List<ProfileCondition> conditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
- if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec))
+ if (i.Type == CodecType.Audio && i.ContainsCodec(audioCodec, item.Container))
{
foreach (ProfileCondition c in i.Conditions)
{
@@ -206,7 +206,7 @@ namespace MediaBrowser.Model.Dlna
List<CodecProfile> audioCodecProfiles = new List<CodecProfile>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
- if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec))
+ if (i.Type == CodecType.Audio && i.ContainsCodec(transcodingProfile.AudioCodec, transcodingProfile.Container))
{
audioCodecProfiles.Add(i);
}
@@ -423,7 +423,7 @@ namespace MediaBrowser.Model.Dlna
List<ProfileCondition> videoTranscodingConditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
- if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec))
+ if (i.Type == CodecType.Video && i.ContainsCodec(transcodingProfile.VideoCodec, transcodingProfile.Container))
{
foreach (ProfileCondition c in i.Conditions)
{
@@ -437,7 +437,7 @@ namespace MediaBrowser.Model.Dlna
List<ProfileCondition> audioTranscodingConditions = new List<ProfileCondition>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
{
- if (i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec))
+ if (i.Type == CodecType.VideoAudio && i.ContainsCodec(transcodingProfile.AudioCodec, transcodingProfile.Container))
{
foreach (ProfileCondition c in i.Conditions)
{
@@ -600,7 +600,7 @@ namespace MediaBrowser.Model.Dlna
conditions = new List<ProfileCondition>();
foreach (CodecProfile i in profile.CodecProfiles)
{
- if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec))
+ if (i.Type == CodecType.Video && i.ContainsCodec(videoCodec, container))
{
foreach (ProfileCondition c in i.Conditions)
{
@@ -635,7 +635,7 @@ namespace MediaBrowser.Model.Dlna
conditions = new List<ProfileCondition>();
foreach (CodecProfile i in profile.CodecProfiles)
{
- if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec))
+ if (i.Type == CodecType.VideoAudio && i.ContainsCodec(audioCodec, container))
{
foreach (ProfileCondition c in i.Conditions)
{
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index fc47b0259..92fc1c2a8 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -38,13 +38,16 @@ namespace MediaBrowser.Providers.Manager
{
var hasChanges = false;
- var images = providers.OfType<ILocalImageFileProvider>()
- .SelectMany(i => i.GetImages(item, directoryService))
- .ToList();
-
- if (MergeImages(item, images))
+ if (!(item is Photo))
{
- hasChanges = true;
+ var images = providers.OfType<ILocalImageFileProvider>()
+ .SelectMany(i => i.GetImages(item, directoryService))
+ .ToList();
+
+ if (MergeImages(item, images))
+ {
+ hasChanges = true;
+ }
}
return hasChanges;
@@ -419,19 +422,14 @@ namespace MediaBrowser.Providers.Manager
var changed = false;
var newImages = images.Where(i => i.Type == type).ToList();
- if (newImages.Count > 0)
- {
- var newImageFileInfos = images.Where(i => i.Type == type)
+
+ var newImageFileInfos = newImages
.Select(i => i.FileInfo)
.ToList();
- if (newImageFileInfos.Count > 0)
- {
- if (item.AddImages(type, newImageFileInfos))
- {
- changed = true;
- }
- }
+ if (item.AddImages(type, newImageFileInfos))
+ {
+ changed = true;
}
return changed;
diff --git a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
index 99be102f8..bd83862a8 100644
--- a/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
+++ b/MediaBrowser.Providers/MediaInfo/AudioImageProvider.cs
@@ -93,7 +93,7 @@ namespace MediaBrowser.Providers.MediaInfo
private string GetAudioImagePath(Audio item)
{
- var album = item.Parent as MusicAlbum;
+ var album = item.AlbumEntity;
var filename = item.Album ?? string.Empty;
filename += string.Join(",", item.Artists.ToArray());
diff --git a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
index cbd3f0af0..68601b6b2 100644
--- a/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
+++ b/MediaBrowser.Providers/TV/TvdbEpisodeProvider.cs
@@ -5,6 +5,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Entities;
+using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Providers;
using System;
using System.Collections.Generic;
@@ -29,12 +30,14 @@ namespace MediaBrowser.Providers.TV
private readonly IFileSystem _fileSystem;
private readonly IServerConfigurationManager _config;
private readonly IHttpClient _httpClient;
+ private readonly ILogger _logger;
- public TvdbEpisodeProvider(IFileSystem fileSystem, IServerConfigurationManager config, IHttpClient httpClient)
+ public TvdbEpisodeProvider(IFileSystem fileSystem, IServerConfigurationManager config, IHttpClient httpClient, ILogger logger)
{
_fileSystem = fileSystem;
_config = config;
_httpClient = httpClient;
+ _logger = logger;
Current = this;
}
@@ -100,7 +103,8 @@ namespace MediaBrowser.Providers.TV
try
{
- result.Item = FetchEpisodeData(searchInfo, identity, seriesDataPath, searchInfo.SeriesProviderIds, cancellationToken);
+ result.Item = FetchEpisodeData(searchInfo, identity, seriesDataPath, searchInfo.SeriesProviderIds,
+ cancellationToken);
result.HasMetadata = result.Item != null;
}
catch (FileNotFoundException)
@@ -112,6 +116,10 @@ namespace MediaBrowser.Providers.TV
// Don't fail the provider because this will just keep on going and going.
}
}
+ else
+ {
+ _logger.Debug("No series identity found for {0}", searchInfo.Name);
+ }
return result;
}
@@ -265,7 +273,6 @@ namespace MediaBrowser.Providers.TV
FetchMainEpisodeInfo(episode, file, cancellationToken);
usingAbsoluteData = true;
- success = true;
}
var end = identity.IndexNumberEnd ?? episodeNumber;
@@ -298,7 +305,7 @@ namespace MediaBrowser.Providers.TV
episodeNumber++;
}
- return success ? episode : null;
+ return episode;
}
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
diff --git a/MediaBrowser.Server.Implementations/Dto/DtoService.cs b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
index 402bd4d98..1b55f47d5 100644
--- a/MediaBrowser.Server.Implementations/Dto/DtoService.cs
+++ b/MediaBrowser.Server.Implementations/Dto/DtoService.cs
@@ -1193,7 +1193,7 @@ namespace MediaBrowser.Server.Implementations.Dto
{
dto.Album = audio.Album;
- var albumParent = audio.FindParent<MusicAlbum>();
+ var albumParent = audio.AlbumEntity;
if (albumParent != null)
{
@@ -1208,15 +1208,6 @@ namespace MediaBrowser.Server.Implementations.Dto
//}
}
- var album = item as MusicAlbum;
-
- if (album != null)
- {
- dto.SoundtrackIds = album.SoundtrackIds
- .Select(i => i.ToString("N"))
- .ToArray();
- }
-
var hasArtist = item as IHasArtist;
if (hasArtist != null)
{
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index d501d1210..2d4770fac 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -84,7 +84,7 @@ namespace MediaBrowser.Server.Implementations.IO
// This is an arbitraty amount of time, but delay it because file system writes often trigger events after RemoveTempIgnore has been called.
// Seeing long delays in some situations, especially over the network.
// Seeing delays up to 40 seconds, but not going to ignore changes for that long.
- await Task.Delay(1500).ConfigureAwait(false);
+ await Task.Delay(5000).ConfigureAwait(false);
string val;
_tempIgnoredPaths.TryRemove(path, out val);
@@ -437,11 +437,11 @@ namespace MediaBrowser.Server.Implementations.IO
{
if (_updateTimer == null)
{
- _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeMonitorDelay), TimeSpan.FromMilliseconds(-1));
+ _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeLibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
}
else
{
- _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeMonitorDelay), TimeSpan.FromMilliseconds(-1));
+ _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.RealtimeLibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
}
}
}
@@ -560,7 +560,7 @@ namespace MediaBrowser.Server.Implementations.IO
/// <returns>Task.</returns>
private async Task ProcessPathChanges(List<string> paths)
{
- var itemsToRefresh = paths.Select(Path.GetDirectoryName)
+ var itemsToRefresh = paths
.Select(GetAffectedBaseItem)
.Where(item => item != null)
.Distinct()
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index 02e1795f3..5012f2479 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -281,10 +281,10 @@ namespace MediaBrowser.Server.Implementations.Library
if (newValue >= maxCount)
{
- _logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture));
- user.Policy.IsDisabled = true;
+ //_logger.Debug("Disabling user {0} due to {1} unsuccessful login attempts.", user.Name, newValue.ToString(CultureInfo.InvariantCulture));
+ //user.Policy.IsDisabled = true;
- fireLockout = true;
+ //fireLockout = true;
}
await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false);
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
index ea141645c..2dff86fce 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/cs.json
@@ -387,7 +387,6 @@
"ButtonSignOut": "Sign Out",
"ButtonMyProfile": "My Profile",
"ButtonMyPreferences": "My Preferences",
- "MessageBrowserDoesNotSupportWebSockets": "This browser does not support web sockets. For a better experience, try a newer browser such as Chrome, Firefox, IE10+, Safari (iOS) or Opera.",
"LabelInstallingPackage": "Installing {0}",
"LabelPackageInstallCompleted": "{0} installation completed.",
"LabelPackageInstallFailed": "{0} installation failed.",
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index c15e520e2..ad6b159e7 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -440,7 +440,7 @@
"HeaderVideo": "Video",
"HeaderRuntime": "Runtime",
"HeaderCommunityRating": "Community rating",
- "HeaderPasswordReset": "Password Reset",
+ "HeaderPasswordReset": "Password Reset",
"HeaderParentalRating": "Parental rating",
"HeaderReleaseDate": "Release date",
"HeaderDateAdded": "Date added",
@@ -766,5 +766,10 @@
"SyncJobItemStatusRemovedFromDevice": "Removed from device",
"SyncJobItemStatusCancelled": "Cancelled",
"LabelProfile": "Profile:",
- "LabelBitrateMbps": "Bitrate (Mbps):"
+ "LabelBitrateMbps": "Bitrate (Mbps):",
+ "EmbyIntroDownloadMessage": "To download and install Emby Server visit {0}.",
+ "ButtonNewServer": "New Server",
+ "ButtonSignInWithConnect": "Sign in with Emby Connect",
+ "HeaderNewServer": "New Server",
+ "MyDevice": "My Device"
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index caff2426a..368d11646 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -882,7 +882,7 @@
"MessageNoSubtitleSearchResultsFound": "No search results founds.",
"TabDisplay": "Display",
"TabLanguages": "Languages",
- "TabWebClient": "Web Client",
+ "TabAppSettings": "App Settings",
"LabelEnableThemeSongs": "Enable theme songs",
"LabelEnableBackdrops": "Enable backdrops",
"LabelEnableThemeSongsHelp": "If enabled, theme songs will be played in the background while browsing the library.",
@@ -1436,10 +1436,17 @@
"LabelSelectViewStyles": "Enable enhanced presentations for:",
"LabelSelectViewStylesHelp": "If enabled, views will be built with metadata to offer categories such as Suggestions, Latest, Genres, and more. If disabled, they'll be displayed with simple folders.",
"TabPhotos": "Photos",
- "TabVideos": "Videos",
- "OptionReportList": "List View",
- "OptionReportStatistics": "Statistics",
- "OptionReportGrouping": "Grouping",
- "OptionReportExport": "Report Export",
- "OptionReportColumns": "Report Columns"
+ "TabVideos": "Videos",
+ "HeaderWelcomeToEmby": "Welcome to Emby",
+ "EmbyIntroMessage": "With Emby you can easily stream videos, music and photos to smart phones, tablets and other devices from your Emby Server.",
+ "ButtonSkip": "Skip",
+ "TextConnectToServerManually": "Connect to server manually",
+ "ButtonSignInWithConnect": "Sign in with Emby Connect",
+ "ButtonConnect": "Connect",
+ "LabelServerHost": "Host:",
+ "LabelServerHostHelp": "192.168.1.100 or https://myserver.com",
+ "LabelServerPort": "Port:",
+ "HeaderNewServer": "New Server",
+ "ButtonChangeServer": "Change Server",
+ "HeaderConnectToServer": "Connect to Server"
}
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index 9e7810c76..572aa3a12 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -48,9 +48,8 @@
<Reference Include="Interfaces.IO">
<HintPath>..\packages\Interfaces.IO.1.0.0.5\lib\portable-net45+sl4+wp71+win8+wpa81\Interfaces.IO.dll</HintPath>
</Reference>
- <Reference Include="MediaBrowser.Naming, Version=1.0.5509.27636, Culture=neutral, processorArchitecture=MSIL">
- <SpecificVersion>False</SpecificVersion>
- <HintPath>..\packages\MediaBrowser.Naming.1.0.0.34\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
+ <Reference Include="MediaBrowser.Naming">
+ <HintPath>..\packages\MediaBrowser.Naming.1.0.0.35\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath>
</Reference>
<Reference Include="Mono.Nat, Version=1.2.24.0, Culture=neutral, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
@@ -226,6 +225,7 @@
<Compile Include="Localization\LocalizationManager.cs" />
<Compile Include="Logging\PatternsLogger.cs" />
<Compile Include="MediaEncoder\EncodingManager.cs" />
+ <Compile Include="Persistence\BaseSqliteRepository.cs" />
<Compile Include="Sorting\StartDateComparer.cs" />
<Compile Include="Sync\SyncHelper.cs" />
<Compile Include="Sync\SyncJobOptions.cs" />
@@ -242,7 +242,6 @@
<Compile Include="Persistence\SqliteMediaStreamsRepository.cs" />
<Compile Include="Notifications\SqliteNotificationsRepository.cs" />
<Compile Include="Persistence\SqliteProviderInfoRepository.cs" />
- <Compile Include="Persistence\SqliteShrinkMemoryTimer.cs" />
<Compile Include="Persistence\TypeMapper.cs" />
<Compile Include="Photos\BaseDynamicImageProvider.cs" />
<Compile Include="Playlists\ManualPlaylistsFolder.cs" />
diff --git a/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs
new file mode 100644
index 000000000..15d76fb60
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Persistence/BaseSqliteRepository.cs
@@ -0,0 +1,56 @@
+using MediaBrowser.Model.Logging;
+using System;
+using System.Threading;
+
+namespace MediaBrowser.Server.Implementations.Persistence
+{
+ public abstract class BaseSqliteRepository : IDisposable
+ {
+ protected readonly SemaphoreSlim WriteLock = new SemaphoreSlim(1, 1);
+ protected ILogger Logger;
+
+ protected BaseSqliteRepository(ILogManager logManager)
+ {
+ Logger = logManager.GetLogger(GetType().Name);
+ }
+
+ public void Dispose()
+ {
+ Dispose(true);
+ GC.SuppressFinalize(this);
+ }
+
+ private readonly object _disposeLock = new object();
+
+ /// <summary>
+ /// Releases unmanaged and - optionally - managed resources.
+ /// </summary>
+ /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
+ protected virtual void Dispose(bool dispose)
+ {
+ if (dispose)
+ {
+ try
+ {
+ lock (_disposeLock)
+ {
+ WriteLock.Wait();
+
+ CloseConnection();
+ }
+ }
+ catch (Exception ex)
+ {
+ Logger.ErrorException("Error disposing database", ex);
+ }
+ }
+ }
+
+ protected virtual void DisposeInternal()
+ {
+
+ }
+
+ protected abstract void CloseConnection();
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
index 77b993205..075ef4239 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteChapterRepository.cs
@@ -32,8 +32,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
_logger = logManager.GetLogger(GetType().Name);
}
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
-
/// <summary>
/// Opens the connection to the database
/// </summary>
@@ -54,8 +52,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
_connection.RunQueries(queries, _logger);
PrepareStatements();
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
/// <summary>
@@ -286,12 +282,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
lock (_disposeLock)
{
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
if (_connection != null)
{
if (_connection.IsOpen())
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
index 3dfa74727..c9ab43e63 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteDisplayPreferencesRepository.cs
@@ -16,11 +16,15 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// <summary>
/// Class SQLiteDisplayPreferencesRepository
/// </summary>
- public class SqliteDisplayPreferencesRepository : IDisplayPreferencesRepository
+ public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
{
private IDbConnection _connection;
- private readonly ILogger _logger;
+ public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths) : base(logManager)
+ {
+ _jsonSerializer = jsonSerializer;
+ _appPaths = appPaths;
+ }
/// <summary>
/// Gets the name of the repository
@@ -44,36 +48,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// </summary>
private readonly IApplicationPaths _appPaths;
- private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SqliteDisplayPreferencesRepository" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="jsonSerializer">The json serializer.</param>
- /// <param name="logManager">The log manager.</param>
- /// <exception cref="System.ArgumentNullException">
- /// jsonSerializer
- /// or
- /// appPaths
- /// </exception>
- public SqliteDisplayPreferencesRepository(IApplicationPaths appPaths, IJsonSerializer jsonSerializer, ILogManager logManager)
- {
- if (jsonSerializer == null)
- {
- throw new ArgumentNullException("jsonSerializer");
- }
- if (appPaths == null)
- {
- throw new ArgumentNullException("appPaths");
- }
-
- _jsonSerializer = jsonSerializer;
- _appPaths = appPaths;
-
- _logger = logManager.GetLogger(GetType().Name);
- }
-
/// <summary>
/// Opens the connection to the database
/// </summary>
@@ -82,7 +56,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var dbFile = Path.Combine(_appPaths.DataPath, "displaypreferences.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
+ _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
string[] queries = {
@@ -95,7 +69,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
"pragma shrink_memory"
};
- _connection.RunQueries(queries, _logger);
+ _connection.RunQueries(queries, Logger);
}
/// <summary>
@@ -122,7 +96,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -157,7 +131,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save display preferences:", e);
+ Logger.ErrorException("Failed to save display preferences:", e);
if (transaction != null)
{
@@ -173,7 +147,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -194,7 +168,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -235,7 +209,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save display preferences:", e);
+ Logger.ErrorException("Failed to save display preferences:", e);
if (transaction != null)
{
@@ -251,7 +225,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -322,45 +296,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
+ protected override void CloseConnection()
{
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private readonly object _disposeLock = new object();
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
- {
- if (dispose)
+ if (_connection != null)
{
- try
+ if (_connection.IsOpen())
{
- lock (_disposeLock)
- {
- if (_connection != null)
- {
- if (_connection.IsOpen())
- {
- _connection.Close();
- }
-
- _connection.Dispose();
- _connection = null;
- }
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error disposing database", ex);
+ _connection.Close();
}
+
+ _connection.Dispose();
+ _connection = null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
index 5d5855bf8..2d5aad04d 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteFileOrganizationRepository.cs
@@ -14,14 +14,10 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Persistence
{
- public class SqliteFileOrganizationRepository : IFileOrganizationRepository, IDisposable
+ public class SqliteFileOrganizationRepository : BaseSqliteRepository, IFileOrganizationRepository, IDisposable
{
private IDbConnection _connection;
- private readonly ILogger _logger;
-
- private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
private readonly IServerApplicationPaths _appPaths;
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
@@ -30,11 +26,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _deleteResultCommand;
private IDbCommand _deleteAllCommand;
- public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths)
+ public SqliteFileOrganizationRepository(ILogManager logManager, IServerApplicationPaths appPaths) : base(logManager)
{
_appPaths = appPaths;
-
- _logger = logManager.GetLogger(GetType().Name);
}
/// <summary>
@@ -45,7 +39,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var dbFile = Path.Combine(_appPaths.DataPath, "fileorganization.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
+ _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
string[] queries = {
@@ -58,11 +52,9 @@ namespace MediaBrowser.Server.Implementations.Persistence
"pragma shrink_memory"
};
- _connection.RunQueries(queries, _logger);
+ _connection.RunQueries(queries, Logger);
PrepareStatements();
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
private void PrepareStatements()
@@ -103,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -145,7 +137,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save FileOrganizationResult:", e);
+ Logger.ErrorException("Failed to save FileOrganizationResult:", e);
if (transaction != null)
{
@@ -161,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -172,7 +164,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
throw new ArgumentNullException("id");
}
- await _writeLock.WaitAsync().ConfigureAwait(false);
+ await WriteLock.WaitAsync().ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -199,7 +191,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to delete FileOrganizationResult:", e);
+ Logger.ErrorException("Failed to delete FileOrganizationResult:", e);
if (transaction != null)
{
@@ -215,13 +207,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
public async Task DeleteAll()
{
- await _writeLock.WaitAsync().ConfigureAwait(false);
+ await WriteLock.WaitAsync().ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -246,7 +238,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to delete results", e);
+ Logger.ErrorException("Failed to delete results", e);
if (transaction != null)
{
@@ -262,7 +254,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -423,51 +415,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
return result;
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private readonly object _disposeLock = new object();
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
+ protected override void CloseConnection()
{
- if (dispose)
+ if (_connection != null)
{
- try
- {
- lock (_disposeLock)
- {
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
- if (_connection != null)
- {
- if (_connection.IsOpen())
- {
- _connection.Close();
- }
-
- _connection.Dispose();
- _connection = null;
- }
- }
- }
- catch (Exception ex)
+ if (_connection.IsOpen())
{
- _logger.ErrorException("Error disposing database", ex);
+ _connection.Close();
}
+
+ _connection.Dispose();
+ _connection = null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
index e063d44dc..c5a9db87b 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteItemRepository.cs
@@ -130,12 +130,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
_mediaStreamsRepository.Initialize();
_chapterRepository.Initialize();
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
-
/// <summary>
/// The _write lock
/// </summary>
@@ -430,12 +426,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
lock (_disposeLock)
{
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
_writeLock.Wait();
if (_connection != null)
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs
index 293da3f0f..994397624 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteMediaStreamsRepository.cs
@@ -1,5 +1,4 @@
-using System.Globalization;
-using MediaBrowser.Controller.Persistence;
+using MediaBrowser.Controller.Persistence;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using System;
@@ -21,8 +20,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
private IDbCommand _deleteStreamsCommand;
private IDbCommand _saveStreamCommand;
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
-
public SqliteMediaStreamsRepository(IDbConnection connection, ILogManager logManager)
{
_connection = connection;
@@ -64,8 +61,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
AddRefFramesCommand();
PrepareStatements();
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
private void AddPixelFormatColumnCommand()
@@ -563,12 +558,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
lock (_disposeLock)
{
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
if (_connection != null)
{
if (_connection.IsOpen())
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
index 743d8fed6..bce33e834 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteProviderInfoRepository.cs
@@ -1,33 +1,28 @@
-using System.Text;
-using MediaBrowser.Common.Configuration;
+using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Logging;
using System;
using System.Data;
using System.IO;
using System.Linq;
+using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Persistence
{
- public class SqliteProviderInfoRepository : IProviderRepository
+ public class SqliteProviderInfoRepository : BaseSqliteRepository, IProviderRepository
{
private IDbConnection _connection;
- private readonly ILogger _logger;
-
private IDbCommand _saveStatusCommand;
private readonly IApplicationPaths _appPaths;
- public SqliteProviderInfoRepository(IApplicationPaths appPaths, ILogManager logManager)
+ public SqliteProviderInfoRepository(ILogManager logManager, IApplicationPaths appPaths) : base(logManager)
{
_appPaths = appPaths;
- _logger = logManager.GetLogger(GetType().Name);
}
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
-
/// <summary>
/// Gets the name of the repository
/// </summary>
@@ -48,7 +43,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var dbFile = Path.Combine(_appPaths.DataPath, "refreshinfo.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
+ _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
string[] queries = {
@@ -61,13 +56,11 @@ namespace MediaBrowser.Server.Implementations.Persistence
"pragma shrink_memory"
};
- _connection.RunQueries(queries, _logger);
+ _connection.RunQueries(queries, Logger);
AddItemDateModifiedCommand();
PrepareStatements();
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
}
private static readonly string[] StatusColumns =
@@ -113,15 +106,10 @@ namespace MediaBrowser.Server.Implementations.Persistence
builder.AppendLine("alter table MetadataStatus");
builder.AppendLine("add column ItemDateModified DateTime NULL");
- _connection.RunQueries(new[] { builder.ToString() }, _logger);
+ _connection.RunQueries(new[] { builder.ToString() }, Logger);
}
/// <summary>
- /// The _write lock
- /// </summary>
- private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
-
- /// <summary>
/// Prepares the statements.
/// </summary>
private void PrepareStatements()
@@ -227,7 +215,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -264,7 +252,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save provider info:", e);
+ Logger.ErrorException("Failed to save provider info:", e);
if (transaction != null)
{
@@ -280,55 +268,21 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private readonly object _disposeLock = new object();
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
+ protected override void CloseConnection()
{
- if (dispose)
+ if (_connection != null)
{
- try
+ if (_connection.IsOpen())
{
- lock (_disposeLock)
- {
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
- if (_connection != null)
- {
- if (_connection.IsOpen())
- {
- _connection.Close();
- }
-
- _connection.Dispose();
- _connection = null;
- }
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error disposing database", ex);
+ _connection.Close();
}
+
+ _connection.Dispose();
+ _connection = null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteShrinkMemoryTimer.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteShrinkMemoryTimer.cs
deleted file mode 100644
index b5a0c10b1..000000000
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteShrinkMemoryTimer.cs
+++ /dev/null
@@ -1,84 +0,0 @@
-using MediaBrowser.Model.Logging;
-using System;
-using System.Data;
-using System.Threading;
-
-namespace MediaBrowser.Server.Implementations.Persistence
-{
- class SqliteShrinkMemoryTimer : IDisposable
- {
- private Timer _shrinkMemoryTimer;
-
- private readonly SemaphoreSlim _writeLock;
- private readonly ILogger _logger;
- private readonly IDbConnection _connection;
-
- public SqliteShrinkMemoryTimer(IDbConnection connection, SemaphoreSlim writeLock, ILogger logger)
- {
- _connection = connection;
- _writeLock = writeLock;
- _logger = logger;
-
- _shrinkMemoryTimer = new Timer(TimerCallback, null, TimeSpan.FromMinutes(30), TimeSpan.FromMinutes(10));
- }
-
- private async void TimerCallback(object state)
- {
- await _writeLock.WaitAsync(CancellationToken.None).ConfigureAwait(false);
-
- IDbTransaction transaction = null;
-
- try
- {
- transaction = _connection.BeginTransaction();
-
- using (var cmd = _connection.CreateCommand())
- {
- cmd.Transaction = transaction;
- cmd.CommandText = "pragma shrink_memory";
- cmd.ExecuteNonQuery();
- }
-
- transaction.Commit();
- }
- catch (OperationCanceledException)
- {
- if (transaction != null)
- {
- transaction.Rollback();
- }
-
- throw;
- }
- catch (Exception e)
- {
- _logger.ErrorException("Failed to save items:", e);
-
- if (transaction != null)
- {
- transaction.Rollback();
- }
-
- throw;
- }
- finally
- {
- if (transaction != null)
- {
- transaction.Dispose();
- }
-
- _writeLock.Release();
- }
- }
-
- public void Dispose()
- {
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
- }
- }
-}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
index 0f0488168..8b86d19a2 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserDataRepository.cs
@@ -11,13 +11,15 @@ using System.Threading.Tasks;
namespace MediaBrowser.Server.Implementations.Persistence
{
- public class SqliteUserDataRepository : IUserDataRepository
+ public class SqliteUserDataRepository : BaseSqliteRepository, IUserDataRepository
{
- private readonly ILogger _logger;
-
- private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
-
private IDbConnection _connection;
+ private readonly IApplicationPaths _appPaths;
+
+ public SqliteUserDataRepository(ILogManager logManager, IApplicationPaths appPaths) : base(logManager)
+ {
+ _appPaths = appPaths;
+ }
/// <summary>
/// Gets the name of the repository
@@ -32,32 +34,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
/// <summary>
- /// The _app paths
- /// </summary>
- private readonly IApplicationPaths _appPaths;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SqliteUserDataRepository" /> class.
- /// </summary>
- /// <param name="appPaths">The app paths.</param>
- /// <param name="logManager">The log manager.</param>
- /// <exception cref="System.ArgumentNullException">jsonSerializer
- /// or
- /// appPaths</exception>
- public SqliteUserDataRepository(IApplicationPaths appPaths, ILogManager logManager)
- {
- if (appPaths == null)
- {
- throw new ArgumentNullException("appPaths");
- }
-
- _appPaths = appPaths;
- _logger = logManager.GetLogger(GetType().Name);
- }
-
- private SqliteShrinkMemoryTimer _shrinkMemoryTimer;
-
- /// <summary>
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
@@ -65,7 +41,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var dbFile = Path.Combine(_appPaths.DataPath, "userdata_v2.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
+ _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
string[] queries = {
@@ -79,9 +55,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
"pragma shrink_memory"
};
- _connection.RunQueries(queries, _logger);
-
- _shrinkMemoryTimer = new SqliteShrinkMemoryTimer(_connection, _writeLock, _logger);
+ _connection.RunQueries(queries, Logger);
}
/// <summary>
@@ -143,7 +117,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -182,7 +156,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save user data:", e);
+ Logger.ErrorException("Failed to save user data:", e);
if (transaction != null)
{
@@ -198,7 +172,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -213,7 +187,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -257,7 +231,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save user data:", e);
+ Logger.ErrorException("Failed to save user data:", e);
if (transaction != null)
{
@@ -273,7 +247,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -379,51 +353,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
return userData;
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private readonly object _disposeLock = new object();
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
+ protected override void CloseConnection()
{
- if (dispose)
+ if (_connection != null)
{
- try
+ if (_connection.IsOpen())
{
- lock (_disposeLock)
- {
- if (_shrinkMemoryTimer != null)
- {
- _shrinkMemoryTimer.Dispose();
- _shrinkMemoryTimer = null;
- }
-
- if (_connection != null)
- {
- if (_connection.IsOpen())
- {
- _connection.Close();
- }
-
- _connection.Dispose();
- _connection = null;
- }
- }
- }
- catch (Exception ex)
- {
- _logger.ErrorException("Error disposing database", ex);
+ _connection.Close();
}
+
+ _connection.Dispose();
+ _connection = null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
index d97a55ae6..ad784ae5d 100644
--- a/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
+++ b/MediaBrowser.Server.Implementations/Persistence/SqliteUserRepository.cs
@@ -15,14 +15,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
/// <summary>
/// Class SQLiteUserRepository
/// </summary>
- public class SqliteUserRepository : IUserRepository
+ public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
{
- private readonly ILogger _logger;
-
- private readonly SemaphoreSlim _writeLock = new SemaphoreSlim(1, 1);
-
private IDbConnection _connection;
private readonly IServerApplicationPaths _appPaths;
+ private readonly IJsonSerializer _jsonSerializer;
+
+ public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer) : base(logManager)
+ {
+ _appPaths = appPaths;
+ _jsonSerializer = jsonSerializer;
+ }
/// <summary>
/// Gets the name of the repository
@@ -37,32 +40,6 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
/// <summary>
- /// Gets the json serializer.
- /// </summary>
- /// <value>The json serializer.</value>
- private readonly IJsonSerializer _jsonSerializer;
-
- /// <summary>
- /// Initializes a new instance of the <see cref="SqliteUserRepository" /> class.
- /// </summary>
- /// <param name="jsonSerializer">The json serializer.</param>
- /// <param name="logManager">The log manager.</param>
- /// <param name="appPaths">The app paths.</param>
- /// <exception cref="System.ArgumentNullException">appPaths</exception>
- public SqliteUserRepository(IJsonSerializer jsonSerializer, ILogManager logManager, IServerApplicationPaths appPaths)
- {
- if (jsonSerializer == null)
- {
- throw new ArgumentNullException("jsonSerializer");
- }
-
- _jsonSerializer = jsonSerializer;
- _appPaths = appPaths;
-
- _logger = logManager.GetLogger(GetType().Name);
- }
-
- /// <summary>
/// Opens the connection to the database
/// </summary>
/// <returns>Task.</returns>
@@ -70,7 +47,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
{
var dbFile = Path.Combine(_appPaths.DataPath, "users.db");
- _connection = await SqliteExtensions.ConnectToDb(dbFile, _logger).ConfigureAwait(false);
+ _connection = await SqliteExtensions.ConnectToDb(dbFile, Logger).ConfigureAwait(false);
string[] queries = {
@@ -84,7 +61,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
"pragma shrink_memory"
};
- _connection.RunQueries(queries, _logger);
+ _connection.RunQueries(queries, Logger);
}
/// <summary>
@@ -107,8 +84,8 @@ namespace MediaBrowser.Server.Implementations.Persistence
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
-
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+
IDbTransaction transaction = null;
try
@@ -139,7 +116,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to save user:", e);
+ Logger.ErrorException("Failed to save user:", e);
if (transaction != null)
{
@@ -155,7 +132,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
@@ -199,7 +176,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
cancellationToken.ThrowIfCancellationRequested();
- await _writeLock.WaitAsync(cancellationToken).ConfigureAwait(false);
+ await WriteLock.WaitAsync(cancellationToken).ConfigureAwait(false);
IDbTransaction transaction = null;
@@ -231,7 +208,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
}
catch (Exception e)
{
- _logger.ErrorException("Failed to delete user:", e);
+ Logger.ErrorException("Failed to delete user:", e);
if (transaction != null)
{
@@ -247,49 +224,21 @@ namespace MediaBrowser.Server.Implementations.Persistence
transaction.Dispose();
}
- _writeLock.Release();
+ WriteLock.Release();
}
}
- /// <summary>
- /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
- /// </summary>
- public void Dispose()
- {
- Dispose(true);
- GC.SuppressFinalize(this);
- }
-
- private readonly object _disposeLock = new object();
-
- /// <summary>
- /// Releases unmanaged and - optionally - managed resources.
- /// </summary>
- /// <param name="dispose"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
- protected virtual void Dispose(bool dispose)
+ protected override void CloseConnection()
{
- if (dispose)
+ if (_connection != null)
{
- try
- {
- lock (_disposeLock)
- {
- if (_connection != null)
- {
- if (_connection.IsOpen())
- {
- _connection.Close();
- }
-
- _connection.Dispose();
- _connection = null;
- }
- }
- }
- catch (Exception ex)
+ if (_connection.IsOpen())
{
- _logger.ErrorException("Error disposing database", ex);
+ _connection.Close();
}
+
+ _connection.Dispose();
+ _connection = null;
}
}
}
diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
index be71a6408..bd22a8a70 100644
--- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
@@ -191,6 +191,8 @@ namespace MediaBrowser.Server.Implementations.Photos
throw new ArgumentException("Unexpected image type");
}
+ private const int MaxImageAgeDays = 7;
+
public bool HasChanged(IHasMetadata item, IDirectoryService directoryService, DateTime date)
{
if (!Supports(item))
@@ -198,6 +200,11 @@ namespace MediaBrowser.Server.Implementations.Photos
return false;
}
+ if (item is UserView)
+ {
+ return HasChanged(item, ImageType.Primary) || HasChanged(item, ImageType.Thumb);
+ }
+
var items = GetItemsWithImages(item).Result;
var cacheKey = GetConfigurationCacheKey(items, item.Name);
@@ -216,7 +223,6 @@ namespace MediaBrowser.Server.Implementations.Photos
}
var currentPathCacheKey = (Path.GetFileNameWithoutExtension(image.Path) ?? string.Empty).Split('_').LastOrDefault();
-
if (string.Equals(cacheKey, currentPathCacheKey, StringComparison.OrdinalIgnoreCase))
{
return false;
@@ -226,6 +232,27 @@ namespace MediaBrowser.Server.Implementations.Photos
return true;
}
+ protected bool HasChanged(IHasImages item, ImageType type)
+ {
+ var image = item.GetImageInfo(type, 0);
+
+ if (image != null)
+ {
+ if (!FileSystem.ContainsSubPath(item.GetInternalMetadataPath(), image.Path))
+ {
+ return false;
+ }
+
+ var age = DateTime.UtcNow - image.DateModified;
+ if (age.TotalDays <= MaxImageAgeDays)
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
protected List<BaseItem> GetFinalItems(List<BaseItem> items)
{
return GetFinalItems(items, 4);
@@ -234,7 +261,7 @@ namespace MediaBrowser.Server.Implementations.Photos
protected virtual List<BaseItem> GetFinalItems(List<BaseItem> items, int limit)
{
// Rotate the images once every x days
- var random = DateTime.Now.DayOfYear % 7;
+ var random = DateTime.Now.DayOfYear % MaxImageAgeDays;
return items
.OrderBy(i => (random + "" + items.IndexOf(i)).GetMD5())
diff --git a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
index 8c142b646..f04c0bf77 100644
--- a/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/PhotoAlbumImageProvider.cs
@@ -11,7 +11,8 @@ namespace MediaBrowser.Server.Implementations.Photos
{
//public class PhotoAlbumImageProvider : BaseDynamicImageProvider<PhotoAlbum>
//{
- // public PhotoAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor) : base(fileSystem, providerManager, applicationPaths, imageProcessor)
+ // public PhotoAlbumImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor)
+ // : base(fileSystem, providerManager, applicationPaths, imageProcessor)
// {
// }
diff --git a/MediaBrowser.Server.Implementations/Session/SessionManager.cs b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
index 112778ec8..757e6938a 100644
--- a/MediaBrowser.Server.Implementations/Session/SessionManager.cs
+++ b/MediaBrowser.Server.Implementations/Session/SessionManager.cs
@@ -1550,7 +1550,7 @@ namespace MediaBrowser.Server.Implementations.Session
if (info.PrimaryImageTag == null)
{
- var album = audio.Parents.OfType<MusicAlbum>().FirstOrDefault();
+ var album = audio.AlbumEntity;
if (album != null && album.HasImage(ImageType.Primary))
{
diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
index 93a9bc8f6..930762696 100644
--- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
@@ -21,13 +21,11 @@ namespace MediaBrowser.Server.Implementations.UserViews
public class DynamicImageProvider : BaseDynamicImageProvider<UserView>
{
private readonly IUserManager _userManager;
- private readonly ILibraryManager _libraryManager;
- public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager, ILibraryManager libraryManager)
+ public DynamicImageProvider(IFileSystem fileSystem, IProviderManager providerManager, IApplicationPaths applicationPaths, IImageProcessor imageProcessor, IUserManager userManager)
: base(fileSystem, providerManager, applicationPaths, imageProcessor)
{
_userManager = userManager;
- _libraryManager = libraryManager;
}
public override IEnumerable<ImageType> GetSupportedImages(IHasImages item)
@@ -122,7 +120,7 @@ namespace MediaBrowser.Server.Implementations.UserViews
var audio = i as Audio;
if (audio != null)
{
- var album = audio.FindParent<MusicAlbum>();
+ var album = audio.AlbumEntity;
if (album != null && album.HasImage(ImageType.Primary))
{
return album;
diff --git a/MediaBrowser.Server.Implementations/packages.config b/MediaBrowser.Server.Implementations/packages.config
index 7fb369106..0b81c1866 100644
--- a/MediaBrowser.Server.Implementations/packages.config
+++ b/MediaBrowser.Server.Implementations/packages.config
@@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Interfaces.IO" version="1.0.0.5" targetFramework="net45" />
- <package id="MediaBrowser.Naming" version="1.0.0.34" targetFramework="net45" />
+ <package id="MediaBrowser.Naming" version="1.0.0.35" targetFramework="net45" />
<package id="Mono.Nat" version="1.2.24.0" targetFramework="net45" />
<package id="morelinq" version="1.1.0" targetFramework="net45" />
<package id="Patterns.Logging" version="1.0.0.2" targetFramework="net45" />
- <package id="SocketHttpListener" version="1.0.0.5" targetFramework="net45" />
+ <package id="SocketHttpListener" version="1.0.0.6" targetFramework="net45" />
</packages> \ No newline at end of file
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index c9a2d3f22..4c25c968c 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -392,13 +392,13 @@ namespace MediaBrowser.Server.Startup.Common
UserRepository = await GetUserRepository().ConfigureAwait(false);
RegisterSingleInstance(UserRepository);
- DisplayPreferencesRepository = new SqliteDisplayPreferencesRepository(ApplicationPaths, JsonSerializer, LogManager);
+ DisplayPreferencesRepository = new SqliteDisplayPreferencesRepository(LogManager, JsonSerializer, ApplicationPaths);
RegisterSingleInstance(DisplayPreferencesRepository);
ItemRepository = new SqliteItemRepository(ApplicationPaths, JsonSerializer, LogManager);
RegisterSingleInstance(ItemRepository);
- ProviderRepository = new SqliteProviderInfoRepository(ApplicationPaths, LogManager);
+ ProviderRepository = new SqliteProviderInfoRepository(LogManager, ApplicationPaths);
RegisterSingleInstance(ProviderRepository);
FileOrganizationRepository = await GetFileOrganizationRepository().ConfigureAwait(false);
@@ -614,7 +614,7 @@ namespace MediaBrowser.Server.Startup.Common
/// <returns>Task{IUserRepository}.</returns>
private async Task<IUserRepository> GetUserRepository()
{
- var repo = new SqliteUserRepository(JsonSerializer, LogManager, ApplicationPaths);
+ var repo = new SqliteUserRepository(LogManager, ApplicationPaths, JsonSerializer);
await repo.Initialize().ConfigureAwait(false);
@@ -704,7 +704,7 @@ namespace MediaBrowser.Server.Startup.Common
/// <returns>Task.</returns>
private async Task ConfigureUserDataRepositories()
{
- var repo = new SqliteUserDataRepository(ApplicationPaths, LogManager);
+ var repo = new SqliteUserDataRepository(LogManager, ApplicationPaths);
await repo.Initialize().ConfigureAwait(false);
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index dcafa9417..119e92cd1 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -52,6 +52,7 @@ namespace MediaBrowser.WebDashboard.Api
[Route("/dashboard/Package", "GET")]
public class GetDashboardPackage
{
+ public string Mode { get; set; }
}
/// <summary>
@@ -134,7 +135,7 @@ namespace MediaBrowser.WebDashboard.Api
{
var page = ServerEntryPoint.Instance.PluginConfigurationPages.First(p => p.Name.Equals(request.Name, StringComparison.OrdinalIgnoreCase));
- return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null, false));
+ return ResultFactory.GetStaticResult(Request, page.Plugin.Version.ToString().GetMD5(), null, null, MimeTypes.GetMimeType("page.html"), () => GetPackageCreator().ModifyHtml(page.GetHtmlStream(), null, null, false));
}
/// <summary>
@@ -252,7 +253,7 @@ namespace MediaBrowser.WebDashboard.Api
var minify = _serverConfigurationManager.Configuration.EnableDashboardResourceMinification;
return GetPackageCreator()
- .GetResource(path, localizationCulture, _appHost.ApplicationVersion.ToString(), minify);
+ .GetResource(path, null, localizationCulture, _appHost.ApplicationVersion.ToString(), minify);
}
private PackageCreator GetPackageCreator()
@@ -292,38 +293,40 @@ namespace MediaBrowser.WebDashboard.Api
var appVersion = DateTime.UtcNow.Ticks.ToString(CultureInfo.InvariantCulture);
- await DumpHtml(creator.DashboardUIPath, path, culture, appVersion);
- await DumpJs(creator.DashboardUIPath, path, culture, appVersion);
+ var mode = request.Mode;
- await DumpFile("scripts/all.js", Path.Combine(path, "scripts", "all.js"), culture, appVersion).ConfigureAwait(false);
- await DumpFile("css/all.css", Path.Combine(path, "css", "all.css"), culture, appVersion).ConfigureAwait(false);
+ await DumpHtml(creator.DashboardUIPath, path, mode, culture, appVersion);
+ await DumpJs(creator.DashboardUIPath, path, mode, culture, appVersion);
+
+ await DumpFile("scripts/all.js", Path.Combine(path, "scripts", "all.js"), mode, culture, appVersion).ConfigureAwait(false);
+ await DumpFile("css/all.css", Path.Combine(path, "css", "all.css"), mode, culture, appVersion).ConfigureAwait(false);
return "";
}
- private async Task DumpHtml(string source, string destination, string culture, string appVersion)
+ private async Task DumpHtml(string source, string destination, string mode, string culture, string appVersion)
{
foreach (var file in Directory.GetFiles(source, "*.html", SearchOption.TopDirectoryOnly))
{
var filename = Path.GetFileName(file);
- await DumpFile(filename, Path.Combine(destination, filename), culture, appVersion).ConfigureAwait(false);
+ await DumpFile(filename, Path.Combine(destination, filename), mode, culture, appVersion).ConfigureAwait(false);
}
}
- private async Task DumpJs(string source, string destination, string culture, string appVersion)
+ private async Task DumpJs(string source, string mode, string destination, string culture, string appVersion)
{
foreach (var file in Directory.GetFiles(source, "*.js", SearchOption.TopDirectoryOnly))
{
var filename = Path.GetFileName(file);
- await DumpFile("scripts/" + filename, Path.Combine(destination, "scripts", filename), culture, appVersion).ConfigureAwait(false);
+ await DumpFile("scripts/" + filename, Path.Combine(destination, "scripts", filename), mode, culture, appVersion).ConfigureAwait(false);
}
}
- private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string culture, string appVersion)
+ private async Task DumpFile(string resourceVirtualPath, string destinationFilePath, string mode, string culture, string appVersion)
{
- using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, culture, appVersion, true).ConfigureAwait(false))
+ using (var stream = await GetPackageCreator().GetResource(resourceVirtualPath, mode, culture, appVersion, true).ConfigureAwait(false))
{
using (var fs = _fileSystem.GetFileStream(destinationFilePath, FileMode.Create, FileAccess.Write, FileShare.Read))
{
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 6e03bd674..a1d47f0d2 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -32,8 +32,10 @@ namespace MediaBrowser.WebDashboard.Api
}
public async Task<Stream> GetResource(string path,
+ string mode,
string localizationCulture,
- string appVersion, bool enableMinification)
+ string appVersion,
+ bool enableMinification)
{
var isHtml = IsHtml(path);
@@ -41,7 +43,7 @@ namespace MediaBrowser.WebDashboard.Api
if (path.Equals("scripts/all.js", StringComparison.OrdinalIgnoreCase))
{
- resourceStream = await GetAllJavascript(localizationCulture, appVersion, enableMinification).ConfigureAwait(false);
+ resourceStream = await GetAllJavascript(mode, localizationCulture, appVersion, enableMinification).ConfigureAwait(false);
}
else if (path.Equals("css/all.css", StringComparison.OrdinalIgnoreCase))
{
@@ -58,7 +60,7 @@ namespace MediaBrowser.WebDashboard.Api
// jQuery ajax doesn't seem to handle if-modified-since correctly
if (isHtml)
{
- resourceStream = await ModifyHtml(resourceStream, localizationCulture, enableMinification).ConfigureAwait(false);
+ resourceStream = await ModifyHtml(resourceStream, mode, localizationCulture, enableMinification).ConfigureAwait(false);
}
}
@@ -106,10 +108,11 @@ namespace MediaBrowser.WebDashboard.Api
/// Modifies the HTML by adding common meta tags, css and js.
/// </summary>
/// <param name="sourceStream">The source stream.</param>
+ /// <param name="mode">The mode.</param>
/// <param name="localizationCulture">The localization culture.</param>
/// <param name="enableMinification">if set to <c>true</c> [enable minification].</param>
/// <returns>Task{Stream}.</returns>
- public async Task<Stream> ModifyHtml(Stream sourceStream, string localizationCulture, bool enableMinification)
+ public async Task<Stream> ModifyHtml(Stream sourceStream, string mode, string localizationCulture, bool enableMinification)
{
using (sourceStream)
{
@@ -155,7 +158,7 @@ namespace MediaBrowser.WebDashboard.Api
var version = GetType().Assembly.GetName().Version;
- html = html.Replace("<head>", "<head>" + GetMetaTags() + GetCommonCss(version) + GetCommonJavascript(version));
+ html = html.Replace("<head>", "<head>" + GetMetaTags(mode) + GetCommonCss(mode, version) + GetCommonJavascript(mode, version));
var bytes = Encoding.UTF8.GetBytes(html);
@@ -172,12 +175,19 @@ namespace MediaBrowser.WebDashboard.Api
/// Gets the meta tags.
/// </summary>
/// <returns>System.String.</returns>
- private static string GetMetaTags()
+ private static string GetMetaTags(string mode)
{
var sb = new StringBuilder();
+ if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
+ {
+ sb.Append("<meta http-equiv=\"Content-Security-Policy\" content=\"default-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'\">");
+ }
+
sb.Append("<meta http-equiv=\"X-UA-Compatibility\" content=\"IE=Edge\">");
- sb.Append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, user-scalable=no\">");
+ sb.Append("<meta name=\"format-detection\" content=\"telephone=no\">");
+ sb.Append("<meta name=\"msapplication-tap-highlight\" content=\"no\">");
+ sb.Append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, user-scalable=no\">");
sb.Append("<meta name=\"apple-mobile-web-app-capable\" content=\"yes\">");
sb.Append("<meta name=\"mobile-web-app-capable\" content=\"yes\">");
sb.Append("<meta name=\"application-name\" content=\"Emby\">");
@@ -200,11 +210,12 @@ namespace MediaBrowser.WebDashboard.Api
/// <summary>
/// Gets the common CSS.
/// </summary>
+ /// <param name="mode">The mode.</param>
/// <param name="version">The version.</param>
/// <returns>System.String.</returns>
- private string GetCommonCss(Version version)
+ private string GetCommonCss(string mode, Version version)
{
- var versionString = "?v=" + version;
+ var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + version : string.Empty;
var files = new[]
{
@@ -223,20 +234,26 @@ namespace MediaBrowser.WebDashboard.Api
/// <summary>
/// Gets the common javascript.
/// </summary>
+ /// <param name="mode">The mode.</param>
/// <param name="version">The version.</param>
/// <returns>System.String.</returns>
- private string GetCommonJavascript(Version version)
+ private string GetCommonJavascript(string mode, Version version)
{
var builder = new StringBuilder();
- var versionString = "?v=" + version;
+ var versionString = !string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase) ? "?v=" + version : string.Empty;
- var files = new[]
- {
- "scripts/all.js" + versionString,
- "thirdparty/swipebox-master/js/jquery.swipebox.min.js" + versionString
+ var files = new List<string>
+ {
+ "scripts/all.js" + versionString,
+ "thirdparty/swipebox-master/js/jquery.swipebox.min.js" + versionString
};
+ if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
+ {
+ files.Insert(0, "cordova.js");
+ }
+
var tags = files.Select(s => string.Format("<script src=\"{0}\"></script>", s)).ToArray();
builder.Append(string.Join(string.Empty, tags));
@@ -248,7 +265,7 @@ namespace MediaBrowser.WebDashboard.Api
/// Gets a stream containing all concatenated javascript
/// </summary>
/// <returns>Task{Stream}.</returns>
- private async Task<Stream> GetAllJavascript(string culture, string version, bool enableMinification)
+ private async Task<Stream> GetAllJavascript(string mode, string culture, string version, bool enableMinification)
{
var memoryStream = new MemoryStream();
var newLineBytes = Encoding.UTF8.GetBytes(Environment.NewLine);
@@ -264,9 +281,18 @@ namespace MediaBrowser.WebDashboard.Api
await AppendResource(memoryStream, "thirdparty/jstree3.0.8/jstree.js", newLineBytes).ConfigureAwait(false);
+ await AppendResource(memoryStream, "thirdparty/fastclick.js", newLineBytes).ConfigureAwait(false);
+ await AppendResource(memoryStream, "thirdparty/headroom.js", newLineBytes).ConfigureAwait(false);
+
await AppendLocalization(memoryStream, culture).ConfigureAwait(false);
await memoryStream.WriteAsync(newLineBytes, 0, newLineBytes.Length).ConfigureAwait(false);
+ if (!string.IsNullOrWhiteSpace(mode))
+ {
+ var appModeBytes = Encoding.UTF8.GetBytes(string.Format("window.appMode='{0}';", mode));
+ await memoryStream.WriteAsync(appModeBytes, 0, appModeBytes.Length).ConfigureAwait(false);
+ }
+
// Write the version string for the dashboard comparison function
var versionString = string.Format("window.dashboardVersion='{0}';", version);
var versionBytes = Encoding.UTF8.GetBytes(versionString);
@@ -276,7 +302,7 @@ namespace MediaBrowser.WebDashboard.Api
var builder = new StringBuilder();
- foreach (var file in new[]
+ var apiClientFiles = new[]
{
"thirdparty/apiclient/logger.js",
"thirdparty/apiclient/md5.js",
@@ -289,10 +315,20 @@ namespace MediaBrowser.WebDashboard.Api
"thirdparty/apiclient/events.js",
"thirdparty/apiclient/deferred.js",
"thirdparty/apiclient/apiclient.js",
- "thirdparty/apiclient/connectservice.js",
- "thirdparty/apiclient/serverdiscovery.js",
- "thirdparty/apiclient/connectionmanager.js"
- })
+ "thirdparty/apiclient/connectservice.js"
+ }.ToList();
+
+ if (string.Equals(mode, "cordova", StringComparison.OrdinalIgnoreCase))
+ {
+ apiClientFiles.Add("thirdparty/apiclient/cordova/serverdiscovery.js");
+ }
+ else
+ {
+ apiClientFiles.Add("thirdparty/apiclient/serverdiscovery.js");
+ }
+ apiClientFiles.Add("thirdparty/apiclient/connectionmanager.js");
+
+ foreach (var file in apiClientFiles)
{
using (var fs = _fileSystem.GetFileStream(GetDashboardResourcePath(file), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{
diff --git a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
index 00debc459..4f029c26a 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -90,10 +90,13 @@
<Content Include="dashboard-ui\css\images\clients\androidtv-tile.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\css\images\empty.png">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\css\images\kids\bg.jpg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
- <Content Include="dashboard-ui\css\images\server.png">
+ <Content Include="dashboard-ui\css\images\logo536.png">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\css\images\splash.jpg">
@@ -216,6 +219,9 @@
<Content Include="dashboard-ui\thirdparty\apiclient\connectservice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\thirdparty\apiclient\cordova\serverdiscovery.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\thirdparty\apiclient\deferred.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -996,6 +1002,9 @@
<Content Include="dashboard-ui\thirdparty\cast_sender.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\thirdparty\fastclick.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\thirdparty\fontawesome\css\font-awesome.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@@ -1005,6 +1014,9 @@
<Content Include="dashboard-ui\thirdparty\fontawesome\fonts\fontawesome-webfont.svg">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
+ <Content Include="dashboard-ui\thirdparty\headroom.js">
+ <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+ </Content>
<Content Include="dashboard-ui\thirdparty\jquery-2.1.1.min.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
diff --git a/Nuget/MediaBrowser.Common.Internal.nuspec b/Nuget/MediaBrowser.Common.Internal.nuspec
index 497c1e070..f2d46de3e 100644
--- a/Nuget/MediaBrowser.Common.Internal.nuspec
+++ b/Nuget/MediaBrowser.Common.Internal.nuspec
@@ -14,7 +14,7 @@
<dependencies>
<dependency id="MediaBrowser.Common" version="3.0.622" />
<dependency id="NLog" version="3.2.1" />
- <dependency id="SimpleInjector" version="2.7.0" />
+ <dependency id="SimpleInjector" version="2.8.0" />
</dependencies>
</metadata>
<files>