Merge pull request #2548 from MediaBrowser/dev

Dev
This commit is contained in:
Luke 2017-03-26 20:28:04 -04:00 committed by GitHub
commit 1d6a27c38d
4 changed files with 163 additions and 65 deletions

View File

@ -49,7 +49,7 @@ namespace Emby.Common.Implementations.Net
private void InitReceiveSocketAsyncEventArgs()
{
var receiveBuffer = new byte[8192];
var receiveBuffer = new byte[81920];
_receiveSocketAsyncEventArgs.SetBuffer(receiveBuffer, 0, receiveBuffer.Length);
_receiveSocketAsyncEventArgs.Completed += _receiveSocketAsyncEventArgs_Completed;
@ -119,20 +119,29 @@ namespace Emby.Common.Implementations.Net
public Task<SocketReceiveResult> ReceiveAsync(CancellationToken cancellationToken)
{
ThrowIfDisposed();
var tcs = new TaskCompletionSource<SocketReceiveResult>();
EndPoint receivedFromEndPoint = new IPEndPoint(IPAddress.Any, 0);
var state = new AsyncReceiveState(_Socket, receivedFromEndPoint);
state.TaskCompletionSource = tcs;
cancellationToken.Register(() => tcs.TrySetCanceled());
_receiveSocketAsyncEventArgs.RemoteEndPoint = receivedFromEndPoint;
_currentReceiveTaskCompletionSource = tcs;
var willRaiseEvent = _Socket.ReceiveFromAsync(_receiveSocketAsyncEventArgs);
if (!willRaiseEvent)
try
{
_receiveSocketAsyncEventArgs_Completed(this, _receiveSocketAsyncEventArgs);
var willRaiseEvent = _Socket.ReceiveFromAsync(_receiveSocketAsyncEventArgs);
if (!willRaiseEvent)
{
_receiveSocketAsyncEventArgs_Completed(this, _receiveSocketAsyncEventArgs);
}
}
catch (Exception ex)
{
tcs.TrySetException(ex);
}
return tcs.Task;
@ -145,31 +154,82 @@ namespace Emby.Common.Implementations.Net
if (buffer == null) throw new ArgumentNullException("messageData");
if (endPoint == null) throw new ArgumentNullException("endPoint");
cancellationToken.ThrowIfCancellationRequested();
var ipEndPoint = NetworkManager.ToIPEndPoint(endPoint);
var tcs = new TaskCompletionSource<int>();
#if NETSTANDARD1_6
cancellationToken.Register(() => tcs.TrySetCanceled());
_sendSocketAsyncEventArgs.SetBuffer(buffer, 0, size);
_sendSocketAsyncEventArgs.RemoteEndPoint = NetworkManager.ToIPEndPoint(endPoint);
_currentSendTaskCompletionSource = tcs;
var willRaiseEvent = _Socket.SendAsync(_sendSocketAsyncEventArgs);
if (!willRaiseEvent)
if (size != buffer.Length)
{
_sendSocketAsyncEventArgs_Completed(this, _sendSocketAsyncEventArgs);
byte[] copy = new byte[size];
Buffer.BlockCopy(buffer, 0, copy, 0, size);
buffer = copy;
}
return tcs.Task;
cancellationToken.ThrowIfCancellationRequested();
_Socket.SendTo(buffer, ipEndPoint);
return Task.FromResult(true);
#else
var taskSource = new TaskCompletionSource<bool>();
try
{
_Socket.BeginSendTo(buffer, 0, size, SocketFlags.None, ipEndPoint, result =>
{
if (cancellationToken.IsCancellationRequested)
{
taskSource.TrySetCanceled();
return;
}
try
{
_Socket.EndSend(result);
taskSource.TrySetResult(true);
}
catch (Exception ex)
{
taskSource.TrySetException(ex);
}
}, null);
}
catch (Exception ex)
{
taskSource.TrySetException(ex);
}
return taskSource.Task;
#endif
//ThrowIfDisposed();
//if (buffer == null) throw new ArgumentNullException("messageData");
//if (endPoint == null) throw new ArgumentNullException("endPoint");
//cancellationToken.ThrowIfCancellationRequested();
//var tcs = new TaskCompletionSource<int>();
//cancellationToken.Register(() => tcs.TrySetCanceled());
//_sendSocketAsyncEventArgs.SetBuffer(buffer, 0, size);
//_sendSocketAsyncEventArgs.RemoteEndPoint = NetworkManager.ToIPEndPoint(endPoint);
//_currentSendTaskCompletionSource = tcs;
//var willRaiseEvent = _Socket.SendAsync(_sendSocketAsyncEventArgs);
//if (!willRaiseEvent)
//{
// _sendSocketAsyncEventArgs_Completed(this, _sendSocketAsyncEventArgs);
//}
//return tcs.Task;
}
public async Task SendWithLockAsync(byte[] buffer, int size, IpEndPointInfo endPoint, CancellationToken cancellationToken)
{
ThrowIfDisposed();
await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false);
//await _sendLock.WaitAsync(cancellationToken).ConfigureAwait(false);
try
{
@ -177,7 +237,7 @@ namespace Emby.Common.Implementations.Net
}
finally
{
_sendLock.Release();
//_sendLock.Release();
}
}
@ -213,5 +273,52 @@ namespace Emby.Common.Implementations.Net
return NetworkManager.ToIpEndPointInfo(endpoint);
}
private void ProcessResponse(IAsyncResult asyncResult)
{
#if NET46
var state = asyncResult.AsyncState as AsyncReceiveState;
try
{
var bytesRead = state.Socket.EndReceiveFrom(asyncResult, ref state.RemoteEndPoint);
var ipEndPoint = state.RemoteEndPoint as IPEndPoint;
state.TaskCompletionSource.SetResult(
new SocketReceiveResult
{
Buffer = state.Buffer,
ReceivedBytes = bytesRead,
RemoteEndPoint = ToIpEndPointInfo(ipEndPoint),
LocalIPAddress = LocalIPAddress
}
);
}
catch (ObjectDisposedException)
{
state.TaskCompletionSource.SetCanceled();
}
catch (Exception ex)
{
state.TaskCompletionSource.SetException(ex);
}
#endif
}
private class AsyncReceiveState
{
public AsyncReceiveState(Socket socket, EndPoint remoteEndPoint)
{
this.Socket = socket;
this.RemoteEndPoint = remoteEndPoint;
}
public EndPoint RemoteEndPoint;
public byte[] Buffer = new byte[8192];
public Socket Socket { get; private set; }
public TaskCompletionSource<SocketReceiveResult> TaskCompletionSource { get; set; }
}
}
}

View File

@ -677,20 +677,7 @@ namespace Emby.Server.Implementations.FileOrganization
var newPath = GetSeasonFolderPath(series, seasonNumber.Value, options);
// MAX_PATH - trailing <NULL> charachter - drive component: 260 - 1 - 3 = 256
// Usually newPath would include the drive component, but use 256 to be sure
var maxFilenameLength = 256 - newPath.Length;
if (!newPath.EndsWith(@"\"))
{
// Remove 1 for missing backslash combining path and filename
maxFilenameLength--;
}
// Remove additional 4 chars to prevent PathTooLongException for downloaded subtitles (eg. filename.ext.eng.srt)
maxFilenameLength -= 4;
var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options, maxFilenameLength);
var episodeFileName = GetEpisodeFileName(sourcePath, series.Name, seasonNumber.Value, episodeNumber.Value, endingEpisodeNumber, episodeName, options);
if (string.IsNullOrEmpty(episodeFileName))
{
@ -742,7 +729,7 @@ namespace Emby.Server.Implementations.FileOrganization
return Path.Combine(path, _fileSystem.GetValidFilename(seasonFolderName));
}
private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options, int? maxLength)
private string GetEpisodeFileName(string sourcePath, string seriesName, int seasonNumber, int episodeNumber, int? endingEpisodeNumber, string episodeTitle, TvFileOrganizationOptions options)
{
seriesName = _fileSystem.GetValidFilename(seriesName).Trim();
@ -786,32 +773,15 @@ namespace Emby.Server.Implementations.FileOrganization
.Replace("%0e", episodeNumber.ToString("00", _usCulture))
.Replace("%00e", episodeNumber.ToString("000", _usCulture));
if (maxLength.HasValue && result.Contains("%#"))
if (result.Contains("%#"))
{
// Substract 3 for the temp token length (%#1, %#2 or %#3)
int maxRemainingTitleLength = maxLength.Value - result.Length + 3;
string shortenedEpisodeTitle = string.Empty;
if (maxRemainingTitleLength > 5)
{
// A title with fewer than 5 letters wouldn't be of much value
shortenedEpisodeTitle = episodeTitle.Substring(0, Math.Min(maxRemainingTitleLength, episodeTitle.Length));
}
result = result.Replace("%#1", shortenedEpisodeTitle)
.Replace("%#2", shortenedEpisodeTitle.Replace(" ", "."))
.Replace("%#3", shortenedEpisodeTitle.Replace(" ", "_"));
result = result.Replace("%#1", episodeTitle)
.Replace("%#2", episodeTitle.Replace(" ", "."))
.Replace("%#3", episodeTitle.Replace(" ", "_"));
}
if (maxLength.HasValue && result.Length > maxLength.Value)
{
// There may be cases where reducing the title length may still not be sufficient to
// stay below maxLength
var msg = string.Format("Unable to generate an episode file name shorter than {0} characters to constrain to the max path limit", maxLength);
throw new Exception(msg);
}
return result;
// Finally, call GetValidFilename again in case user customized the episode expression with any invalid filename characters
return _fileSystem.GetValidFilename(result).Trim();
}
private bool IsSameEpisode(string sourcePath, string newPath)

View File

@ -20,6 +20,7 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.MediaEncoding;
using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Net;
using MediaBrowser.Model.System;
namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
@ -30,8 +31,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
private readonly IServerApplicationHost _appHost;
private readonly ISocketFactory _socketFactory;
private readonly INetworkManager _networkManager;
private readonly IEnvironmentInfo _environment;
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager)
public HdHomerunHost(IServerConfigurationManager config, ILogger logger, IJsonSerializer jsonSerializer, IMediaEncoder mediaEncoder, IHttpClient httpClient, IFileSystem fileSystem, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment)
: base(config, logger, jsonSerializer, mediaEncoder)
{
_httpClient = httpClient;
@ -39,6 +41,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
_appHost = appHost;
_socketFactory = socketFactory;
_networkManager = networkManager;
_environment = environment;
}
public string Name
@ -503,11 +506,29 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
{
return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Url), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
}
else
// The UDP method is not working reliably on OSX, and on BSD it hasn't been tested yet
var enableHttpStream = _environment.OperatingSystem == OperatingSystem.OSX ||
_environment.OperatingSystem == OperatingSystem.BSD;
if (enableHttpStream)
{
//return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
mediaSource.Protocol = MediaProtocol.Http;
var httpUrl = GetApiUrl(info, true) + "/auto/v" + hdhrId;
// If raw was used, the tuner doesn't support params
if (!string.IsNullOrWhiteSpace(profile)
&& !string.Equals(profile, "native", StringComparison.OrdinalIgnoreCase))
{
httpUrl += "?transcode=" + profile;
}
mediaSource.Path = httpUrl;
return new HdHomerunHttpStream(mediaSource, streamId, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost);
}
return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number), modelInfo.TunerCount, _fileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager);
}
public async Task Validate(TunerHostInfo info)

View File

@ -1,3 +1,3 @@
using System.Reflection;
[assembly: AssemblyVersion("3.2.8.14")]
[assembly: AssemblyVersion("3.2.8.15")]