Browse Source

Merge pull request #3022 from MediaBrowser/dev

Dev
Luke 7 years ago
parent
commit
fd5059147d

+ 20 - 4
Emby.Server.Implementations/LiveTv/EmbyTV/EmbyTV.cs

@@ -1052,10 +1052,27 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
             {
                 _liveStreamsSemaphore.Release();
             }
+        }
+
+        public async Task<List<ILiveStream>> GetLiveStreams(TunerHostInfo host, CancellationToken cancellationToken)
+        {
+            //await _liveStreamsSemaphore.WaitAsync(cancellationToken).ConfigureAwait(false);
+
+            //try
+            //{
+            var hostId = host.Id;
 
+            return _liveStreams
+                .Where(i => string.Equals(i.TunerHostId, hostId, StringComparison.OrdinalIgnoreCase))
+                .ToList();
+            //}
+            //finally
+            //{
+            //    _liveStreamsSemaphore.Release();
+            //}
         }
 
-        private async Task<Tuple<ILiveStream, MediaSourceInfo, ITunerHost>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken)
+        private async Task<Tuple<ILiveStream, MediaSourceInfo>> GetChannelStreamInternal(string channelId, string streamId, CancellationToken cancellationToken)
         {
             _logger.Info("Streaming Channel " + channelId);
 
@@ -1072,7 +1089,7 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
 
                     _logger.Info("Live stream {0} consumer count is now {1}", streamId, result.ConsumerCount);
 
-                    return new Tuple<ILiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, result.TunerHost);
+                    return new Tuple<ILiveStream, MediaSourceInfo>(result, openedMediaSource);
                 }
 
                 foreach (var hostInstance in _liveTvManager.TunerHosts)
@@ -1086,13 +1103,12 @@ namespace Emby.Server.Implementations.LiveTv.EmbyTV
                         result.SharedStreamIds.Add(openedMediaSource.Id);
                         _liveStreams.Add(result);
 
-                        result.TunerHost = hostInstance;
                         result.OriginalStreamId = streamId;
 
                         _logger.Info("Returning mediasource streamId {0}, mediaSource.Id {1}, mediaSource.LiveStreamId {2}",
                             streamId, openedMediaSource.Id, openedMediaSource.LiveStreamId);
 
-                        return new Tuple<ILiveStream, MediaSourceInfo, ITunerHost>(result, openedMediaSource, hostInstance);
+                        return new Tuple<ILiveStream, MediaSourceInfo>(result, openedMediaSource);
                     }
                     catch (FileNotFoundException)
                     {

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

@@ -598,7 +598,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 
             if (hdhomerunChannel != null && hdhomerunChannel.IsLegacyTuner)
             {
-                return new HdHomerunUdpStream(mediaSource, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
+                return new HdHomerunUdpStream(mediaSource, info, streamId, new LegacyHdHomerunChannelCommands(hdhomerunChannel.Path), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
             }
 
             // The UDP method is not working reliably on OSX, and on BSD it hasn't been tested yet
@@ -618,10 +618,10 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
                 }
                 mediaSource.Path = httpUrl;
 
-                return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+                return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
             }
 
-            return new HdHomerunUdpStream(mediaSource, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
+            return new HdHomerunUdpStream(mediaSource, info, streamId, new HdHomerunChannelCommands(hdhomerunChannel.Number, profile), modelInfo.TunerCount, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _socketFactory, _networkManager, _environment);
         }
 
         public async Task Validate(TunerHostInfo info)

+ 3 - 2
Emby.Server.Implementations/LiveTv/TunerHosts/HdHomerun/HdHomerunUdpStream.cs

@@ -11,6 +11,7 @@ using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.Net;
 using MediaBrowser.Model.System;
+using MediaBrowser.Model.LiveTv;
 
 namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
 {
@@ -23,8 +24,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts.HdHomerun
         private readonly int _numTuners;
         private readonly INetworkManager _networkManager;
 
-        public HdHomerunUdpStream(MediaSourceInfo mediaSource, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment)
-            : base(mediaSource, environment, fileSystem, logger, appPaths)
+        public HdHomerunUdpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IHdHomerunChannelCommands channelCommands, int numTuners, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, ISocketFactory socketFactory, INetworkManager networkManager, IEnvironmentInfo environment)
+            : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths)
         {
             _appHost = appHost;
             _socketFactory = socketFactory;

+ 6 - 2
Emby.Server.Implementations/LiveTv/TunerHosts/LiveStream.cs

@@ -10,6 +10,7 @@ using MediaBrowser.Model.Dto;
 using MediaBrowser.Model.IO;
 using MediaBrowser.Model.Logging;
 using MediaBrowser.Model.System;
+using MediaBrowser.Model.LiveTv;
 
 namespace Emby.Server.Implementations.LiveTv.TunerHosts
 {
@@ -21,7 +22,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
         {
             get { return SharedStreamIds.Count; }
         }
-        public ITunerHost TunerHost { get; set; }
+
         public string OriginalStreamId { get; set; }
         public bool EnableStreamSharing { get; set; }
         public string UniqueId { get; private set; }
@@ -35,7 +36,9 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
         protected readonly ILogger Logger;
         protected readonly CancellationTokenSource LiveStreamCancellationTokenSource = new CancellationTokenSource();
 
-        public LiveStream(MediaSourceInfo mediaSource, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths)
+        public string TunerHostId { get; private set; }
+
+        public LiveStream(MediaSourceInfo mediaSource, TunerHostInfo tuner, IEnvironmentInfo environment, IFileSystem fileSystem, ILogger logger, IServerApplicationPaths appPaths)
         {
             OriginalMediaSource = mediaSource;
             Environment = environment;
@@ -45,6 +48,7 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
             EnableStreamSharing = true;
             SharedStreamIds = new List<string>();
             UniqueId = Guid.NewGuid().ToString("N");
+            TunerHostId = tuner.Id;
 
             AppPaths = appPaths;
 

+ 14 - 2
Emby.Server.Implementations/LiveTv/TunerHosts/M3UTunerHost.cs

@@ -77,16 +77,28 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
 
         protected override async Task<ILiveStream> GetChannelStream(TunerHostInfo info, string channelId, string streamId, CancellationToken cancellationToken)
         {
+            var tunerCount = info.TunerCount;
+
+            if (tunerCount > 0)
+            {
+                var liveStreams = await EmbyTV.EmbyTV.Current.GetLiveStreams(info, cancellationToken).ConfigureAwait(false);
+
+                if (liveStreams.Count >= info.TunerCount)
+                {
+                    throw new LiveTvConflictException();
+                }
+            }
+
             var sources = await GetChannelStreamMediaSources(info, channelId, cancellationToken).ConfigureAwait(false);
 
             var mediaSource = sources.First();
 
             if (mediaSource.Protocol == MediaProtocol.Http && !mediaSource.RequiresLooping)
             {
-                return new SharedHttpStream(mediaSource, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
+                return new SharedHttpStream(mediaSource, info, streamId, FileSystem, _httpClient, Logger, Config.ApplicationPaths, _appHost, _environment);
             }
 
-            return new LiveStream(mediaSource, _environment, FileSystem, Logger, Config.ApplicationPaths);
+            return new LiveStream(mediaSource, info, _environment, FileSystem, Logger, Config.ApplicationPaths);
         }
 
         public async Task Validate(TunerHostInfo info)

+ 3 - 2
Emby.Server.Implementations/LiveTv/TunerHosts/SharedHttpStream.cs

@@ -14,6 +14,7 @@ using MediaBrowser.Model.MediaInfo;
 using MediaBrowser.Model.System;
 using System.Globalization;
 using MediaBrowser.Controller.IO;
+using MediaBrowser.Model.LiveTv;
 
 namespace Emby.Server.Implementations.LiveTv.TunerHosts
 {
@@ -22,8 +23,8 @@ namespace Emby.Server.Implementations.LiveTv.TunerHosts
         private readonly IHttpClient _httpClient;
         private readonly IServerApplicationHost _appHost;
 
-        public SharedHttpStream(MediaSourceInfo mediaSource, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
-            : base(mediaSource, environment, fileSystem, logger, appPaths)
+        public SharedHttpStream(MediaSourceInfo mediaSource, TunerHostInfo tunerHostInfo, string originalStreamId, IFileSystem fileSystem, IHttpClient httpClient, ILogger logger, IServerApplicationPaths appPaths, IServerApplicationHost appHost, IEnvironmentInfo environment)
+            : base(mediaSource, tunerHostInfo, environment, fileSystem, logger, appPaths)
         {
             _httpClient = httpClient;
             _appHost = appHost;

+ 4 - 2
MediaBrowser.Api/VideosService.cs

@@ -114,12 +114,14 @@ namespace MediaBrowser.Api
 
             foreach (var link in video.GetLinkedAlternateVersions())
             {
-                link.PrimaryVersionId = null;
+                link.SetPrimaryVersionId(null);
+                link.LinkedAlternateVersions = Video.EmptyLinkedChildArray;
 
                 link.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
             }
 
             video.LinkedAlternateVersions = Video.EmptyLinkedChildArray;
+            video.SetPrimaryVersionId(null);
             video.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
         }
 
@@ -174,7 +176,7 @@ namespace MediaBrowser.Api
 
             foreach (var item in items.Where(i => i.Id != primaryVersion.Id))
             {
-                item.PrimaryVersionId = primaryVersion.Id.ToString("N");
+                item.SetPrimaryVersionId(primaryVersion.Id.ToString("N"));
 
                 item.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None);
 

+ 27 - 51
MediaBrowser.Controller/Entities/Video.cs

@@ -84,6 +84,20 @@ namespace MediaBrowser.Controller.Entities
             }
         }
 
+        public void SetPrimaryVersionId(string id)
+        {
+            if (string.IsNullOrWhiteSpace(id))
+            {
+                PrimaryVersionId = null;
+            }
+            else
+            {
+                PrimaryVersionId = id;
+            }
+
+            PresentationUniqueKey = CreatePresentationUniqueKey();
+        }
+
         public override string CreatePresentationUniqueKey()
         {
             if (!string.IsNullOrWhiteSpace(PrimaryVersionId))
@@ -667,8 +681,6 @@ namespace MediaBrowser.Controller.Entities
                 throw new ArgumentNullException("media");
             }
 
-            var mediaStreams = MediaSourceManager.GetMediaStreams(media.Id);
-
             var locationType = media.LocationType;
 
             var info = new MediaSourceInfo
@@ -676,8 +688,8 @@ namespace MediaBrowser.Controller.Entities
                 Id = media.Id.ToString("N"),
                 IsoType = media.IsoType,
                 Protocol = locationType == LocationType.Remote ? MediaProtocol.Http : MediaProtocol.File,
-                MediaStreams = mediaStreams,
-                Name = GetMediaSourceName(media, mediaStreams),
+                MediaStreams = MediaSourceManager.GetMediaStreams(media.Id),
+                Name = GetMediaSourceName(media),
                 Path = enablePathSubstitution ? GetMappedPath(media, media.Path, locationType) : media.Path,
                 RunTimeTicks = media.RunTimeTicks,
                 Video3DFormat = media.Video3DFormat,
@@ -740,12 +752,20 @@ namespace MediaBrowser.Controller.Entities
             return info;
         }
 
-        private static string GetMediaSourceName(Video video, List<MediaStream> mediaStreams)
+        private static string GetMediaSourceName(Video video)
         {
             var terms = new List<string>();
 
-            var videoStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Video);
-            var audioStream = mediaStreams.FirstOrDefault(i => i.Type == MediaStreamType.Audio);
+            var locationType = video.LocationType;
+            var path = video.Path;
+            if ((locationType == LocationType.FileSystem || locationType == LocationType.Offline) && !string.IsNullOrWhiteSpace(path))
+            {
+                terms.Add(System.IO.Path.GetFileName(path));
+            }
+            else
+            {
+                terms.Add(video.Name);
+            }
 
             if (video.Video3DFormat.HasValue)
             {
@@ -779,50 +799,6 @@ namespace MediaBrowser.Controller.Entities
                 }
             }
 
-            if (videoStream != null)
-            {
-                if (videoStream.Width.HasValue)
-                {
-                    if (videoStream.Width.Value >= 3800)
-                    {
-                        terms.Add("4K");
-                    }
-                    else if (videoStream.Width.Value >= 1900)
-                    {
-                        terms.Add("1080P");
-                    }
-                    else if (videoStream.Width.Value >= 1270)
-                    {
-                        terms.Add("720P");
-                    }
-                    else if (videoStream.Width.Value >= 700)
-                    {
-                        terms.Add("480P");
-                    }
-                    else
-                    {
-                        terms.Add("SD");
-                    }
-                }
-            }
-
-            if (videoStream != null && !string.IsNullOrWhiteSpace(videoStream.Codec))
-            {
-                terms.Add(videoStream.Codec.ToUpper());
-            }
-
-            if (audioStream != null)
-            {
-                var audioCodec = string.Equals(audioStream.Codec, "dca", StringComparison.OrdinalIgnoreCase)
-                    ? audioStream.Profile
-                    : audioStream.Codec;
-
-                if (!string.IsNullOrEmpty(audioCodec))
-                {
-                    terms.Add(audioCodec.ToUpper());
-                }
-            }
-
             return string.Join("/", terms.ToArray(terms.Count));
         }
 

+ 1 - 1
MediaBrowser.Controller/LiveTv/ITunerHost.cs

@@ -63,8 +63,8 @@ namespace MediaBrowser.Controller.LiveTv
         void Close();
         int ConsumerCount { get; }
         string OriginalStreamId { get; set; }
+        string TunerHostId { get; }
         bool EnableStreamSharing { get; set; }
-        ITunerHost TunerHost { get; set; }
         MediaSourceInfo OpenedMediaSource { get; set; }
         string UniqueId { get; }
         List<string> SharedStreamIds { get; }

+ 4 - 6
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -1341,13 +1341,11 @@ namespace MediaBrowser.Model.Dlna
                 return false;
             }
 
-            if (!item.Bitrate.HasValue)
-            {
-                _logger.Info("Cannot " + playMethod + " due to unknown content bitrate");
-                return false;
-            }
+            // If we don't know the bitrate, then force a transcode if requested max bitrate is under 40 mbps
+            var itemBitrate = item.Bitrate ?? 
+                40000000;
 
-            if (item.Bitrate.Value > maxBitrate.Value)
+            if (itemBitrate > maxBitrate.Value)
             {
                 _logger.Info("Bitrate exceeds " + playMethod + " limit: media bitrate: {0}, max bitrate: {1}", item.Bitrate.Value.ToString(CultureInfo.InvariantCulture), maxBitrate.Value.ToString(CultureInfo.InvariantCulture));
                 return false;

+ 1 - 0
MediaBrowser.Model/LiveTv/LiveTvOptions.cs

@@ -47,6 +47,7 @@ namespace MediaBrowser.Model.LiveTv
         public bool EnableStreamLooping { get; set; }
         public bool EnableNewHdhrChannelIds { get; set; }
         public string Source { get; set; }
+        public int TunerCount { get; set; }
 
         public TunerHostInfo()
         {

+ 1 - 1
SharedVersion.cs

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