From a7b25c065c831804c701c44f30b277c9c7689ac3 Mon Sep 17 00:00:00 2001 From: Luke Pulverenti Date: Fri, 31 Jul 2015 16:38:08 -0400 Subject: [PATCH] update stream buffering --- .../Playback/Hls/DynamicHlsService.cs | 72 +++---------------- .../Progressive/ProgressiveStreamWriter.cs | 5 +- .../Entities/TV/Episode.cs | 2 +- .../HttpServer/RangeRequestWriter.cs | 13 ++-- .../HttpServer/StreamWriter.cs | 5 +- .../LiveTv/EmbyTV/EmbyTV.cs | 2 +- 6 files changed, 27 insertions(+), 72 deletions(-) diff --git a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs index 305547e418..8ee508c4d1 100644 --- a/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs +++ b/MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs @@ -210,8 +210,6 @@ namespace MediaBrowser.Api.Playback.Hls { ApiEntryPoint.Instance.KillTranscodingJobs(request.DeviceId, request.PlaySessionId, p => false); - await ReadSegmentLengths(playlistPath).ConfigureAwait(false); - if (currentTranscodingIndex.HasValue) { DeleteLastFile(playlistPath, segmentExtension, 0); @@ -255,55 +253,8 @@ namespace MediaBrowser.Api.Playback.Hls return await GetSegmentResult(playlistPath, segmentPath, requestedIndex, segmentLength, job, cancellationToken).ConfigureAwait(false); } - private static readonly ConcurrentDictionary SegmentLengths = new ConcurrentDictionary(StringComparer.OrdinalIgnoreCase); - private async Task ReadSegmentLengths(string playlist) - { - try - { - using (var fileStream = GetPlaylistFileStream(playlist)) - { - using (var reader = new StreamReader(fileStream)) - { - double duration = -1; - - while (!reader.EndOfStream) - { - var text = await reader.ReadLineAsync().ConfigureAwait(false); - - if (text.StartsWith("#EXTINF", StringComparison.OrdinalIgnoreCase)) - { - var parts = text.Split(new[] { ':' }, 2); - if (parts.Length == 2) - { - var time = parts[1].Trim(new[] { ',' }).Trim(); - double timeValue; - if (double.TryParse(time, NumberStyles.Any, CultureInfo.InvariantCulture, out timeValue)) - { - duration = timeValue; - continue; - } - } - } - else if (duration != -1) - { - SegmentLengths.AddOrUpdate(text, duration, (k, v) => duration); - Logger.Debug("Added segment length of {0} for {1}", duration, text); - } - - duration = -1; - } - } - } - } - catch (DirectoryNotFoundException) - { - - } - catch (FileNotFoundException) - { - - } - } + // 256k + private const int BufferSize = 262144; private long GetSeekPositionTicks(StreamState state, string playlist, int requestedIndex) { @@ -455,21 +406,18 @@ namespace MediaBrowser.Api.Playback.Hls { using (var fileStream = GetPlaylistFileStream(playlistPath)) { - using (var reader = new StreamReader(fileStream)) + using (var reader = new StreamReader(fileStream, Encoding.UTF8, true, BufferSize)) { - while (!reader.EndOfStream) - { - var text = await reader.ReadLineAsync().ConfigureAwait(false); + var text = await reader.ReadToEndAsync().ConfigureAwait(false); - // If it appears in the playlist, it's done - if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + // If it appears in the playlist, it's done + if (text.IndexOf(segmentFilename, StringComparison.OrdinalIgnoreCase) != -1) + { + if (File.Exists(segmentPath)) { - if (File.Exists(segmentPath)) - { - return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); - } - break; + return GetSegmentResult(segmentPath, segmentIndex, segmentLength, transcodingJob); } + //break; } } } diff --git a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs index 6a3443f359..adedd94616 100644 --- a/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs +++ b/MediaBrowser.Api/Playback/Progressive/ProgressiveStreamWriter.cs @@ -91,6 +91,9 @@ namespace MediaBrowser.Api.Playback.Progressive private readonly IFileSystem _fileSystem; private readonly TranscodingJob _job; + // 256k + private const int BufferSize = 262144; + private long _bytesWritten = 0; public ProgressiveFileCopier(IFileSystem fileSystem, TranscodingJob job) @@ -108,7 +111,7 @@ namespace MediaBrowser.Api.Playback.Progressive { while (eofCount < 15) { - CopyToInternal(fs, outputStream, 81920); + CopyToInternal(fs, outputStream, BufferSize); var fsPosition = fs.Position; diff --git a/MediaBrowser.Controller/Entities/TV/Episode.cs b/MediaBrowser.Controller/Entities/TV/Episode.cs index 8f5b8f6cff..5163c3de4a 100644 --- a/MediaBrowser.Controller/Entities/TV/Episode.cs +++ b/MediaBrowser.Controller/Entities/TV/Episode.cs @@ -150,7 +150,7 @@ namespace MediaBrowser.Controller.Entities.TV { var series = Series; - if (ParentIndexNumber.HasValue) + if (series != null && ParentIndexNumber.HasValue) { var findNumber = ParentIndexNumber.Value; diff --git a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs index 3221141124..f204877332 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/RangeRequestWriter.cs @@ -28,6 +28,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer public Action OnComplete { get; set; } private readonly ILogger _logger; + // 256k + private const int BufferSize = 262144; + /// /// The _options /// @@ -187,7 +190,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer // If the requested range is "0-", we can optimize by just doing a stream copy if (RangeEnd >= TotalContentLength - 1) { - source.CopyTo(responseStream); + source.CopyTo(responseStream, BufferSize); } else { @@ -211,8 +214,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private void CopyToInternal(Stream source, Stream destination, long copyLength) { - const int bufferSize = 81920; - var array = new byte[bufferSize]; + var array = new byte[BufferSize]; int count; while ((count = source.Read(array, 0, array.Length)) != 0) { @@ -249,7 +251,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer // If the requested range is "0-", we can optimize by just doing a stream copy if (RangeEnd >= TotalContentLength - 1) { - await source.CopyToAsync(responseStream).ConfigureAwait(false); + await source.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false); } else { @@ -268,8 +270,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer private async Task CopyToAsyncInternal(Stream source, Stream destination, int copyLength, CancellationToken cancellationToken) { - const int bufferSize = 81920; - var array = new byte[bufferSize]; + var array = new byte[BufferSize]; int count; while ((count = await source.ReadAsync(array, 0, array.Length, cancellationToken).ConfigureAwait(false)) != 0) { diff --git a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs index fe662542ef..daa5b86d96 100644 --- a/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs +++ b/MediaBrowser.Server.Implementations/HttpServer/StreamWriter.cs @@ -81,6 +81,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer WriteToInternal(responseStream); } + // 256k + private const int BufferSize = 262144; + /// /// Writes to async. /// @@ -92,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer { using (var src = SourceStream) { - src.CopyTo(responseStream); + src.CopyTo(responseStream, BufferSize); } } catch (Exception ex) diff --git a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs index c323f8e0dc..4430b94551 100644 --- a/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs +++ b/MediaBrowser.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs @@ -525,7 +525,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.EmbyTV { using (var output = File.Open(recordPath, FileMode.Create, FileAccess.Write, FileShare.Read)) { - await response.Content.CopyToAsync(output, 4096, linkedToken); + await response.Content.CopyToAsync(output, 131072, linkedToken); } }