diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2010Profile.cs
index 78e90af26e..3bd425cb38 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[]
{
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2011Profile.cs
index b435c63642..de4f1d2b65 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[]
{
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2012Profile.cs
index b0cbb0970d..5a5fb9e942 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[]
{
diff --git a/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs b/MediaBrowser.Dlna/Profiles/SonyBravia2013Profile.cs
index ca4e802a16..74a07f3892 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[]
{
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
index 68bfe85cf9..7afc8183d2 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2010).xml
@@ -15,7 +15,7 @@
Emby
3.0
http://www.microsoft.com/
- false
+ true
true
Audio,Photo,Video
JPEG_TN
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
index 4f9ca7550c..7400600e22 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2011).xml
@@ -15,7 +15,7 @@
Emby
3.0
http://www.microsoft.com/
- false
+ true
true
Audio,Photo,Video
JPEG_TN
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
index 682b2f3585..b8e3d6d309 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2012).xml
@@ -15,7 +15,7 @@
Emby
3.0
http://www.microsoft.com/
- false
+ true
true
Audio,Photo,Video
JPEG_TN
diff --git a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
index 5032bf69a8..5733d9d0b1 100644
--- a/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
+++ b/MediaBrowser.Dlna/Profiles/Xml/Sony Bravia (2013).xml
@@ -15,7 +15,7 @@
Emby
3.0
http://www.microsoft.com/
- false
+ true
true
Audio,Photo,Video
JPEG_TN
diff --git a/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs b/MediaBrowser.MediaEncoding/Encoder/MediaEncoder.cs
index a01f37f91d..4d5b669e2c 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(process.StandardOutput.BaseStream);
+ var result = _jsonSerializer.DeserializeFromStream(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();
+ var lines = new List();
- 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 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.Model/Dlna/ContentFeatureBuilder.cs b/MediaBrowser.Model/Dlna/ContentFeatureBuilder.cs
index b3fe28561a..62463d196a 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.AddRange(mediaProfile.OrgPn.Split(','));
+ orgPnValues.AddRange(mediaProfile.OrgPn.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
}
else
{
diff --git a/MediaBrowser.Providers/Manager/ItemImageProvider.cs b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
index c95cf67256..92fc1c2a80 100644
--- a/MediaBrowser.Providers/Manager/ItemImageProvider.cs
+++ b/MediaBrowser.Providers/Manager/ItemImageProvider.cs
@@ -38,12 +38,9 @@ namespace MediaBrowser.Providers.Manager
{
var hasChanges = false;
- var localImageProviders = providers.OfType()
- .ToList();
-
- if (localImageProviders.Count > 0 || !(item is Photo))
+ if (!(item is Photo))
{
- var images = localImageProviders
+ var images = providers.OfType()
.SelectMany(i => i.GetImages(item, directoryService))
.ToList();
@@ -425,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.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index ff99c40786..0a922dd0a6 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -1447,5 +1447,6 @@
"LabelServerHostHelp": "192.168.1.100 or https://myserver.com",
"LabelServerPort": "Port:",
"HeaderNewServer": "New Server",
- "ButtonChangeServer": "Change Server"
+ "ButtonChangeServer": "Change Server",
+ "HeaderConnectToServer": "Connect to Server"
}
diff --git a/MediaBrowser.WebDashboard/Api/PackageCreator.cs b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
index 6c812acce0..292f74a56d 100644
--- a/MediaBrowser.WebDashboard/Api/PackageCreator.cs
+++ b/MediaBrowser.WebDashboard/Api/PackageCreator.cs
@@ -301,7 +301,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",
@@ -314,10 +314,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 e39df9602c..6b3a0ae7ea 100644
--- a/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
+++ b/MediaBrowser.WebDashboard/MediaBrowser.WebDashboard.csproj
@@ -210,6 +210,9 @@
PreserveNewest
+
+ PreserveNewest
+
PreserveNewest