Merge pull request #1925 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2016-07-07 12:01:35 -04:00 committed by GitHub
commit 63ae4310f4
2 changed files with 81 additions and 60 deletions

View File

@ -120,6 +120,15 @@ namespace MediaBrowser.MediaEncoding.Subtitles
bool preserveOriginalTimestamps, bool preserveOriginalTimestamps,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (string.IsNullOrWhiteSpace(itemId))
{
throw new ArgumentNullException("itemId");
}
if (string.IsNullOrWhiteSpace(mediaSourceId))
{
throw new ArgumentNullException("mediaSourceId");
}
var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken) var subtitle = await GetSubtitleStream(itemId, mediaSourceId, subtitleStreamIndex, cancellationToken)
.ConfigureAwait(false); .ConfigureAwait(false);
@ -141,10 +150,19 @@ namespace MediaBrowser.MediaEncoding.Subtitles
int subtitleStreamIndex, int subtitleStreamIndex,
CancellationToken cancellationToken) CancellationToken cancellationToken)
{ {
if (string.IsNullOrWhiteSpace(itemId))
{
throw new ArgumentNullException("itemId");
}
if (string.IsNullOrWhiteSpace(mediaSourceId))
{
throw new ArgumentNullException("mediaSourceId");
}
var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false); var mediaSources = await _mediaSourceManager.GetPlayackMediaSources(itemId, null, false, new[] { MediaType.Audio, MediaType.Video }, cancellationToken).ConfigureAwait(false);
var mediaSource = mediaSources var mediaSource = mediaSources
.First(i => string.Equals(i.Id, mediaSourceId)); .First(i => string.Equals(i.Id, mediaSourceId, StringComparison.OrdinalIgnoreCase));
var subtitleStream = mediaSource.MediaStreams var subtitleStream = mediaSource.MediaStreams
.First(i => i.Type == MediaStreamType.Subtitle && i.Index == subtitleStreamIndex); .First(i => i.Type == MediaStreamType.Subtitle && i.Index == subtitleStreamIndex);
@ -609,7 +627,8 @@ namespace MediaBrowser.MediaEncoding.Subtitles
throw; throw;
} }
process.StandardError.BaseStream.CopyToAsync(logFileStream); // Important - don't await the log task or we won't be able to kill ffmpeg when the user stops playback
Task.Run(() => StartStreamingLog(process.StandardError.BaseStream, logFileStream));
var ranToCompletion = process.WaitForExit(300000); var ranToCompletion = process.WaitForExit(300000);
@ -686,6 +705,33 @@ namespace MediaBrowser.MediaEncoding.Subtitles
} }
} }
private async Task StartStreamingLog(Stream source, Stream target)
{
try
{
using (var reader = new StreamReader(source))
{
while (!reader.EndOfStream)
{
var line = await reader.ReadLineAsync().ConfigureAwait(false);
var bytes = Encoding.UTF8.GetBytes(Environment.NewLine + line);
await target.WriteAsync(bytes, 0, bytes.Length).ConfigureAwait(false);
await target.FlushAsync().ConfigureAwait(false);
}
}
}
catch (ObjectDisposedException)
{
// Don't spam the log. This doesn't seem to throw in windows, but sometimes under linux
}
catch (Exception ex)
{
_logger.ErrorException("Error reading ffmpeg log", ex);
}
}
/// <summary> /// <summary>
/// Sets the ass font. /// Sets the ass font.
/// </summary> /// </summary>

View File

@ -142,55 +142,33 @@ namespace MediaBrowser.Server.Implementations.Persistence
} }
} }
private Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress<double> progress) private async Task UpdateToLatestSchema(CancellationToken cancellationToken, IProgress<double> progress)
{ {
return UpdateToLatestSchema(0, 0, null, cancellationToken, progress); var itemIds = _libraryManager.GetItemIds(new InternalItemsQuery
}
private async Task UpdateToLatestSchema(int queryStartIndex, int progressStartIndex, int? totalRecordCount, CancellationToken cancellationToken, IProgress<double> progress)
{
IEnumerable<BaseItem> items;
int numItemsToSave;
var pageSize = 1000;
if (totalRecordCount.HasValue)
{
var list = _libraryManager.GetItemList(new InternalItemsQuery
{ {
IsCurrentSchema = false, IsCurrentSchema = false,
ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name }, ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name }
StartIndex = queryStartIndex,
Limit = pageSize
}).ToList();
items = list;
numItemsToSave = list.Count;
}
else
{
var itemsResult = _libraryManager.GetItemsResult(new InternalItemsQuery
{
IsCurrentSchema = false,
ExcludeItemTypes = new[] { typeof(LiveTvProgram).Name },
StartIndex = queryStartIndex,
Limit = pageSize
}); });
totalRecordCount = itemsResult.TotalRecordCount; var numComplete = 0;
items = itemsResult.Items; var numItems = itemIds.Count;
numItemsToSave = itemsResult.Items.Length;
}
var numItems = totalRecordCount.Value;
_logger.Debug("Upgrading schema for {0} items", numItems); _logger.Debug("Upgrading schema for {0} items", numItems);
if (numItemsToSave > 0) foreach (var itemId in itemIds)
{
cancellationToken.ThrowIfCancellationRequested();
if (itemId != Guid.Empty)
{
// Somehow some invalid data got into the db. It probably predates the boundary checking
var item = _libraryManager.GetItemById(itemId);
if (item != null)
{ {
try try
{ {
await _itemRepo.SaveItems(items, cancellationToken).ConfigureAwait(false); await _itemRepo.SaveItem(item, cancellationToken).ConfigureAwait(false);
} }
catch (OperationCanceledException) catch (OperationCanceledException)
{ {
@ -200,20 +178,17 @@ namespace MediaBrowser.Server.Implementations.Persistence
{ {
_logger.ErrorException("Error saving item", ex); _logger.ErrorException("Error saving item", ex);
} }
}
}
progressStartIndex += pageSize; numComplete++;
double percent = progressStartIndex; double percent = numComplete;
percent /= numItems; percent /= numItems;
progress.Report(percent * 100); progress.Report(percent * 100);
}
var newStartIndex = queryStartIndex + (pageSize - numItemsToSave);
await UpdateToLatestSchema(newStartIndex, progressStartIndex, totalRecordCount, cancellationToken, progress).ConfigureAwait(false);
}
else
{
progress.Report(100); progress.Report(100);
} }
}
private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress) private async Task CleanDeadItems(CancellationToken cancellationToken, IProgress<double> progress)
{ {