mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-13 13:52:16 +01:00
avoid buffering http responses
This commit is contained in:
@@ -127,7 +127,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
|
||||
// Seeing block length errors with our server
|
||||
EnableHttpCompression = false,
|
||||
PreferIpv4 = preferIpv4
|
||||
PreferIpv4 = preferIpv4,
|
||||
BufferContent = false
|
||||
|
||||
}).ConfigureAwait(false))
|
||||
{
|
||||
|
||||
@@ -266,7 +266,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
options.SetPostData(postData);
|
||||
@@ -314,7 +315,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
options.SetPostData(postData);
|
||||
@@ -464,7 +466,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
var accessToken = Guid.NewGuid().ToString("N");
|
||||
@@ -599,7 +602,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
var accessToken = Guid.NewGuid().ToString("N");
|
||||
@@ -652,7 +656,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
var postData = new Dictionary<string, string>
|
||||
@@ -726,7 +731,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
CancellationToken = cancellationToken,
|
||||
Url = url
|
||||
Url = url,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
SetServerAccessToken(options);
|
||||
@@ -790,7 +796,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
SetServerAccessToken(options);
|
||||
@@ -1078,7 +1085,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
var postData = new Dictionary<string, string>
|
||||
@@ -1126,7 +1134,8 @@ namespace MediaBrowser.Server.Implementations.Connect
|
||||
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = GetConnectUrl("user/authenticate")
|
||||
Url = GetConnectUrl("user/authenticate"),
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
options.SetPostData(new Dictionary<string, string>
|
||||
|
||||
@@ -1176,6 +1176,12 @@ namespace MediaBrowser.Server.Implementations.Dto
|
||||
.Except(foundArtists, new DistinctNameComparer())
|
||||
.Select(i =>
|
||||
{
|
||||
// This should not be necessary but we're seeing some cases of it
|
||||
if (string.IsNullOrWhiteSpace(i))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var artist = _libraryManager.GetArtist(i);
|
||||
if (artist != null)
|
||||
{
|
||||
|
||||
@@ -64,7 +64,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||
EnableHttpCompression = false,
|
||||
|
||||
LogRequest = false,
|
||||
LogErrors = logErrors
|
||||
LogErrors = logErrors,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
options.SetPostData(data);
|
||||
@@ -114,7 +115,8 @@ namespace MediaBrowser.Server.Implementations.EntryPoints
|
||||
EnableHttpCompression = false,
|
||||
|
||||
LogRequest = false,
|
||||
LogErrors = logErrors
|
||||
LogErrors = logErrors,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
options.SetPostData(data);
|
||||
|
||||
@@ -19,6 +19,7 @@ using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Common.Security;
|
||||
using MediaBrowser.Model.Extensions;
|
||||
@@ -45,16 +46,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
private readonly IServerConfigurationManager _config;
|
||||
private readonly INetworkManager _networkManager;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public HttpListenerHost(IApplicationHost applicationHost,
|
||||
ILogManager logManager,
|
||||
IServerConfigurationManager config,
|
||||
string serviceName,
|
||||
string defaultRedirectPath, INetworkManager networkManager, params Assembly[] assembliesWithServices)
|
||||
string defaultRedirectPath, INetworkManager networkManager, IMemoryStreamProvider memoryStreamProvider, params Assembly[] assembliesWithServices)
|
||||
: base(serviceName, assembliesWithServices)
|
||||
{
|
||||
DefaultRedirectPath = defaultRedirectPath;
|
||||
_networkManager = networkManager;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
_config = config;
|
||||
|
||||
_logger = logManager.GetLogger("HttpServer");
|
||||
@@ -95,6 +98,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
container.Adapter = _containerAdapter;
|
||||
|
||||
Plugins.RemoveAll(x => x is NativeTypesFeature);
|
||||
Plugins.Add(new SwaggerFeature());
|
||||
Plugins.Add(new CorsFeature(allowedHeaders: "Content-Type, Authorization, Range, X-MediaBrowser-Token, X-Emby-Authorization"));
|
||||
|
||||
@@ -179,7 +183,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
private IHttpListener GetListener()
|
||||
{
|
||||
return new WebSocketSharpListener(_logger, CertificatePath);
|
||||
return new WebSocketSharpListener(_logger, CertificatePath, _memoryStreamProvider);
|
||||
}
|
||||
|
||||
private void OnWebSocketConnecting(WebSocketConnectingEventArgs args)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using MediaBrowser.Common;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Common.Net;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Net;
|
||||
@@ -15,23 +16,18 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
/// <summary>
|
||||
/// Creates the server.
|
||||
/// </summary>
|
||||
/// <param name="applicationHost">The application host.</param>
|
||||
/// <param name="logManager">The log manager.</param>
|
||||
/// <param name="config">The configuration.</param>
|
||||
/// <param name="_networkmanager">The _networkmanager.</param>
|
||||
/// <param name="serverName">Name of the server.</param>
|
||||
/// <param name="defaultRedirectpath">The default redirectpath.</param>
|
||||
/// <returns>IHttpServer.</returns>
|
||||
public static IHttpServer CreateServer(IApplicationHost applicationHost,
|
||||
ILogManager logManager,
|
||||
IServerConfigurationManager config,
|
||||
INetworkManager _networkmanager,
|
||||
IMemoryStreamProvider streamProvider,
|
||||
string serverName,
|
||||
string defaultRedirectpath)
|
||||
{
|
||||
LogManager.LogFactory = new ServerLogFactory(logManager);
|
||||
|
||||
return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager);
|
||||
return new HttpListenerHost(applicationHost, logManager, config, serverName, defaultRedirectpath, _networkmanager, streamProvider);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,11 +39,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
if (boundary == null)
|
||||
return;
|
||||
|
||||
using (var requestStream = GetSubStream(InputStream))
|
||||
using (var requestStream = GetSubStream(InputStream, _memoryStreamProvider))
|
||||
{
|
||||
//DB: 30/01/11 - Hack to get around non-seekable stream and received HTTP request
|
||||
//Not ending with \r\n?
|
||||
var ms = new MemoryStream(32 * 1024);
|
||||
var ms = _memoryStreamProvider.CreateNew(32 * 1024);
|
||||
await requestStream.CopyToAsync(ms).ConfigureAwait(false);
|
||||
|
||||
var input = ms;
|
||||
@@ -229,9 +229,9 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
|
||||
async Task LoadWwwForm()
|
||||
{
|
||||
using (Stream input = GetSubStream(InputStream))
|
||||
using (Stream input = GetSubStream(InputStream, _memoryStreamProvider))
|
||||
{
|
||||
using (var ms = new MemoryStream())
|
||||
using (var ms = _memoryStreamProvider.CreateNew())
|
||||
{
|
||||
await input.CopyToAsync(ms).ConfigureAwait(false);
|
||||
ms.Position = 0;
|
||||
|
||||
@@ -9,6 +9,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
@@ -18,11 +19,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
|
||||
private readonly ILogger _logger;
|
||||
private readonly string _certificatePath;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public WebSocketSharpListener(ILogger logger, string certificatePath)
|
||||
public WebSocketSharpListener(ILogger logger, string certificatePath, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
_certificatePath = certificatePath;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
}
|
||||
|
||||
public Action<Exception, IRequest> ErrorHandler { get; set; }
|
||||
@@ -148,7 +151,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
{
|
||||
var operationName = httpContext.Request.GetOperationName();
|
||||
|
||||
var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger);
|
||||
var req = new WebSocketSharpRequest(httpContext, operationName, RequestAttributes.None, _logger, _memoryStreamProvider);
|
||||
req.RequestAttributes = req.GetAttributes();
|
||||
|
||||
return req;
|
||||
|
||||
@@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
using Funq;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using ServiceStack;
|
||||
using ServiceStack.Host;
|
||||
@@ -16,11 +17,13 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
public Container Container { get; set; }
|
||||
private readonly HttpListenerRequest request;
|
||||
private readonly IHttpResponse response;
|
||||
private IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger)
|
||||
public WebSocketSharpRequest(HttpListenerContext httpContext, string operationName, RequestAttributes requestAttributes, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
this.OperationName = operationName;
|
||||
this.RequestAttributes = requestAttributes;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
this.request = httpContext.Request;
|
||||
this.response = new WebSocketSharpResponse(logger, httpContext.Response, this);
|
||||
|
||||
@@ -403,7 +406,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
set
|
||||
{
|
||||
bufferedStream = value
|
||||
? bufferedStream ?? new MemoryStream(request.InputStream.ReadFully())
|
||||
? bufferedStream ?? _memoryStreamProvider.CreateNew(request.InputStream.ReadFully())
|
||||
: null;
|
||||
}
|
||||
}
|
||||
@@ -447,7 +450,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.SocketSharp
|
||||
}
|
||||
}
|
||||
|
||||
static Stream GetSubStream(Stream stream)
|
||||
static Stream GetSubStream(Stream stream, IMemoryStreamProvider streamProvider)
|
||||
{
|
||||
if (stream is MemoryStream)
|
||||
{
|
||||
|
||||
@@ -5,6 +5,7 @@ using System.Collections.Generic;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using ServiceStack;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
@@ -17,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
private ILogger Logger { get; set; }
|
||||
|
||||
private static readonly CultureInfo UsCulture = new CultureInfo("en-US");
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the source stream.
|
||||
/// </summary>
|
||||
@@ -39,6 +40,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
|
||||
public Action OnComplete { get; set; }
|
||||
public Action OnError { get; set; }
|
||||
private readonly byte[] _bytes;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="StreamWriter" /> class.
|
||||
@@ -73,6 +75,17 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
public StreamWriter(byte[] source, string contentType, ILogger logger)
|
||||
: this(new MemoryStream(source), contentType, logger)
|
||||
{
|
||||
if (string.IsNullOrEmpty(contentType))
|
||||
{
|
||||
throw new ArgumentNullException("contentType");
|
||||
}
|
||||
|
||||
_bytes = source;
|
||||
Logger = logger;
|
||||
|
||||
Options["Content-Type"] = contentType;
|
||||
|
||||
Options["Content-Length"] = source.Length.ToString(UsCulture);
|
||||
}
|
||||
|
||||
private const int BufferSize = 81920;
|
||||
@@ -85,9 +98,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var src = SourceStream)
|
||||
if (_bytes != null)
|
||||
{
|
||||
src.CopyTo(responseStream, BufferSize);
|
||||
responseStream.Write(_bytes, 0, _bytes.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var src = SourceStream)
|
||||
{
|
||||
src.CopyTo(responseStream, BufferSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -114,9 +134,16 @@ namespace MediaBrowser.Server.Implementations.HttpServer
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var src = SourceStream)
|
||||
if (_bytes != null)
|
||||
{
|
||||
await src.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false);
|
||||
await responseStream.WriteAsync(_bytes, 0, _bytes.Length);
|
||||
}
|
||||
else
|
||||
{
|
||||
using (var src = SourceStream)
|
||||
{
|
||||
await src.CopyToAsync(responseStream, BufferSize).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
|
||||
@@ -846,7 +846,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.Listings
|
||||
Url = ApiUrl + "/lineups/" + info.ListingsId,
|
||||
UserAgent = UserAgent,
|
||||
CancellationToken = cancellationToken,
|
||||
LogErrorResponseBody = true
|
||||
LogErrorResponseBody = true,
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
httpOptions.RequestHeaders["token"] = token;
|
||||
|
||||
@@ -558,7 +558,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
return item;
|
||||
}
|
||||
|
||||
private async Task<LiveTvProgram> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
||||
private Tuple<LiveTvProgram, bool, bool> GetProgram(ProgramInfo info, Dictionary<Guid, LiveTvProgram> allExistingPrograms, LiveTvChannel channel, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
|
||||
{
|
||||
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
|
||||
|
||||
@@ -671,13 +671,13 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
}
|
||||
}
|
||||
|
||||
var isUpdated = false;
|
||||
if (isNew)
|
||||
{
|
||||
await _libraryManager.CreateItem(item, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
else if (forceUpdate || string.IsNullOrWhiteSpace(info.Etag))
|
||||
{
|
||||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
isUpdated = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -687,13 +687,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
if (!string.Equals(etag, item.ExternalEtag, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
item.ExternalEtag = etag;
|
||||
await _libraryManager.UpdateItem(item, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
isUpdated = true;
|
||||
}
|
||||
}
|
||||
|
||||
_providerManager.QueueRefresh(item.Id, new MetadataRefreshOptions(_fileSystem));
|
||||
|
||||
return item;
|
||||
return new Tuple<LiveTvProgram, bool, bool>(item, isNew, isUpdated);
|
||||
}
|
||||
|
||||
private async Task<Guid> CreateRecordingRecord(RecordingInfo info, string serviceName, Guid parentFolderId, CancellationToken cancellationToken)
|
||||
@@ -1289,9 +1287,22 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
|
||||
}).Cast<LiveTvProgram>().ToDictionary(i => i.Id);
|
||||
|
||||
var newPrograms = new List<LiveTvProgram>();
|
||||
var updatedPrograms = new List<LiveTvProgram>();
|
||||
|
||||
foreach (var program in channelPrograms)
|
||||
{
|
||||
var programItem = await GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false);
|
||||
var programTuple = GetProgram(program, existingPrograms, currentChannel, currentChannel.ChannelType, service.Name, cancellationToken);
|
||||
var programItem = programTuple.Item1;
|
||||
|
||||
if (programTuple.Item2)
|
||||
{
|
||||
newPrograms.Add(programItem);
|
||||
}
|
||||
else if (programTuple.Item3)
|
||||
{
|
||||
updatedPrograms.Add(programItem);
|
||||
}
|
||||
|
||||
programs.Add(programItem.Id);
|
||||
|
||||
@@ -1321,6 +1332,26 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
}
|
||||
}
|
||||
|
||||
if (newPrograms.Count > 0)
|
||||
{
|
||||
await _libraryManager.CreateItems(newPrograms, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
// TODO: Do this in bulk
|
||||
foreach (var program in updatedPrograms)
|
||||
{
|
||||
await _libraryManager.UpdateItem(program, ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
foreach (var program in newPrograms)
|
||||
{
|
||||
_providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions(_fileSystem));
|
||||
}
|
||||
foreach (var program in updatedPrograms)
|
||||
{
|
||||
_providerManager.QueueRefresh(program.Id, new MetadataRefreshOptions(_fileSystem));
|
||||
}
|
||||
|
||||
currentChannel.IsMovie = isMovie;
|
||||
currentChannel.IsNews = isNews;
|
||||
currentChannel.IsSports = isSports;
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Dlna;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
{
|
||||
@@ -138,7 +139,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
|
||||
try
|
||||
{
|
||||
await AddMediaInfo(stream, isAudio, cancellationToken).ConfigureAwait(false);
|
||||
await AddMediaInfoInternal(stream, isAudio, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
@@ -207,6 +208,85 @@ namespace MediaBrowser.Server.Implementations.LiveTv
|
||||
}
|
||||
}
|
||||
|
||||
private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
|
||||
{
|
||||
var originalRuntime = mediaSource.RunTimeTicks;
|
||||
|
||||
var info = await _mediaEncoder.GetMediaInfo(new MediaInfoRequest
|
||||
{
|
||||
InputPath = mediaSource.Path,
|
||||
Protocol = mediaSource.Protocol,
|
||||
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
|
||||
ExtractChapters = false
|
||||
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
mediaSource.Bitrate = info.Bitrate;
|
||||
mediaSource.Container = info.Container;
|
||||
mediaSource.Formats = info.Formats;
|
||||
mediaSource.MediaStreams = info.MediaStreams;
|
||||
mediaSource.RunTimeTicks = info.RunTimeTicks;
|
||||
mediaSource.Size = info.Size;
|
||||
mediaSource.Timestamp = info.Timestamp;
|
||||
mediaSource.Video3DFormat = info.Video3DFormat;
|
||||
mediaSource.VideoType = info.VideoType;
|
||||
|
||||
mediaSource.DefaultSubtitleStreamIndex = null;
|
||||
|
||||
// Null this out so that it will be treated like a live stream
|
||||
if (!originalRuntime.HasValue)
|
||||
{
|
||||
mediaSource.RunTimeTicks = null;
|
||||
}
|
||||
|
||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
|
||||
|
||||
if (audioStream == null || audioStream.Index == -1)
|
||||
{
|
||||
mediaSource.DefaultAudioStreamIndex = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaSource.DefaultAudioStreamIndex = audioStream.Index;
|
||||
}
|
||||
|
||||
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video);
|
||||
if (videoStream != null)
|
||||
{
|
||||
if (!videoStream.BitRate.HasValue)
|
||||
{
|
||||
var width = videoStream.Width ?? 1920;
|
||||
|
||||
if (width >= 1900)
|
||||
{
|
||||
videoStream.BitRate = 8000000;
|
||||
}
|
||||
|
||||
else if (width >= 1260)
|
||||
{
|
||||
videoStream.BitRate = 3000000;
|
||||
}
|
||||
|
||||
else if (width >= 700)
|
||||
{
|
||||
videoStream.BitRate = 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to estimate this
|
||||
if (!mediaSource.Bitrate.HasValue)
|
||||
{
|
||||
var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
|
||||
|
||||
if (total > 0)
|
||||
{
|
||||
mediaSource.Bitrate = total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public Task CloseMediaSource(string liveStreamId)
|
||||
{
|
||||
return _liveTvManager.CloseLiveStream(liveStreamId);
|
||||
|
||||
@@ -252,84 +252,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts
|
||||
//}
|
||||
}
|
||||
|
||||
private async Task AddMediaInfoInternal(MediaSourceInfo mediaSource, bool isAudio, CancellationToken cancellationToken)
|
||||
{
|
||||
var originalRuntime = mediaSource.RunTimeTicks;
|
||||
|
||||
var info = await MediaEncoder.GetMediaInfo(new MediaInfoRequest
|
||||
{
|
||||
InputPath = mediaSource.Path,
|
||||
Protocol = mediaSource.Protocol,
|
||||
MediaType = isAudio ? DlnaProfileType.Audio : DlnaProfileType.Video,
|
||||
ExtractChapters = false
|
||||
|
||||
}, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
mediaSource.Bitrate = info.Bitrate;
|
||||
mediaSource.Container = info.Container;
|
||||
mediaSource.Formats = info.Formats;
|
||||
mediaSource.MediaStreams = info.MediaStreams;
|
||||
mediaSource.RunTimeTicks = info.RunTimeTicks;
|
||||
mediaSource.Size = info.Size;
|
||||
mediaSource.Timestamp = info.Timestamp;
|
||||
mediaSource.Video3DFormat = info.Video3DFormat;
|
||||
mediaSource.VideoType = info.VideoType;
|
||||
|
||||
mediaSource.DefaultSubtitleStreamIndex = null;
|
||||
|
||||
// Null this out so that it will be treated like a live stream
|
||||
if (!originalRuntime.HasValue)
|
||||
{
|
||||
mediaSource.RunTimeTicks = null;
|
||||
}
|
||||
|
||||
var audioStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Audio);
|
||||
|
||||
if (audioStream == null || audioStream.Index == -1)
|
||||
{
|
||||
mediaSource.DefaultAudioStreamIndex = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
mediaSource.DefaultAudioStreamIndex = audioStream.Index;
|
||||
}
|
||||
|
||||
var videoStream = mediaSource.MediaStreams.FirstOrDefault(i => i.Type == Model.Entities.MediaStreamType.Video);
|
||||
if (videoStream != null)
|
||||
{
|
||||
if (!videoStream.BitRate.HasValue)
|
||||
{
|
||||
var width = videoStream.Width ?? 1920;
|
||||
|
||||
if (width >= 1900)
|
||||
{
|
||||
videoStream.BitRate = 8000000;
|
||||
}
|
||||
|
||||
else if (width >= 1260)
|
||||
{
|
||||
videoStream.BitRate = 3000000;
|
||||
}
|
||||
|
||||
else if (width >= 700)
|
||||
{
|
||||
videoStream.BitRate = 1000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Try to estimate this
|
||||
if (!mediaSource.Bitrate.HasValue)
|
||||
{
|
||||
var total = mediaSource.MediaStreams.Select(i => i.BitRate ?? 0).Sum();
|
||||
|
||||
if (total > 0)
|
||||
{
|
||||
mediaSource.Bitrate = total;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected abstract bool IsValidChannelId(string channelId);
|
||||
|
||||
protected LiveTvOptions GetConfiguration()
|
||||
|
||||
@@ -88,7 +88,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = string.Format("{0}/discover.json", url),
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
}))
|
||||
{
|
||||
var response = _json.DeserializeFromStream<HdHomerunHost.DiscoverResponse>(stream);
|
||||
|
||||
@@ -72,7 +72,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
var options = new HttpRequestOptions
|
||||
{
|
||||
Url = string.Format("{0}/lineup.json", GetApiUrl(info, false)),
|
||||
CancellationToken = cancellationToken
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = false
|
||||
};
|
||||
using (var stream = await _httpClient.Get(options))
|
||||
{
|
||||
@@ -124,7 +125,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
CancellationToken = cancellationToken,
|
||||
CacheLength = TimeSpan.FromDays(1),
|
||||
CacheMode = CacheMode.Unconditional,
|
||||
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
|
||||
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
|
||||
BufferContent = false
|
||||
}))
|
||||
{
|
||||
var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
|
||||
@@ -165,7 +167,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
{
|
||||
Url = string.Format("{0}/tuners.html", GetApiUrl(info, false)),
|
||||
CancellationToken = cancellationToken,
|
||||
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds)
|
||||
TimeoutMs = Convert.ToInt32(TimeSpan.FromSeconds(5).TotalMilliseconds),
|
||||
BufferContent = false
|
||||
}))
|
||||
{
|
||||
var tuners = new List<LiveTvTunerInfo>();
|
||||
@@ -538,7 +541,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
using (var stream = await _httpClient.Get(new HttpRequestOptions
|
||||
{
|
||||
Url = string.Format("{0}/discover.json", GetApiUrl(info, false)),
|
||||
CancellationToken = CancellationToken.None
|
||||
CancellationToken = CancellationToken.None,
|
||||
BufferContent = false
|
||||
}))
|
||||
{
|
||||
var response = JsonSerializer.DeserializeFromStream<DiscoverResponse>(stream);
|
||||
|
||||
@@ -12,6 +12,7 @@ using MediaBrowser.Model.Logging;
|
||||
using MediaBrowser.Model.MediaInfo;
|
||||
using MediaBrowser.Server.Implementations.LiveTv.EmbyTV;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
{
|
||||
@@ -139,7 +140,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
private List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>> _additionalStreams = new List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>>();
|
||||
private readonly List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>> _additionalStreams = new List<Tuple<Stream, CancellationToken, TaskCompletionSource<bool>>>();
|
||||
|
||||
public Task CopyToAsync(Stream stream, CancellationToken cancellationToken)
|
||||
{
|
||||
@@ -186,7 +187,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
{
|
||||
await destination.WriteAsync(buffer, 0, bytesRead, cancellationToken).ConfigureAwait(false);
|
||||
|
||||
foreach (var additionalStream in _additionalStreams)
|
||||
var additionalStreams = _additionalStreams.ToList();
|
||||
foreach (var additionalStream in additionalStreams)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -196,6 +198,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv.TunerHosts.HdHomerun
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.ErrorException("Error writing HDHR data to stream", ex);
|
||||
|
||||
PopAdditionalStream(additionalStream, ex);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,8 @@ namespace MediaBrowser.Server.Implementations.News
|
||||
{
|
||||
Url = "http://emby.media/community/index.php?/blog/rss/1-media-browser-developers-blog",
|
||||
Progress = new Progress<double>(),
|
||||
UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36"
|
||||
UserAgent = "Mozilla/5.0 (Windows NT 6.3; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/46.0.2490.42 Safari/537.36",
|
||||
BufferContent = false
|
||||
};
|
||||
|
||||
using (var stream = await _httpClient.Get(requestOptions).ConfigureAwait(false))
|
||||
|
||||
@@ -4,6 +4,7 @@ using MediaBrowser.Model.Serialization;
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.IO;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
@@ -51,18 +52,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
/// <summary>
|
||||
/// Gets a stream from a DataReader at a given ordinal
|
||||
/// </summary>
|
||||
/// <param name="reader">The reader.</param>
|
||||
/// <param name="ordinal">The ordinal.</param>
|
||||
/// <returns>Stream.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">reader</exception>
|
||||
public static Stream GetMemoryStream(this IDataReader reader, int ordinal)
|
||||
public static Stream GetMemoryStream(this IDataReader reader, int ordinal, IMemoryStreamProvider streamProvider)
|
||||
{
|
||||
if (reader == null)
|
||||
{
|
||||
throw new ArgumentNullException("reader");
|
||||
}
|
||||
|
||||
var memoryStream = new MemoryStream();
|
||||
var memoryStream = streamProvider.CreateNew();
|
||||
var num = 0L;
|
||||
var array = new byte[4096];
|
||||
long bytes;
|
||||
@@ -132,18 +131,16 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
/// <summary>
|
||||
/// Serializes to bytes.
|
||||
/// </summary>
|
||||
/// <param name="json">The json.</param>
|
||||
/// <param name="obj">The obj.</param>
|
||||
/// <returns>System.Byte[][].</returns>
|
||||
/// <exception cref="System.ArgumentNullException">obj</exception>
|
||||
public static byte[] SerializeToBytes(this IJsonSerializer json, object obj)
|
||||
public static byte[] SerializeToBytes(this IJsonSerializer json, object obj, IMemoryStreamProvider streamProvider)
|
||||
{
|
||||
if (obj == null)
|
||||
{
|
||||
throw new ArgumentNullException("obj");
|
||||
}
|
||||
|
||||
using (var stream = new MemoryStream())
|
||||
using (var stream = streamProvider.CreateNew())
|
||||
{
|
||||
json.SerializeToStream(obj, stream);
|
||||
return stream.ToArray();
|
||||
|
||||
@@ -10,6 +10,7 @@ using System.Data;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
@@ -18,10 +19,13 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
/// </summary>
|
||||
public class SqliteDisplayPreferencesRepository : BaseSqliteRepository, IDisplayPreferencesRepository
|
||||
{
|
||||
public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector)
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public SqliteDisplayPreferencesRepository(ILogManager logManager, IJsonSerializer jsonSerializer, IApplicationPaths appPaths, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider)
|
||||
: base(logManager, dbConnector)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
DbFilePath = Path.Combine(appPaths.DataPath, "displaypreferences.db");
|
||||
}
|
||||
|
||||
@@ -82,7 +86,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var serialized = _jsonSerializer.SerializeToBytes(displayPreferences);
|
||||
var serialized = _jsonSerializer.SerializeToBytes(displayPreferences, _memoryStreamProvider);
|
||||
|
||||
using (var connection = await CreateConnection().ConfigureAwait(false))
|
||||
{
|
||||
@@ -166,7 +170,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
foreach (var displayPreference in displayPreferences)
|
||||
{
|
||||
|
||||
var serialized = _jsonSerializer.SerializeToBytes(displayPreference);
|
||||
var serialized = _jsonSerializer.SerializeToBytes(displayPreference, _memoryStreamProvider);
|
||||
|
||||
using (var cmd = connection.CreateCommand())
|
||||
{
|
||||
@@ -246,7 +250,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
if (reader.Read())
|
||||
{
|
||||
using (var stream = reader.GetMemoryStream(0))
|
||||
using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
|
||||
{
|
||||
return _jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream);
|
||||
}
|
||||
@@ -283,7 +287,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
while (reader.Read())
|
||||
{
|
||||
using (var stream = reader.GetMemoryStream(0))
|
||||
using (var stream = reader.GetMemoryStream(0, _memoryStreamProvider))
|
||||
{
|
||||
list.Add(_jsonSerializer.DeserializeFromStream<DisplayPreferences>(stream));
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@ using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.IO;
|
||||
using MediaBrowser.Controller.Channels;
|
||||
using MediaBrowser.Controller.Configuration;
|
||||
using MediaBrowser.Controller.Playlists;
|
||||
@@ -95,11 +96,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
private IDbCommand _updateInheritedTagsCommand;
|
||||
|
||||
public const int LatestSchemaVersion = 109;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="SqliteItemRepository"/> class.
|
||||
/// </summary>
|
||||
public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector)
|
||||
public SqliteItemRepository(IServerConfigurationManager config, IJsonSerializer jsonSerializer, ILogManager logManager, IDbConnector connector, IMemoryStreamProvider memoryStreamProvider)
|
||||
: base(logManager, connector)
|
||||
{
|
||||
if (config == null)
|
||||
@@ -113,6 +115,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
|
||||
_config = config;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
|
||||
_criticReviewsPath = Path.Combine(_config.ApplicationPaths.DataPath, "critic-reviews");
|
||||
DbFilePath = Path.Combine(_config.ApplicationPaths.DataPath, "library.db");
|
||||
@@ -724,7 +727,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
|
||||
_saveItemCommand.GetParameter(index++).Value = item.Id;
|
||||
_saveItemCommand.GetParameter(index++).Value = item.GetType().FullName;
|
||||
_saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item);
|
||||
_saveItemCommand.GetParameter(index++).Value = _jsonSerializer.SerializeToBytes(item, _memoryStreamProvider);
|
||||
|
||||
_saveItemCommand.GetParameter(index++).Value = item.Path;
|
||||
|
||||
@@ -1075,7 +1078,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
|
||||
BaseItem item = null;
|
||||
|
||||
using (var stream = reader.GetMemoryStream(1))
|
||||
using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Data;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
@@ -18,10 +19,12 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
public class SqliteUserRepository : BaseSqliteRepository, IUserRepository
|
||||
{
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector) : base(logManager, dbConnector)
|
||||
public SqliteUserRepository(ILogManager logManager, IServerApplicationPaths appPaths, IJsonSerializer jsonSerializer, IDbConnector dbConnector, IMemoryStreamProvider memoryStreamProvider) : base(logManager, dbConnector)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
|
||||
DbFilePath = Path.Combine(appPaths.DataPath, "users.db");
|
||||
}
|
||||
@@ -75,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
var serialized = _jsonSerializer.SerializeToBytes(user);
|
||||
var serialized = _jsonSerializer.SerializeToBytes(user, _memoryStreamProvider);
|
||||
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.Persistence
|
||||
{
|
||||
var id = reader.GetGuid(0);
|
||||
|
||||
using (var stream = reader.GetMemoryStream(1))
|
||||
using (var stream = reader.GetMemoryStream(1, _memoryStreamProvider))
|
||||
{
|
||||
var user = _jsonSerializer.DeserializeFromStream<User>(stream);
|
||||
user.Id = id;
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace MediaBrowser.Server.Implementations.Playlists
|
||||
|
||||
public override bool IsVisible(User user)
|
||||
{
|
||||
return base.IsVisible(user) && GetChildren(user, false).Any();
|
||||
return base.IsVisible(user);
|
||||
}
|
||||
|
||||
protected override IEnumerable<BaseItem> GetEligibleChildrenForRecursiveChildren(User user)
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Linq;
|
||||
using System.Net.Sockets;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
{
|
||||
@@ -72,6 +73,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
private readonly List<IWebSocketListener> _webSocketListeners = new List<IWebSocketListener>();
|
||||
|
||||
private bool _disposed;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ServerManager" /> class.
|
||||
@@ -81,7 +83,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="configurationManager">The configuration manager.</param>
|
||||
/// <exception cref="System.ArgumentNullException">applicationHost</exception>
|
||||
public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager)
|
||||
public ServerManager(IServerApplicationHost applicationHost, IJsonSerializer jsonSerializer, ILogger logger, IServerConfigurationManager configurationManager, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
if (applicationHost == null)
|
||||
{
|
||||
@@ -100,6 +102,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_applicationHost = applicationHost;
|
||||
ConfigurationManager = configurationManager;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -150,7 +153,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
return;
|
||||
}
|
||||
|
||||
var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger)
|
||||
var connection = new WebSocketConnection(e.WebSocket, e.Endpoint, _jsonSerializer, _logger, _memoryStreamProvider)
|
||||
{
|
||||
OnReceive = ProcessWebSocketMessageReceived,
|
||||
Url = e.Url,
|
||||
|
||||
@@ -9,6 +9,7 @@ using System.Collections.Specialized;
|
||||
using System.IO;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Common.IO;
|
||||
using UniversalDetector;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
@@ -78,7 +79,8 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// </summary>
|
||||
/// <value>The query string.</value>
|
||||
public NameValueCollection QueryString { get; set; }
|
||||
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WebSocketConnection" /> class.
|
||||
/// </summary>
|
||||
@@ -87,7 +89,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
/// <param name="jsonSerializer">The json serializer.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <exception cref="System.ArgumentNullException">socket</exception>
|
||||
public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger)
|
||||
public WebSocketConnection(IWebSocket socket, string remoteEndPoint, IJsonSerializer jsonSerializer, ILogger logger, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
if (socket == null)
|
||||
{
|
||||
@@ -113,6 +115,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
_socket.OnReceive = OnReceiveInternal;
|
||||
RemoteEndPoint = remoteEndPoint;
|
||||
_logger = logger;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
|
||||
socket.Closed += socket_Closed;
|
||||
}
|
||||
@@ -149,7 +152,7 @@ namespace MediaBrowser.Server.Implementations.ServerManager
|
||||
{
|
||||
try
|
||||
{
|
||||
using (var ms = new MemoryStream(bytes))
|
||||
using (var ms = _memoryStreamProvider.CreateNew(bytes))
|
||||
{
|
||||
var detector = new CharsetDetector();
|
||||
detector.Feed(ms);
|
||||
|
||||
@@ -75,7 +75,8 @@ namespace MediaBrowser.Server.Implementations.Session
|
||||
await _httpClient.Post(new HttpRequestOptions
|
||||
{
|
||||
Url = url,
|
||||
CancellationToken = cancellationToken
|
||||
CancellationToken = cancellationToken,
|
||||
BufferContent = false
|
||||
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -30,6 +30,7 @@ using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sync
|
||||
{
|
||||
@@ -51,6 +52,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
private readonly Func<IMediaSourceManager> _mediaSourceManager;
|
||||
private readonly IJsonSerializer _json;
|
||||
private readonly ITaskManager _taskManager;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
private ISyncProvider[] _providers = { };
|
||||
|
||||
@@ -60,7 +62,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemUpdated;
|
||||
public event EventHandler<GenericEventArgs<SyncJobItem>> SyncJobItemCreated;
|
||||
|
||||
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager)
|
||||
public SyncManager(ILibraryManager libraryManager, ISyncRepository repo, IImageProcessor imageProcessor, ILogger logger, IUserManager userManager, Func<IDtoService> dtoService, IServerApplicationHost appHost, ITVSeriesManager tvSeriesManager, Func<IMediaEncoder> mediaEncoder, IFileSystem fileSystem, Func<ISubtitleEncoder> subtitleEncoder, IConfigurationManager config, IUserDataManager userDataManager, Func<IMediaSourceManager> mediaSourceManager, IJsonSerializer json, ITaskManager taskManager, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
_libraryManager = libraryManager;
|
||||
_repo = repo;
|
||||
@@ -78,6 +80,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
_mediaSourceManager = mediaSourceManager;
|
||||
_json = json;
|
||||
_taskManager = taskManager;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
}
|
||||
|
||||
public void AddParts(IEnumerable<ISyncProvider> providers)
|
||||
@@ -95,7 +98,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
|
||||
public ISyncDataProvider GetDataProvider(IServerSyncProvider provider, SyncTarget target)
|
||||
{
|
||||
return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost, _logger, _json, _fileSystem, _config.CommonApplicationPaths));
|
||||
return _dataProviders.GetOrAdd(target.Id, key => new TargetDataProvider(provider, target, _appHost, _logger, _json, _fileSystem, _config.CommonApplicationPaths, _memoryStreamProvider));
|
||||
}
|
||||
|
||||
public async Task<SyncJobCreationResult> CreateJob(SyncJobRequest request)
|
||||
|
||||
@@ -12,6 +12,7 @@ using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using CommonIO;
|
||||
using Interfaces.IO;
|
||||
using MediaBrowser.Common.IO;
|
||||
|
||||
namespace MediaBrowser.Server.Implementations.Sync
|
||||
{
|
||||
@@ -28,8 +29,9 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
private readonly IFileSystem _fileSystem;
|
||||
private readonly IApplicationPaths _appPaths;
|
||||
private readonly IServerApplicationHost _appHost;
|
||||
private readonly IMemoryStreamProvider _memoryStreamProvider;
|
||||
|
||||
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths)
|
||||
public TargetDataProvider(IServerSyncProvider provider, SyncTarget target, IServerApplicationHost appHost, ILogger logger, IJsonSerializer json, IFileSystem fileSystem, IApplicationPaths appPaths, IMemoryStreamProvider memoryStreamProvider)
|
||||
{
|
||||
_logger = logger;
|
||||
_json = json;
|
||||
@@ -37,6 +39,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
_target = target;
|
||||
_fileSystem = fileSystem;
|
||||
_appPaths = appPaths;
|
||||
_memoryStreamProvider = memoryStreamProvider;
|
||||
_appHost = appHost;
|
||||
}
|
||||
|
||||
@@ -90,7 +93,7 @@ namespace MediaBrowser.Server.Implementations.Sync
|
||||
|
||||
private async Task SaveData(List<LocalItem> items, CancellationToken cancellationToken)
|
||||
{
|
||||
using (var stream = new MemoryStream())
|
||||
using (var stream = _memoryStreamProvider.CreateNew())
|
||||
{
|
||||
_json.SerializeToStream(items, stream);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user