updated bravia profiles

This commit is contained in:
Luke Pulverenti 2015-05-06 08:56:26 -04:00
parent 2f05af4be4
commit 6c97afef23
14 changed files with 226 additions and 191 deletions

View file

@ -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"; "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; EnableSingleAlbumArtLimit = true;
EnableAlbumArtInDidl = true;
TranscodingProfiles = new[] TranscodingProfiles = new[]
{ {

View file

@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/"; ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10"; SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true; EnableSingleAlbumArtLimit = true;
EnableAlbumArtInDidl = true;
TranscodingProfiles = new[] TranscodingProfiles = new[]
{ {

View file

@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/"; ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10"; SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true; EnableSingleAlbumArtLimit = true;
EnableAlbumArtInDidl = true;
TranscodingProfiles = new[] TranscodingProfiles = new[]
{ {

View file

@ -44,6 +44,7 @@ namespace MediaBrowser.Dlna.Profiles
ManufacturerUrl = "http://www.microsoft.com/"; ManufacturerUrl = "http://www.microsoft.com/";
SonyAggregationFlags = "10"; SonyAggregationFlags = "10";
EnableSingleAlbumArtLimit = true; EnableSingleAlbumArtLimit = true;
EnableAlbumArtInDidl = true;
TranscodingProfiles = new[] TranscodingProfiles = new[]
{ {

View file

@ -15,7 +15,7 @@
<ModelDescription>Emby</ModelDescription> <ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber> <ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl> <ModelUrl>http://www.microsoft.com/</ModelUrl>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit> <EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes> <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn> <AlbumArtPn>JPEG_TN</AlbumArtPn>

View file

@ -15,7 +15,7 @@
<ModelDescription>Emby</ModelDescription> <ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber> <ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl> <ModelUrl>http://www.microsoft.com/</ModelUrl>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit> <EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes> <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn> <AlbumArtPn>JPEG_TN</AlbumArtPn>

View file

@ -15,7 +15,7 @@
<ModelDescription>Emby</ModelDescription> <ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber> <ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl> <ModelUrl>http://www.microsoft.com/</ModelUrl>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit> <EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes> <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn> <AlbumArtPn>JPEG_TN</AlbumArtPn>

View file

@ -15,7 +15,7 @@
<ModelDescription>Emby</ModelDescription> <ModelDescription>Emby</ModelDescription>
<ModelNumber>3.0</ModelNumber> <ModelNumber>3.0</ModelNumber>
<ModelUrl>http://www.microsoft.com/</ModelUrl> <ModelUrl>http://www.microsoft.com/</ModelUrl>
<EnableAlbumArtInDidl>false</EnableAlbumArtInDidl> <EnableAlbumArtInDidl>true</EnableAlbumArtInDidl>
<EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit> <EnableSingleAlbumArtLimit>true</EnableSingleAlbumArtLimit>
<SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes> <SupportedMediaTypes>Audio,Photo,Video</SupportedMediaTypes>
<AlbumArtPn>JPEG_TN</AlbumArtPn> <AlbumArtPn>JPEG_TN</AlbumArtPn>

View file

@ -199,82 +199,83 @@ namespace MediaBrowser.MediaEncoding.Encoder
await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false); await _ffProbeResourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
var processWrapper = new ProcessWrapper(process, this); using (var processWrapper = new ProcessWrapper(process, this))
try
{ {
StartProcess(processWrapper); try
}
catch (Exception ex)
{
_ffProbeResourcePool.Release();
_logger.ErrorException("Error starting ffprobe", ex);
throw;
}
try
{
process.BeginErrorReadLine();
var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
if (result != null)
{ {
if (result.streams != null) StartProcess(processWrapper);
{
// Normalize aspect ratio if invalid
foreach (var stream in result.streams)
{
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);
if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue)
{
foreach (var stream in mediaInfo.MediaStreams)
{
if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase))
{
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;
} }
} catch (Exception ex)
catch {
{ _ffProbeResourcePool.Release();
StopProcess(processWrapper, 100, true);
throw; _logger.ErrorException("Error starting ffprobe", ex);
}
finally throw;
{ }
_ffProbeResourcePool.Release();
try
{
process.BeginErrorReadLine();
var result = _jsonSerializer.DeserializeFromStream<InternalMediaInfoResult>(process.StandardOutput.BaseStream);
if (result != null)
{
if (result.streams != null)
{
// Normalize aspect ratio if invalid
foreach (var stream in result.streams)
{
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);
if (extractKeyFrameInterval && mediaInfo.RunTimeTicks.HasValue)
{
foreach (var stream in mediaInfo.MediaStreams)
{
if (stream.Type == MediaStreamType.Video && string.Equals(stream.Codec, "h264", StringComparison.OrdinalIgnoreCase))
{
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;
}
}
catch
{
StopProcess(processWrapper, 100, true);
throw;
}
finally
{
_ffProbeResourcePool.Release();
}
} }
throw new ApplicationException(string.Format("FFProbe failed for {0}", inputPath)); 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); _logger.Debug("{0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
var processWrapper = new ProcessWrapper(process, this); using (var processWrapper = new ProcessWrapper(process, this))
StartProcess(processWrapper);
var lines = new List<int>();
try
{ {
process.BeginErrorReadLine(); StartProcess(processWrapper);
await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false); var lines = new List<int>();
}
catch (OperationCanceledException) try
{
if (cancellationToken.IsCancellationRequested)
{ {
throw; process.BeginErrorReadLine();
}
}
finally
{
StopProcess(processWrapper, 100, true);
}
return lines; await StartReadingOutput(process.StandardOutput.BaseStream, lines, 120000, cancellationToken).ConfigureAwait(false);
}
catch (OperationCanceledException)
{
if (cancellationToken.IsCancellationRequested)
{
throw;
}
}
finally
{
StopProcess(processWrapper, 100, true);
}
return lines;
}
} }
private async Task StartReadingOutput(Stream source, List<int> lines, int timeoutMs, CancellationToken cancellationToken) 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); await resourcePool.WaitAsync(cancellationToken).ConfigureAwait(false);
var processWrapper = new ProcessWrapper(process, this); using (var processWrapper = new ProcessWrapper(process, this))
bool ranToCompletion;
var memoryStream = new MemoryStream();
try
{ {
StartProcess(processWrapper); bool ranToCompletion;
var memoryStream = new MemoryStream();
try
{
StartProcess(processWrapper);
#pragma warning disable 4014 #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 // 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); process.StandardOutput.BaseStream.CopyToAsync(memoryStream);
#pragma warning restore 4014 #pragma warning restore 4014
// MUST read both stdout and stderr asynchronously or a deadlock may occurr // MUST read both stdout and stderr asynchronously or a deadlock may occurr
process.BeginErrorReadLine(); 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();
} }
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
if (exitCode == -1 || memoryStream.Length == 0)
{
memoryStream.Dispose();
var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath);
_logger.Error(msg);
throw new ApplicationException(msg);
}
memoryStream.Position = 0;
return memoryStream;
} }
finally
{
resourcePool.Release();
}
var exitCode = ranToCompletion ? processWrapper.ExitCode ?? 0 : -1;
if (exitCode == -1 || memoryStream.Length == 0)
{
memoryStream.Dispose();
var msg = string.Format("ffmpeg image extraction failed for {0}", inputPath);
_logger.Error(msg);
throw new ApplicationException(msg);
}
memoryStream.Position = 0;
return memoryStream;
} }
public string GetTimeParameter(long ticks) public string GetTimeParameter(long ticks)
@ -603,55 +607,56 @@ namespace MediaBrowser.MediaEncoding.Encoder
bool ranToCompletion = false; bool ranToCompletion = false;
var processWrapper = new ProcessWrapper(process, this); using (var processWrapper = new ProcessWrapper(process, this))
try
{ {
StartProcess(processWrapper); try
// 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;
while (isResponsive)
{ {
if (process.WaitForExit(30000)) 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.
bool isResponsive = true;
int lastCount = 0;
while (isResponsive)
{ {
ranToCompletion = true; if (process.WaitForExit(30000))
break; {
ranToCompletion = true;
break;
}
cancellationToken.ThrowIfCancellationRequested();
var jpegCount = Directory.GetFiles(targetDirectory)
.Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase));
isResponsive = (jpegCount > lastCount);
lastCount = jpegCount;
} }
cancellationToken.ThrowIfCancellationRequested(); if (!ranToCompletion)
{
var jpegCount = Directory.GetFiles(targetDirectory) StopProcess(processWrapper, 1000, false);
.Count(i => string.Equals(Path.GetExtension(i), ".jpg", StringComparison.OrdinalIgnoreCase)); }
isResponsive = (jpegCount > lastCount);
lastCount = jpegCount;
} }
finally
if (!ranToCompletion)
{ {
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) if (exitCode == -1)
{ {
var msg = string.Format("ffmpeg image extraction failed for {0}", inputArgument); 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 readonly Process Process;
public bool HasExited; public bool HasExited;
@ -810,6 +815,25 @@ namespace MediaBrowser.MediaEncoding.Encoder
process.Dispose(); 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;
}
}
} }
} }
} }

View file

@ -1,4 +1,5 @@
using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.MediaInfo;
using System;
using System.Collections.Generic; using System.Collections.Generic;
namespace MediaBrowser.Model.Dlna namespace MediaBrowser.Model.Dlna
@ -164,7 +165,7 @@ namespace MediaBrowser.Model.Dlna
if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn)) if (mediaProfile != null && !string.IsNullOrEmpty(mediaProfile.OrgPn))
{ {
orgPnValues.AddRange(mediaProfile.OrgPn.Split(',')); orgPnValues.AddRange(mediaProfile.OrgPn.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries));
} }
else else
{ {

View file

@ -38,12 +38,9 @@ namespace MediaBrowser.Providers.Manager
{ {
var hasChanges = false; var hasChanges = false;
var localImageProviders = providers.OfType<ILocalImageFileProvider>() if (!(item is Photo))
.ToList();
if (localImageProviders.Count > 0 || !(item is Photo))
{ {
var images = localImageProviders var images = providers.OfType<ILocalImageFileProvider>()
.SelectMany(i => i.GetImages(item, directoryService)) .SelectMany(i => i.GetImages(item, directoryService))
.ToList(); .ToList();
@ -425,19 +422,14 @@ namespace MediaBrowser.Providers.Manager
var changed = false; var changed = false;
var newImages = images.Where(i => i.Type == type).ToList(); var newImages = images.Where(i => i.Type == type).ToList();
if (newImages.Count > 0)
{ var newImageFileInfos = newImages
var newImageFileInfos = images.Where(i => i.Type == type)
.Select(i => i.FileInfo) .Select(i => i.FileInfo)
.ToList(); .ToList();
if (newImageFileInfos.Count > 0) if (item.AddImages(type, newImageFileInfos))
{ {
if (item.AddImages(type, newImageFileInfos)) changed = true;
{
changed = true;
}
}
} }
return changed; return changed;

View file

@ -1447,5 +1447,6 @@
"LabelServerHostHelp": "192.168.1.100 or https://myserver.com", "LabelServerHostHelp": "192.168.1.100 or https://myserver.com",
"LabelServerPort": "Port:", "LabelServerPort": "Port:",
"HeaderNewServer": "New Server", "HeaderNewServer": "New Server",
"ButtonChangeServer": "Change Server" "ButtonChangeServer": "Change Server",
"HeaderConnectToServer": "Connect to Server"
} }

View file

@ -301,7 +301,7 @@ namespace MediaBrowser.WebDashboard.Api
var builder = new StringBuilder(); var builder = new StringBuilder();
foreach (var file in new[] var apiClientFiles = new[]
{ {
"thirdparty/apiclient/logger.js", "thirdparty/apiclient/logger.js",
"thirdparty/apiclient/md5.js", "thirdparty/apiclient/md5.js",
@ -314,10 +314,20 @@ namespace MediaBrowser.WebDashboard.Api
"thirdparty/apiclient/events.js", "thirdparty/apiclient/events.js",
"thirdparty/apiclient/deferred.js", "thirdparty/apiclient/deferred.js",
"thirdparty/apiclient/apiclient.js", "thirdparty/apiclient/apiclient.js",
"thirdparty/apiclient/connectservice.js", "thirdparty/apiclient/connectservice.js"
"thirdparty/apiclient/serverdiscovery.js", }.ToList();
"thirdparty/apiclient/connectionmanager.js"
}) 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)) using (var fs = _fileSystem.GetFileStream(GetDashboardResourcePath(file), FileMode.Open, FileAccess.Read, FileShare.ReadWrite, true))
{ {

View file

@ -210,6 +210,9 @@
<Content Include="dashboard-ui\thirdparty\apiclient\connectservice.js"> <Content Include="dashboard-ui\thirdparty\apiclient\connectservice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>
<Content Include="dashboard-ui\thirdparty\apiclient\cordova\serverdiscovery.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\thirdparty\apiclient\deferred.js"> <Content Include="dashboard-ui\thirdparty\apiclient\deferred.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content> </Content>