aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2016-05-28 19:48:26 -0400
committerLuke <luke.pulverenti@gmail.com>2016-05-28 19:48:26 -0400
commite205caee0380dc49ef4bcdb0016ef38a0c3a9ea5 (patch)
tree75409d7a5c9317cdf0a1daaca8bd3fcc2fb1f25f
parent996da16d9030b9f33d834536503d10991ec09c29 (diff)
parent2e2766bd19d6d974abe11284cc065ee7692ae1ed (diff)
Merge pull request #1786 from MediaBrowser/dev
Dev
-rw-r--r--MediaBrowser.Api/LiveTv/LiveTvService.cs4
-rw-r--r--MediaBrowser.Api/Playback/BaseStreamingService.cs9
-rw-r--r--MediaBrowser.Api/Subtitles/SubtitleService.cs6
-rw-r--r--MediaBrowser.Controller/Entities/UserViewBuilder.cs21
-rw-r--r--MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs8
-rw-r--r--MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs6
-rw-r--r--MediaBrowser.Server.Implementations/IO/FileRefresher.cs49
-rw-r--r--MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs276
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs5
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs2
-rw-r--r--MediaBrowser.WebDashboard/Api/DashboardService.cs3
11 files changed, 137 insertions, 252 deletions
diff --git a/MediaBrowser.Api/LiveTv/LiveTvService.cs b/MediaBrowser.Api/LiveTv/LiveTvService.cs
index d3a4558c8..a59b5f351 100644
--- a/MediaBrowser.Api/LiveTv/LiveTvService.cs
+++ b/MediaBrowser.Api/LiveTv/LiveTvService.cs
@@ -550,9 +550,7 @@ namespace MediaBrowser.Api.LiveTv
var response = await _httpClient.Get(new HttpRequestOptions
{
- Url = "https://json.schedulesdirect.org/20141201/available/countries",
- CacheLength = TimeSpan.FromDays(1),
- CacheMode = CacheMode.Unconditional
+ Url = "https://json.schedulesdirect.org/20141201/available/countries"
}).ConfigureAwait(false);
diff --git a/MediaBrowser.Api/Playback/BaseStreamingService.cs b/MediaBrowser.Api/Playback/BaseStreamingService.cs
index 421ccdb5d..253e3d8e4 100644
--- a/MediaBrowser.Api/Playback/BaseStreamingService.cs
+++ b/MediaBrowser.Api/Playback/BaseStreamingService.cs
@@ -1519,6 +1519,13 @@ namespace MediaBrowser.Api.Playback
}
else if (i == 25)
{
+ if (videoRequest != null)
+ {
+ videoRequest.ForceLiveStream = string.Equals("true", val, StringComparison.OrdinalIgnoreCase);
+ }
+ }
+ else if (i == 26)
+ {
if (!string.IsNullOrWhiteSpace(val) && videoRequest != null)
{
SubtitleDeliveryMethod method;
@@ -1528,7 +1535,7 @@ namespace MediaBrowser.Api.Playback
}
}
}
- else if (i == 26)
+ else if (i == 27)
{
request.TranscodingMaxAudioChannels = int.Parse(val, UsCulture);
}
diff --git a/MediaBrowser.Api/Subtitles/SubtitleService.cs b/MediaBrowser.Api/Subtitles/SubtitleService.cs
index c2183ad7b..1382527e2 100644
--- a/MediaBrowser.Api/Subtitles/SubtitleService.cs
+++ b/MediaBrowser.Api/Subtitles/SubtitleService.cs
@@ -98,6 +98,9 @@ namespace MediaBrowser.Api.Subtitles
[ApiMember(Name = "EndPositionTicks", Description = "EndPositionTicks", IsRequired = false, DataType = "string", ParameterType = "query", Verb = "GET")]
public long? EndPositionTicks { get; set; }
+
+ [ApiMember(Name = "CopyTimestamps", Description = "CopyTimestamps", IsRequired = false, DataType = "bool", ParameterType = "query", Verb = "GET")]
+ public bool CopyTimestamps { get; set; }
}
[Route("/Videos/{Id}/{MediaSourceId}/Subtitles/{Index}/subtitles.m3u8", "GET", Summary = "Gets an HLS subtitle playlist.")]
@@ -175,7 +178,7 @@ namespace MediaBrowser.Api.Subtitles
var endPositionTicks = Math.Min(runtime, positionTicks + segmentLengthTicks);
- var url = string.Format("stream.vtt?StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
+ var url = string.Format("stream.vtt?CopyTimestamps=true,StartPositionTicks={0}&EndPositionTicks={1}&api_key={2}",
positionTicks.ToString(CultureInfo.InvariantCulture),
endPositionTicks.ToString(CultureInfo.InvariantCulture),
accessToken);
@@ -222,6 +225,7 @@ namespace MediaBrowser.Api.Subtitles
request.Format,
request.StartPositionTicks,
request.EndPositionTicks,
+ request.CopyTimestamps,
CancellationToken.None).ConfigureAwait(false);
}
diff --git a/MediaBrowser.Controller/Entities/UserViewBuilder.cs b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
index d4a8b0730..2bde80641 100644
--- a/MediaBrowser.Controller/Entities/UserViewBuilder.cs
+++ b/MediaBrowser.Controller/Entities/UserViewBuilder.cs
@@ -332,13 +332,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMusicAlbumArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
+ EnableTotalRecordCount = false
- }).Cast<IHasAlbumArtist>();
+ }).Items.Cast<IHasAlbumArtist>();
var artists = _libraryManager.GetAlbumArtists(items);
@@ -347,13 +348,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetMusicArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name, typeof(MusicVideo).Name },
+ EnableTotalRecordCount = false
- }).Cast<IHasArtist>();
+ }).Items.Cast<IHasArtist>();
var artists = _libraryManager.GetArtists(items);
@@ -362,13 +364,14 @@ namespace MediaBrowser.Controller.Entities
private QueryResult<BaseItem> GetFavoriteArtists(Folder parent, User user, InternalItemsQuery query)
{
- var items = _libraryManager.GetItemList(new InternalItemsQuery(user)
+ var items = parent.QueryRecursive(new InternalItemsQuery(user)
{
Recursive = true,
ParentId = parent.Id,
- IncludeItemTypes = new[] { typeof(Audio.Audio).Name }
+ IncludeItemTypes = new[] { typeof(Audio.Audio).Name },
+ EnableTotalRecordCount = false
- }).Cast<IHasAlbumArtist>();
+ }).Items.Cast<IHasAlbumArtist>();
var artists = _libraryManager.GetAlbumArtists(items).Where(i => _userDataManager.GetUserData(user, i).IsFavorite);
diff --git a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
index e538b84d8..44489cbf5 100644
--- a/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
+++ b/MediaBrowser.Controller/MediaEncoding/ISubtitleEncoder.cs
@@ -10,13 +10,6 @@ namespace MediaBrowser.Controller.MediaEncoding
/// <summary>
/// Gets the subtitles.
/// </summary>
- /// <param name="itemId">The item identifier.</param>
- /// <param name="mediaSourceId">The media source identifier.</param>
- /// <param name="subtitleStreamIndex">Index of the subtitle stream.</param>
- /// <param name="outputFormat">The output format.</param>
- /// <param name="startTimeTicks">The start time ticks.</param>
- /// <param name="endTimeTicks">The end time ticks.</param>
- /// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task{Stream}.</returns>
Task<Stream> GetSubtitles(string itemId,
string mediaSourceId,
@@ -24,6 +17,7 @@ namespace MediaBrowser.Controller.MediaEncoding
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken);
/// <summary>
diff --git a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
index 8c33cc7c0..25adbcdb0 100644
--- a/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
+++ b/MediaBrowser.MediaEncoding/Subtitles/SubtitleEncoder.cs
@@ -58,6 +58,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken)
{
var ms = new MemoryStream();
@@ -68,7 +69,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
var trackInfo = reader.Parse(stream, cancellationToken);
- FilterEvents(trackInfo, startTimeTicks, endTimeTicks, false);
+ FilterEvents(trackInfo, startTimeTicks, endTimeTicks, preserveOriginalTimestamps);
var writer = GetWriter(outputFormat);
@@ -116,6 +117,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
string outputFormat,
long startTimeTicks,
long? endTimeTicks,
+ bool preserveOriginalTimestamps,
CancellationToken cancellationToken)
{
var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken)
@@ -130,7 +132,7 @@ namespace MediaBrowser.MediaEncoding.Subtitles
using (var stream = subtitle.Item1)
{
- return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, cancellationToken).ConfigureAwait(false);
+ return await ConvertSubtitles(stream, inputFormat, outputFormat, startTimeTicks, endTimeTicks, preserveOriginalTimestamps, cancellationToken).ConfigureAwait(false);
}
}
diff --git a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
index 74dfbc679..18c52ab29 100644
--- a/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
+++ b/MediaBrowser.Server.Implementations/IO/FileRefresher.cs
@@ -5,6 +5,7 @@ using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using CommonIO;
+using MediaBrowser.Common.Events;
using MediaBrowser.Common.ScheduledTasks;
using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
@@ -24,9 +25,14 @@ namespace MediaBrowser.Server.Implementations.IO
private readonly List<string> _affectedPaths = new List<string>();
private Timer _timer;
private readonly object _timerLock = new object();
+ public string Path { get; private set; }
+
+ public event EventHandler<EventArgs> Completed;
public FileRefresher(string path, IFileSystem fileSystem, IServerConfigurationManager configurationManager, ILibraryManager libraryManager, ITaskManager taskManager, ILogger logger)
{
+ logger.Debug("New file refresher created for {0}", path);
+ Path = path;
_affectedPaths.Add(path);
_fileSystem = fileSystem;
@@ -36,7 +42,24 @@ namespace MediaBrowser.Server.Implementations.IO
Logger = logger;
}
- private void RestartTimer()
+ private void AddAffectedPath(string path)
+ {
+ if (!_affectedPaths.Contains(path, StringComparer.Ordinal))
+ {
+ _affectedPaths.Add(path);
+ }
+ }
+
+ public void AddPath(string path)
+ {
+ lock (_timerLock)
+ {
+ AddAffectedPath(path);
+ }
+ RestartTimer();
+ }
+
+ public void RestartTimer()
{
lock (_timerLock)
{
@@ -51,6 +74,23 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
+ public void ResetPath(string path, string affectedFile)
+ {
+ lock (_timerLock)
+ {
+ Logger.Debug("Resetting file refresher from {0} to {1}", Path, path);
+
+ Path = path;
+ AddAffectedPath(path);
+
+ if (!string.IsNullOrWhiteSpace(affectedFile))
+ {
+ AddAffectedPath(affectedFile);
+ }
+ }
+ RestartTimer();
+ }
+
private async void OnTimerCallback(object state)
{
// Extend the timer as long as any of the paths are still being written to.
@@ -64,10 +104,11 @@ namespace MediaBrowser.Server.Implementations.IO
Logger.Debug("Timer stopped.");
DisposeTimer();
+ EventHelper.FireEventIfNotNull(Completed, this, EventArgs.Empty, Logger);
try
{
- await ProcessPathChanges(_affectedPaths).ConfigureAwait(false);
+ await ProcessPathChanges(_affectedPaths.ToList()).ConfigureAwait(false);
}
catch (Exception ex)
{
@@ -130,7 +171,7 @@ namespace MediaBrowser.Server.Implementations.IO
{
item = LibraryManager.FindByPath(path, null);
- path = Path.GetDirectoryName(path);
+ path = System.IO.Path.GetDirectoryName(path);
}
if (item != null)
@@ -222,7 +263,7 @@ namespace MediaBrowser.Server.Implementations.IO
}
}
- public void DisposeTimer()
+ private void DisposeTimer()
{
lock (_timerLock)
{
diff --git a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
index 09ca134d1..0690d62dd 100644
--- a/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
+++ b/MediaBrowser.Server.Implementations/IO/LibraryMonitor.cs
@@ -26,13 +26,9 @@ namespace MediaBrowser.Server.Implementations.IO
/// </summary>
private readonly ConcurrentDictionary<string, FileSystemWatcher> _fileSystemWatchers = new ConcurrentDictionary<string, FileSystemWatcher>(StringComparer.OrdinalIgnoreCase);
/// <summary>
- /// The update timer
- /// </summary>
- private Timer _updateTimer;
- /// <summary>
/// The affected paths
/// </summary>
- private readonly ConcurrentDictionary<string, string> _affectedPaths = new ConcurrentDictionary<string, string>();
+ private readonly List<FileRefresher> _activeRefreshers = new List<FileRefresher>();
/// <summary>
/// A dynamic list of paths that should be ignored. Added to during our own file sytem modifications.
@@ -44,8 +40,8 @@ namespace MediaBrowser.Server.Implementations.IO
/// </summary>
private readonly IReadOnlyList<string> _alwaysIgnoreFiles = new List<string>
{
- "thumbs.db",
- "small.jpg",
+ "thumbs.db",
+ "small.jpg",
"albumart.jpg",
// WMC temp recording directories that will constantly be written to
@@ -54,11 +50,6 @@ namespace MediaBrowser.Server.Implementations.IO
};
/// <summary>
- /// The timer lock
- /// </summary>
- private readonly object _timerLock = new object();
-
- /// <summary>
/// Add the path to our temporary ignore list. Use when writing to a path within our listening scope.
/// </summary>
/// <param name="path">The path.</param>
@@ -463,226 +454,58 @@ namespace MediaBrowser.Server.Implementations.IO
if (monitorPath)
{
// Avoid implicitly captured closure
- var affectedPath = path;
- _affectedPaths.AddOrUpdate(path, path, (key, oldValue) => affectedPath);
- }
-
- RestartTimer();
- }
-
- private void RestartTimer()
- {
- lock (_timerLock)
- {
- if (_updateTimer == null)
- {
- _updateTimer = new Timer(TimerStopped, null, TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
- }
- else
- {
- _updateTimer.Change(TimeSpan.FromSeconds(ConfigurationManager.Configuration.LibraryMonitorDelay), TimeSpan.FromMilliseconds(-1));
- }
- }
- }
-
- /// <summary>
- /// Timers the stopped.
- /// </summary>
- /// <param name="stateInfo">The state info.</param>
- private async void TimerStopped(object stateInfo)
- {
- // Extend the timer as long as any of the paths are still being written to.
- if (_affectedPaths.Any(p => IsFileLocked(p.Key)))
- {
- Logger.Info("Timer extended.");
- RestartTimer();
- return;
- }
-
- Logger.Debug("Timer stopped.");
-
- DisposeTimer();
-
- var paths = _affectedPaths.Keys.ToList();
- _affectedPaths.Clear();
-
- try
- {
- await ProcessPathChanges(paths).ConfigureAwait(false);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error processing directory changes", ex);
+ CreateRefresher(path);
}
}
- private bool IsFileLocked(string path)
+ private void CreateRefresher(string path)
{
- if (Environment.OSVersion.Platform != PlatformID.Win32NT)
- {
- // Causing lockups on linux
- return false;
- }
+ var parentPath = Path.GetDirectoryName(path);
- try
+ lock (_activeRefreshers)
{
- var data = _fileSystem.GetFileSystemInfo(path);
-
- if (!data.Exists
- || data.IsDirectory
-
- // Opening a writable stream will fail with readonly files
- || data.Attributes.HasFlag(FileAttributes.ReadOnly))
+ var refreshers = _activeRefreshers.ToList();
+ foreach (var refresher in refreshers)
{
- return false;
- }
- }
- catch (IOException)
- {
- return false;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error getting file system info for: {0}", ex, path);
- return false;
- }
-
- // In order to determine if the file is being written to, we have to request write access
- // But if the server only has readonly access, this is going to cause this entire algorithm to fail
- // So we'll take a best guess about our access level
- var requestedFileAccess = ConfigurationManager.Configuration.SaveLocalMeta
- ? FileAccess.ReadWrite
- : FileAccess.Read;
+ // Path is already being refreshed
+ if (string.Equals(path, refresher.Path, StringComparison.Ordinal))
+ {
+ refresher.RestartTimer();
+ return;
+ }
- try
- {
- using (_fileSystem.GetFileStream(path, FileMode.Open, requestedFileAccess, FileShare.ReadWrite))
- {
- if (_updateTimer != null)
+ // Parent folder is already being refreshed
+ if (_fileSystem.ContainsSubPath(refresher.Path, path))
{
- //file is not locked
- return false;
+ refresher.AddPath(path);
+ return;
}
- }
- }
- catch (DirectoryNotFoundException)
- {
- // File may have been deleted
- return false;
- }
- catch (FileNotFoundException)
- {
- // File may have been deleted
- return false;
- }
- catch (IOException)
- {
- //the file is unavailable because it is:
- //still being written to
- //or being processed by another thread
- //or does not exist (has already been processed)
- Logger.Debug("{0} is locked.", path);
- return true;
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error determining if file is locked: {0}", ex, path);
- return false;
- }
- return false;
- }
+ // New path is a parent
+ if (_fileSystem.ContainsSubPath(path, refresher.Path))
+ {
+ refresher.ResetPath(path, null);
+ return;
+ }
- private void DisposeTimer()
- {
- lock (_timerLock)
- {
- if (_updateTimer != null)
- {
- _updateTimer.Dispose();
- _updateTimer = null;
+ // They are siblings. Rebase the refresher to the parent folder.
+ if (string.Equals(parentPath, Path.GetDirectoryName(refresher.Path), StringComparison.Ordinal))
+ {
+ refresher.ResetPath(parentPath, path);
+ return;
+ }
}
- }
- }
-
- /// <summary>
- /// Processes the path changes.
- /// </summary>
- /// <param name="paths">The paths.</param>
- /// <returns>Task.</returns>
- private async Task ProcessPathChanges(List<string> paths)
- {
- var itemsToRefresh = paths
- .Select(GetAffectedBaseItem)
- .Where(item => item != null)
- .Distinct()
- .ToList();
-
- foreach (var p in paths)
- {
- Logger.Info(p + " reports change.");
- }
-
- // If the root folder changed, run the library task so the user can see it
- if (itemsToRefresh.Any(i => i is AggregateFolder))
- {
- TaskManager.CancelIfRunningAndQueue<RefreshMediaLibraryTask>();
- return;
- }
-
- foreach (var item in itemsToRefresh)
- {
- Logger.Info(item.Name + " (" + item.Path + ") will be refreshed.");
- try
- {
- await item.ChangedExternally().ConfigureAwait(false);
- }
- catch (IOException ex)
- {
- // For now swallow and log.
- // Research item: If an IOException occurs, the item may be in a disconnected state (media unavailable)
- // Should we remove it from it's parent?
- Logger.ErrorException("Error refreshing {0}", ex, item.Name);
- }
- catch (Exception ex)
- {
- Logger.ErrorException("Error refreshing {0}", ex, item.Name);
- }
+ var newRefresher = new FileRefresher(path, _fileSystem, ConfigurationManager, LibraryManager, TaskManager, Logger);
+ newRefresher.Completed += NewRefresher_Completed;
+ _activeRefreshers.Add(newRefresher);
}
}
- /// <summary>
- /// Gets the affected base item.
- /// </summary>
- /// <param name="path">The path.</param>
- /// <returns>BaseItem.</returns>
- private BaseItem GetAffectedBaseItem(string path)
+ private void NewRefresher_Completed(object sender, EventArgs e)
{
- BaseItem item = null;
-
- while (item == null && !string.IsNullOrEmpty(path))
- {
- item = LibraryManager.FindByPath(path, null);
-
- path = Path.GetDirectoryName(path);
- }
-
- if (item != null)
- {
- // If the item has been deleted find the first valid parent that still exists
- while (!_fileSystem.DirectoryExists(item.Path) && !_fileSystem.FileExists(item.Path))
- {
- item = item.GetParent();
-
- if (item == null)
- {
- break;
- }
- }
- }
-
- return item;
+ var refresher = (FileRefresher)sender;
+ DisposeRefresher(refresher);
}
/// <summary>
@@ -713,10 +536,29 @@ namespace MediaBrowser.Server.Implementations.IO
watcher.Dispose();
}
- DisposeTimer();
-
_fileSystemWatchers.Clear();
- _affectedPaths.Clear();
+ DisposeRefreshers();
+ }
+
+ private void DisposeRefresher(FileRefresher refresher)
+ {
+ lock (_activeRefreshers)
+ {
+ refresher.Dispose();
+ _activeRefreshers.Remove(refresher);
+ }
+ }
+
+ private void DisposeRefreshers()
+ {
+ lock (_activeRefreshers)
+ {
+ foreach (var refresher in _activeRefreshers.ToList())
+ {
+ refresher.Dispose();
+ }
+ _activeRefreshers.Clear();
+ }
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index bbdc4ab0d..e126e5411 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1959,10 +1959,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var defaults = await GetNewTimerDefaultsInternal(cancellationToken, program).ConfigureAwait(false);
var info = _tvDtoService.GetSeriesTimerInfoDto(defaults.Item1, defaults.Item2, null);
- info.Days = new List<DayOfWeek>
- {
- program.StartDate.ToLocalTime().DayOfWeek
- };
+ info.Days = defaults.Item1.Days;
info.DayPattern = _tvDtoService.GetDayPattern(info.Days);
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
index bbba06870..398dcc86b 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncJobProcessor.cs
@@ -748,7 +748,7 @@ namespace MediaBrowser.Server.Implementations.Sync
_fileSystem.CreateDirectory(Path.GetDirectoryName(path));
- using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, cancellationToken).ConfigureAwait(false))
+ using (var stream = await _subtitleEncoder.GetSubtitles(streamInfo.ItemId, streamInfo.MediaSourceId, subtitleStreamIndex, subtitleStreamInfo.Format, 0, null, false, cancellationToken).ConfigureAwait(false))
{
using (var fs = _fileSystem.GetFileStream(path, FileMode.Create, FileAccess.Write, FileShare.Read, true))
{
diff --git a/MediaBrowser.WebDashboard/Api/DashboardService.cs b/MediaBrowser.WebDashboard/Api/DashboardService.cs
index 1569c1fc5..904953cfc 100644
--- a/MediaBrowser.WebDashboard/Api/DashboardService.cs
+++ b/MediaBrowser.WebDashboard/Api/DashboardService.cs
@@ -356,9 +356,6 @@ namespace MediaBrowser.WebDashboard.Api
DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "meteor");
DeleteFoldersByName(Path.Combine(bowerPath, "Sortable"), "st");
DeleteFoldersByName(Path.Combine(bowerPath, "Swiper"), "src");
- DeleteFoldersByName(Path.Combine(bowerPath, "material-design-lite"), "src");
- DeleteFoldersByName(Path.Combine(bowerPath, "material-design-lite"), "utils");
- _fileSystem.DeleteFile(Path.Combine(bowerPath, "material-design-lite", "gulpfile.babel.js"));
_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "marked"), true);
_fileSystem.DeleteDirectory(Path.Combine(bowerPath, "marked-element"), true);