Bladeren bron

Merge pull request #2548 from MediaBrowser/dev

Dev
Luke 8 jaren geleden
bovenliggende
commit
1d6a27c38d

+ 125 - 18
Emby.Common.Implementations/Net/UdpSocket.cs

@@ -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);
+            try
+            {
+                var willRaiseEvent = _Socket.ReceiveFromAsync(_receiveSocketAsyncEventArgs);
 
-            if (!willRaiseEvent)
+                if (!willRaiseEvent)
+                {
+                    _receiveSocketAsyncEventArgs_Completed(this, _receiveSocketAsyncEventArgs);
+                }
+            }
+            catch (Exception ex)
             {
-                _receiveSocketAsyncEventArgs_Completed(this, _receiveSocketAsyncEventArgs);
+                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());
+            if (size != buffer.Length)
+            {
+                byte[] copy = new byte[size];
+                Buffer.BlockCopy(buffer, 0, copy, 0, size);
+                buffer = copy;
+            }
 
-            _sendSocketAsyncEventArgs.SetBuffer(buffer, 0, size);
-            _sendSocketAsyncEventArgs.RemoteEndPoint = NetworkManager.ToIPEndPoint(endPoint);
-            _currentSendTaskCompletionSource = tcs;
+            cancellationToken.ThrowIfCancellationRequested();
 
-            var willRaiseEvent = _Socket.SendAsync(_sendSocketAsyncEventArgs);
+            _Socket.SendTo(buffer, ipEndPoint);
+            return Task.FromResult(true);
+#else
+            var taskSource = new TaskCompletionSource<bool>();
 
-            if (!willRaiseEvent)
+            try
             {
-                _sendSocketAsyncEventArgs_Completed(this, _sendSocketAsyncEventArgs);
+                _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 tcs.Task;
+            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; }
+
+        }
     }
 }

+ 8 - 38
Emby.Server.Implementations/FileOrganization/EpisodeFileOrganizer.cs

@@ -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("%#"))
-            {
-                // 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(" ", "_"));
-            }
-
-            if (maxLength.HasValue && result.Length > maxLength.Value)
+            if (result.Contains("%#"))
             {
-                // 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);
+                result = result.Replace("%#1", episodeTitle)
+                    .Replace("%#2", episodeTitle.Replace(" ", "."))
+                    .Replace("%#3", episodeTitle.Replace(" ", "_"));
             }
 
-            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)

+ 25 - 4
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunHost.cs

@@ -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)

+ 1 - 1
SharedVersion.cs

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