Merge pull request #1494 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-02-24 12:02:01 -05:00
commit 5b5b5ab645
15 changed files with 138 additions and 72 deletions

View File

@ -155,6 +155,7 @@ namespace Emby.Drawing.ImageMagick
AutoOrientImage(originalImage);
}
AddForegroundLayer(originalImage, options);
DrawIndicator(originalImage, width, height, options);
originalImage.CurrentImage.CompressionQuality = quality;
@ -177,6 +178,8 @@ namespace Emby.Drawing.ImageMagick
}
wand.CurrentImage.CompositeImage(originalImage, CompositeOperator.OverCompositeOp, 0, 0);
AddForegroundLayer(wand, options);
DrawIndicator(wand, width, height, options);
wand.CurrentImage.CompressionQuality = quality;
@ -189,6 +192,16 @@ namespace Emby.Drawing.ImageMagick
SaveDelay();
}
private void AddForegroundLayer(MagickWand wand, ImageProcessingOptions options)
{
if (string.IsNullOrWhiteSpace(options.ForegroundLayer))
{
return;
}
// TODO
}
private void AutoOrientImage(MagickWand wand)
{
wand.CurrentImage.AutoOrientImage();

View File

@ -234,7 +234,7 @@ namespace Emby.Drawing
var quality = options.Quality;
var outputFormat = GetOutputFormat(options.SupportedOutputFormats[0]);
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor);
var cacheFilePath = GetCacheFilePath(originalImagePath, newSize, quality, dateModified, outputFormat, options.AddPlayedIndicator, options.PercentPlayed, options.UnplayedCount, options.BackgroundColor, options.ForegroundLayer);
var semaphore = GetLock(cacheFilePath);
@ -473,7 +473,7 @@ namespace Emby.Drawing
/// <summary>
/// Gets the cache file path based on a set of parameters
/// </summary>
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor)
private string GetCacheFilePath(string originalPath, ImageSize outputSize, int quality, DateTime dateModified, ImageFormat format, bool addPlayedIndicator, double percentPlayed, int? unwatchedCount, string backgroundColor, string foregroundLayer)
{
var filename = originalPath;
@ -507,6 +507,11 @@ namespace Emby.Drawing
filename += "b=" + backgroundColor;
}
if (!string.IsNullOrEmpty(foregroundLayer))
{
filename += "fl=" + foregroundLayer;
}
filename += "v=" + Version;
return GetCachePath(ResizedImageCachePath, filename, "." + format.ToString().ToLower());

View File

@ -66,7 +66,10 @@ namespace MediaBrowser.Api.Images
[ApiMember(Name = "BackgroundColor", Description = "Optional. Apply a background color for transparent images.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string BackgroundColor { get; set; }
[ApiMember(Name = "ForegroundLayer", Description = "Optional. Apply a foreground layer on top of the image.", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public string ForegroundLayer { get; set; }
public ImageRequest()
{
EnableImageEnhancers = true;

View File

@ -624,6 +624,7 @@ namespace MediaBrowser.Api.Images
PercentPlayed = request.PercentPlayed ?? 0,
UnplayedCount = request.UnplayedCount,
BackgroundColor = request.BackgroundColor,
ForegroundLayer = request.ForegroundLayer,
SupportedOutputFormats = supportedFormats
};

View File

@ -477,7 +477,7 @@ namespace MediaBrowser.Api.Playback
var pts = string.Empty;
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream)
if (state.SubtitleStream != null && state.SubtitleStream.IsTextSubtitleStream && !state.VideoRequest.CopyTimestamps)
{
var seconds = TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds;
@ -604,6 +604,10 @@ namespace MediaBrowser.Api.Playback
{
var seconds = Math.Round(TimeSpan.FromTicks(state.Request.StartTimeTicks ?? 0).TotalSeconds);
var setPtsParam = state.VideoRequest.CopyTimestamps
? string.Empty
: string.Format(",setpts=PTS -{0}/TB", seconds.ToString(UsCulture));
if (state.SubtitleStream.IsExternal)
{
var subtitlePath = state.SubtitleStream.Path;
@ -621,18 +625,18 @@ namespace MediaBrowser.Api.Playback
}
// TODO: Perhaps also use original_size=1920x800 ??
return string.Format("subtitles=filename='{0}'{1},setpts=PTS -{2}/TB",
return string.Format("subtitles=filename='{0}'{1}{2}",
MediaEncoder.EscapeSubtitleFilterPath(subtitlePath),
charsetParam,
seconds.ToString(UsCulture));
setPtsParam);
}
var mediaPath = state.MediaPath ?? string.Empty;
return string.Format("subtitles='{0}:si={1}',setpts=PTS -{2}/TB",
return string.Format("subtitles='{0}:si={1}'{2}",
MediaEncoder.EscapeSubtitleFilterPath(mediaPath),
state.InternalSubtitleStreamOffset.ToString(UsCulture),
seconds.ToString(UsCulture));
setPtsParam);
}
/// <summary>

View File

@ -65,7 +65,8 @@ 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, IJsonSerializer jsonSerializer, IImageProcessor imageProcessor, IHttpClient httpClient) : base(serverConfig, userManager, libraryManager, isoManager, mediaEncoder, fileSystem, dlnaManager, subtitleEncoder, deviceManager, mediaSourceManager, zipClient, jsonSerializer, 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)
{
}
@ -137,11 +138,6 @@ namespace MediaBrowser.Api.Playback.Progressive
var isOutputMkv = string.Equals(state.OutputContainer, "mkv", StringComparison.OrdinalIgnoreCase);
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
{
args += " -copyts -avoid_negative_ts disabled -start_at_zero";
}
if (string.Equals(videoCodec, "copy", StringComparison.OrdinalIgnoreCase))
{
if (state.VideoStream != null && IsH264(state.VideoStream) &&
@ -160,10 +156,22 @@ namespace MediaBrowser.Api.Playback.Progressive
var hasGraphicalSubs = state.SubtitleStream != null && !state.SubtitleStream.IsTextSubtitleStream;
var hasCopyTs = false;
// Add resolution params, if specified
if (!hasGraphicalSubs)
{
args += GetOutputSizeParam(state, videoCodec);
var outputSizeParam = GetOutputSizeParam(state, videoCodec);
args += outputSizeParam;
hasCopyTs = outputSizeParam.IndexOf("copyts", StringComparison.OrdinalIgnoreCase) != -1;
}
if (state.RunTimeTicks.HasValue && state.VideoRequest.CopyTimestamps)
{
if (!hasCopyTs)
{
args += " -copyts";
}
args += " -avoid_negative_ts disabled -start_at_zero";
}
var qualityParam = GetVideoQualityParam(state, videoCodec);

View File

@ -20,7 +20,7 @@ namespace MediaBrowser.Common.Implementations.Networking
Logger = logger;
}
private volatile List<IPAddress> _localIpAddresses;
private List<IPAddress> _localIpAddresses;
private readonly object _localIpAddressSyncLock = new object();
/// <summary>
@ -29,24 +29,20 @@ namespace MediaBrowser.Common.Implementations.Networking
/// <returns>IPAddress.</returns>
public IEnumerable<IPAddress> GetLocalIpAddresses()
{
const int cacheMinutes = 3;
var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
const int cacheMinutes = 5;
if (_localIpAddresses == null || forceRefresh)
lock (_localIpAddressSyncLock)
{
lock (_localIpAddressSyncLock)
var forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
if (_localIpAddresses == null || forceRefresh)
{
forceRefresh = (DateTime.UtcNow - _lastRefresh).TotalMinutes >= cacheMinutes;
var addresses = GetLocalIpAddressesInternal().ToList();
if (_localIpAddresses == null || forceRefresh)
{
var addresses = GetLocalIpAddressesInternal().ToList();
_localIpAddresses = addresses;
_lastRefresh = DateTime.UtcNow;
_localIpAddresses = addresses;
_lastRefresh = DateTime.UtcNow;
return addresses;
}
return addresses;
}
}

View File

@ -103,7 +103,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
Logger = logger;
_fileSystem = fileSystem;
ReloadTriggerEvents(true);
InitTriggerEvents();
}
/// <summary>
@ -233,11 +233,7 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
/// <summary>
/// The _triggers
/// </summary>
private volatile List<ITaskTrigger> _triggers;
/// <summary>
/// The _triggers sync lock
/// </summary>
private readonly object _triggersSyncLock = new object();
private List<ITaskTrigger> _triggers;
/// <summary>
/// Gets the triggers that define when the task will run
/// </summary>
@ -247,17 +243,6 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
{
get
{
if (_triggers == null)
{
lock (_triggersSyncLock)
{
if (_triggers == null)
{
_triggers = LoadTriggers();
}
}
}
return _triggers;
}
set
@ -303,6 +288,12 @@ namespace MediaBrowser.Common.Implementations.ScheduledTasks
}
}
private void InitTriggerEvents()
{
_triggers = LoadTriggers();
ReloadTriggerEvents(true);
}
public void ReloadTriggerEvents()
{
ReloadTriggerEvents(false);

View File

@ -39,6 +39,7 @@ namespace MediaBrowser.Controller.Drawing
public double PercentPlayed { get; set; }
public string BackgroundColor { get; set; }
public string ForegroundLayer { get; set; }
public bool HasDefaultOptions(string originalImagePath)
{
@ -83,7 +84,8 @@ namespace MediaBrowser.Controller.Drawing
!AddPlayedIndicator &&
PercentPlayed.Equals(0) &&
!UnplayedCount.HasValue &&
string.IsNullOrEmpty(BackgroundColor);
string.IsNullOrEmpty(BackgroundColor) &&
string.IsNullOrEmpty(ForegroundLayer);
}
private bool IsFormatSupported(string originalImagePath)

View File

@ -31,6 +31,7 @@ namespace MediaBrowser.Model.LiveTv
public string Type { get; set; }
public bool ImportFavoritesOnly { get; set; }
public bool IsEnabled { get; set; }
public string GuideGroup { get; set; }
public TunerHostInfo()
{
@ -48,5 +49,6 @@ namespace MediaBrowser.Model.LiveTv
public string ZipCode { get; set; }
public string Country { get; set; }
public string Path { get; set; }
public string GuideGroup { get; set; }
}
}

View File

@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.FileOrganization
if (previousResult != null)
{
// Don't keep saving the same result over and over if nothing has changed
if (previousResult.Status == result.Status && result.Status != FileSortingStatus.Success)
if (previousResult.Status == result.Status && previousResult.StatusMessage == result.StatusMessage && result.Status != FileSortingStatus.Success)
{
return previousResult;
}

View File

@ -125,10 +125,21 @@ namespace MediaBrowser.Server.Implementations.Library.Validators
validIds.Add(item.Id);
var hasMetdata = !string.IsNullOrWhiteSpace(item.Overview);
var performFullRefresh = !hasMetdata && (DateTime.UtcNow - item.DateLastRefreshed).TotalDays >= 30;
var defaultMetadataRefreshMode = performFullRefresh
? MetadataRefreshMode.FullRefresh
: MetadataRefreshMode.Default;
var imageRefreshMode = performFullRefresh
? ImageRefreshMode.FullRefresh
: ImageRefreshMode.Default;
var options = new MetadataRefreshOptions(_fileSystem)
{
MetadataRefreshMode = person.Value ? MetadataRefreshMode.Default : MetadataRefreshMode.ValidationOnly,
ImageRefreshMode = person.Value ? ImageRefreshMode.Default : ImageRefreshMode.ValidationOnly
MetadataRefreshMode = person.Value ? defaultMetadataRefreshMode : MetadataRefreshMode.ValidationOnly,
ImageRefreshMode = person.Value ? imageRefreshMode : ImageRefreshMode.ValidationOnly
};
await item.RefreshMetadata(options, cancellationToken).ConfigureAwait(false);

View File

@ -13,7 +13,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
where T : class
{
private readonly object _fileDataLock = new object();
private volatile List<T> _items;
private List<T> _items;
private readonly IJsonSerializer _jsonSerializer;
protected readonly ILogger Logger;
private readonly string _dataPath;
@ -31,17 +31,14 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV
public IReadOnlyList<T> GetAll()
{
if (_items == null)
lock (_fileDataLock)
{
lock (_fileDataLock)
if (_items == null)
{
if (_items == null)
{
_items = GetItemsFromFile(_dataPath);
}
_items = GetItemsFromFile(_dataPath);
}
return _items;
}
return _items;
}
private List<T> GetItemsFromFile(string path)

View File

@ -466,12 +466,6 @@
<Content Include="dashboard-ui\components\tvproviders\schedulesdirect.template.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\textprocessor-en-us.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voice.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\dashboardhosting.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -550,9 +544,6 @@
<Content Include="dashboard-ui\scripts\userpassword.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\scripts\wizardagreement.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -1402,6 +1393,42 @@
<Content Include="dashboard-ui\userpassword.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\controlcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\disablecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\enablecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\playcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\searchcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\showcommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\commands\togglecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\grammarprocessor.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voicedialog.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voice.css">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voice.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\voice\voicecommands.js">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
<Content Include="dashboard-ui\wizardagreement.html">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
@ -2232,6 +2259,15 @@
</None>
<None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\LICENSE" />
<None Include="dashboard-ui\thirdparty\social-share-kit-1.0.4\README.md" />
<None Include="dashboard-ui\voice\grammar\en-US.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="dashboard-ui\voice\grammar\grammar.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="dashboard-ui\voice\Readme.md">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup />

View File

@ -1,7 +1,7 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 2013
VisualStudioVersion = 12.0.31101.0
# Visual Studio 14
VisualStudioVersion = 14.0.24720.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{F0E0E64C-2A6F-4E35-9533-D53AC07C2CD1}"
EndProject
@ -521,7 +521,4 @@ Global
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(Performance) = preSolution
HasPerformanceSessions = true
EndGlobalSection
EndGlobal