瀏覽代碼

update behavior with restricted transcoding access

Luke Pulverenti 9 年之前
父節點
當前提交
8328f39834

+ 14 - 1
MediaBrowser.Api/Playback/BaseStreamingService.cs

@@ -1669,7 +1669,7 @@ namespace MediaBrowser.Api.Playback
                 RequestedUrl = url,
                 UserAgent = Request.UserAgent
             };
-            
+
             //if ((Request.UserAgent ?? string.Empty).IndexOf("iphone", StringComparison.OrdinalIgnoreCase) != -1 ||
             //    (Request.UserAgent ?? string.Empty).IndexOf("ipad", StringComparison.OrdinalIgnoreCase) != -1 ||
             //    (Request.UserAgent ?? string.Empty).IndexOf("ipod", StringComparison.OrdinalIgnoreCase) != -1)
@@ -1770,6 +1770,19 @@ namespace MediaBrowser.Api.Playback
             {
                 state.OutputVideoCodec = "copy";
             }
+            else
+            {
+                // If the user doesn't have access to transcoding, then force stream copy, regardless of whether it will be compatible or not
+                var auth = AuthorizationContext.GetAuthorizationInfo(Request);
+                if (!string.IsNullOrWhiteSpace(auth.UserId))
+                {
+                    var user = UserManager.GetUserById(auth.UserId);
+                    if (!user.Policy.EnableVideoPlaybackTranscoding)
+                    {
+                        state.OutputVideoCodec = "copy";
+                    }
+                }
+            }
 
             if (state.AudioStream != null && CanStreamCopyAudio(state, state.SupportedAudioCodecs))
             {

+ 0 - 12
MediaBrowser.Api/Playback/Hls/DynamicHlsService.cs

@@ -942,17 +942,5 @@ namespace MediaBrowser.Api.Playback.Hls
         {
             return isOutputVideo ? ".ts" : ".ts";
         }
-
-        protected override bool CanStreamCopyVideo(StreamState state)
-        {
-            var isLiveStream = IsLiveStream(state);
-
-            //if (!isLiveStream && Request.QueryString["AllowCustomSegmenting"] != "true")
-            //{
-            //    return false;
-            //}
-
-            return base.CanStreamCopyVideo(state);
-        }
     }
 }

+ 29 - 6
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -15,6 +15,7 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Threading;
 using System.Threading.Tasks;
+using MediaBrowser.Controller.Entities.Audio;
 using MediaBrowser.Controller.MediaEncoding;
 
 namespace MediaBrowser.Api.Playback
@@ -68,8 +69,9 @@ namespace MediaBrowser.Api.Playback
         private readonly IServerConfigurationManager _config;
         private readonly INetworkManager _networkManager;
         private readonly IMediaEncoder _mediaEncoder;
+        private readonly IUserManager _userManager;
 
-        public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder)
+        public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager, IServerConfigurationManager config, INetworkManager networkManager, IMediaEncoder mediaEncoder, IUserManager userManager)
         {
             _mediaSourceManager = mediaSourceManager;
             _deviceManager = deviceManager;
@@ -77,6 +79,7 @@ namespace MediaBrowser.Api.Playback
             _config = config;
             _networkManager = networkManager;
             _mediaEncoder = mediaEncoder;
+            _userManager = userManager;
         }
 
         public object Get(GetBitrateTestBytes request)
@@ -119,7 +122,7 @@ namespace MediaBrowser.Api.Playback
 
                 SetDeviceSpecificData(item, result.MediaSource, profile, authInfo, request.MaxStreamingBitrate,
                     request.StartTimeTicks ?? 0, result.MediaSource.Id, request.AudioStreamIndex,
-                    request.SubtitleStreamIndex, request.PlaySessionId);
+                    request.SubtitleStreamIndex, request.PlaySessionId, request.UserId);
             }
             else
             {
@@ -159,7 +162,7 @@ namespace MediaBrowser.Api.Playback
             {
                 var mediaSourceId = request.MediaSourceId;
 
-                SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex);
+                SetDeviceSpecificData(request.Id, info, profile, authInfo, request.MaxStreamingBitrate ?? profile.MaxStreamingBitrate, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex, request.UserId);
             }
 
             return ToOptimizedResult(info);
@@ -221,13 +224,14 @@ namespace MediaBrowser.Api.Playback
             long startTimeTicks,
             string mediaSourceId,
             int? audioStreamIndex,
-            int? subtitleStreamIndex)
+            int? subtitleStreamIndex,
+            string userId)
         {
             var item = _libraryManager.GetItemById(itemId);
 
             foreach (var mediaSource in result.MediaSources)
             {
-                SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId);
+                SetDeviceSpecificData(item, mediaSource, profile, auth, maxBitrate, startTimeTicks, mediaSourceId, audioStreamIndex, subtitleStreamIndex, result.PlaySessionId, userId);
             }
 
             SortMediaSources(result, maxBitrate);
@@ -242,7 +246,8 @@ namespace MediaBrowser.Api.Playback
             string mediaSourceId,
             int? audioStreamIndex,
             int? subtitleStreamIndex,
-            string playSessionId)
+            string playSessionId,
+            string userId)
         {
             var streamBuilder = new StreamBuilder(_mediaEncoder, Logger);
 
@@ -262,6 +267,8 @@ namespace MediaBrowser.Api.Playback
                 options.SubtitleStreamIndex = subtitleStreamIndex;
             }
 
+            var user = _userManager.GetUserById(userId);
+
             if (mediaSource.SupportsDirectPlay)
             {
                 var supportsDirectStream = mediaSource.SupportsDirectStream;
@@ -270,6 +277,14 @@ namespace MediaBrowser.Api.Playback
                 mediaSource.SupportsDirectStream = true;
                 options.MaxBitrate = maxBitrate;
 
+                if (item is Audio)
+                {
+                    if (!user.Policy.EnableAudioPlaybackTranscoding)
+                    {
+                        options.ForceDirectPlay = true;
+                    }
+                }
+
                 // The MediaSource supports direct stream, now test to see if the client supports it
                 var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
                     streamBuilder.BuildAudioItem(options) :
@@ -293,6 +308,14 @@ namespace MediaBrowser.Api.Playback
             {
                 options.MaxBitrate = GetMaxBitrate(maxBitrate);
 
+                if (item is Audio)
+                {
+                    if (!user.Policy.EnableAudioPlaybackTranscoding)
+                    {
+                        options.ForceDirectStream = true;
+                    }
+                }
+
                 // The MediaSource supports direct stream, now test to see if the client supports it
                 var streamInfo = string.Equals(item.MediaType, MediaType.Audio, StringComparison.OrdinalIgnoreCase) ?
                     streamBuilder.BuildAudioItem(options) :

+ 2 - 5
MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj

@@ -346,8 +346,8 @@
     <Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
       <Link>Dlna\HttpHeaderInfo.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
-      <Link>Dlna\ILocalPlayer.cs</Link>
+    <Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
+      <Link>Dlna\ITranscoderSupport.cs</Link>
     </Compile>
     <Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
       <Link>Dlna\MediaFormatProfile.cs</Link>
@@ -355,9 +355,6 @@
     <Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
       <Link>Dlna\MediaFormatProfileResolver.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
-      <Link>Dlna\NullLocalPlayer.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
       <Link>Dlna\PlaybackErrorCode.cs</Link>
     </Compile>

+ 2 - 5
MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj

@@ -318,8 +318,8 @@
     <Compile Include="..\MediaBrowser.Model\Dlna\HttpHeaderInfo.cs">
       <Link>Dlna\HttpHeaderInfo.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Dlna\ILocalPlayer.cs">
-      <Link>Dlna\ILocalPlayer.cs</Link>
+    <Compile Include="..\MediaBrowser.Model\Dlna\ITranscoderSupport.cs">
+      <Link>Dlna\ITranscoderSupport.cs</Link>
     </Compile>
     <Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfile.cs">
       <Link>Dlna\MediaFormatProfile.cs</Link>
@@ -327,9 +327,6 @@
     <Compile Include="..\MediaBrowser.Model\Dlna\MediaFormatProfileResolver.cs">
       <Link>Dlna\MediaFormatProfileResolver.cs</Link>
     </Compile>
-    <Compile Include="..\MediaBrowser.Model\Dlna\NullLocalPlayer.cs">
-      <Link>Dlna\NullLocalPlayer.cs</Link>
-    </Compile>
     <Compile Include="..\MediaBrowser.Model\Dlna\PlaybackErrorCode.cs">
       <Link>Dlna\PlaybackErrorCode.cs</Link>
     </Compile>

+ 2 - 0
MediaBrowser.Model/Dlna/AudioOptions.cs

@@ -18,6 +18,8 @@ namespace MediaBrowser.Model.Dlna
 
         public bool EnableDirectPlay { get; set; }
         public bool EnableDirectStream { get; set; }
+        public bool ForceDirectPlay { get; set; }
+        public bool ForceDirectStream { get; set; }
 
         public string ItemId { get; set; }
         public List<MediaSourceInfo> MediaSources { get; set; }

+ 0 - 39
MediaBrowser.Model/Dlna/ILocalPlayer.cs

@@ -1,39 +0,0 @@
-
-namespace MediaBrowser.Model.Dlna
-{
-    public interface ILocalPlayer
-    {
-        /// <summary>
-        /// Determines whether this instance [can access file] the specified path.
-        /// </summary>
-        /// <param name="path">The path.</param>
-        /// <returns><c>true</c> if this instance [can access file] the specified path; otherwise, <c>false</c>.</returns>
-        bool CanAccessFile(string path);
-        /// <summary>
-        /// Determines whether this instance [can access directory] the specified path.
-        /// </summary>
-        /// <param name="path">The path.</param>
-        /// <returns><c>true</c> if this instance [can access directory] the specified path; otherwise, <c>false</c>.</returns>
-        bool CanAccessDirectory(string path);
-        /// <summary>
-        /// Determines whether this instance [can access URL] the specified URL.
-        /// </summary>
-        /// <param name="url">The URL.</param>
-        /// <param name="requiresCustomRequestHeaders">if set to <c>true</c> [requires custom request headers].</param>
-        /// <returns><c>true</c> if this instance [can access URL] the specified URL; otherwise, <c>false</c>.</returns>
-        bool CanAccessUrl(string url, bool requiresCustomRequestHeaders);
-    }
-
-    public interface ITranscoderSupport
-    {
-        bool CanEncodeToAudioCodec(string codec);
-    }
-
-    public class FullTranscoderSupport : ITranscoderSupport
-    {
-        public bool CanEncodeToAudioCodec(string codec)
-        {
-            return true;
-        }
-    }
-}

+ 15 - 0
MediaBrowser.Model/Dlna/ITranscoderSupport.cs

@@ -0,0 +1,15 @@
+namespace MediaBrowser.Model.Dlna
+{
+    public interface ITranscoderSupport
+    {
+        bool CanEncodeToAudioCodec(string codec);
+    }
+
+    public class FullTranscoderSupport : ITranscoderSupport
+    {
+        public bool CanEncodeToAudioCodec(string codec)
+        {
+            return true;
+        }
+    }
+}

+ 0 - 21
MediaBrowser.Model/Dlna/NullLocalPlayer.cs

@@ -1,21 +0,0 @@
-
-namespace MediaBrowser.Model.Dlna
-{
-    public class NullLocalPlayer : ILocalPlayer
-    {
-        public bool CanAccessFile(string path)
-        {
-            return false;
-        }
-
-        public bool CanAccessDirectory(string path)
-        {
-            return false;
-        }
-
-        public bool CanAccessUrl(string url, bool requiresCustomRequestHeaders)
-        {
-            return false;
-        }
-    }
-}

+ 32 - 50
MediaBrowser.Model/Dlna/StreamBuilder.cs

@@ -11,29 +11,17 @@ namespace MediaBrowser.Model.Dlna
 {
     public class StreamBuilder
     {
-        private readonly ILocalPlayer _localPlayer;
         private readonly ILogger _logger;
         private readonly ITranscoderSupport _transcoderSupport;
 
-        public StreamBuilder(ILocalPlayer localPlayer, ITranscoderSupport transcoderSupport, ILogger logger)
+        public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger)
         {
             _transcoderSupport = transcoderSupport;
-            _localPlayer = localPlayer;
             _logger = logger;
         }
 
-        public StreamBuilder(ITranscoderSupport transcoderSupport, ILogger logger)
-            : this(new NullLocalPlayer(), transcoderSupport, logger)
-        {
-        }
-
-        public StreamBuilder(ILocalPlayer localPlayer, ILogger logger)
-            : this(localPlayer, new FullTranscoderSupport(), logger)
-        {
-        }
-
         public StreamBuilder(ILogger logger)
-            : this(new NullLocalPlayer(), new FullTranscoderSupport(), logger)
+            : this(new FullTranscoderSupport(), logger)
         {
         }
 
@@ -127,6 +115,20 @@ namespace MediaBrowser.Model.Dlna
                 DeviceProfile = options.Profile
             };
 
+            if (options.ForceDirectPlay)
+            {
+                playlistItem.PlayMethod = PlayMethod.DirectPlay;
+                playlistItem.Container = item.Container;
+                return playlistItem;
+            }
+
+            if (options.ForceDirectStream)
+            {
+                playlistItem.PlayMethod = PlayMethod.DirectStream;
+                playlistItem.Container = item.Container;
+                return playlistItem;
+            }
+
             MediaStream audioStream = item.GetDefaultAudioStream(null);
 
             List<PlayMethod> directPlayMethods = GetAudioDirectPlayMethods(item, audioStream, options);
@@ -182,19 +184,7 @@ namespace MediaBrowser.Model.Dlna
 
                     if (all)
                     {
-                        if (item.Protocol == MediaProtocol.File &&
-                            directPlayMethods.Contains(PlayMethod.DirectPlay) &&
-                            _localPlayer.CanAccessFile(item.Path))
-                        {
-                            playlistItem.PlayMethod = PlayMethod.DirectPlay;
-                        }
-                        else if (item.Protocol == MediaProtocol.Http &&
-                            directPlayMethods.Contains(PlayMethod.DirectPlay) &&
-                            _localPlayer.CanAccessUrl(item.Path, item.RequiredHttpHeaders.Count > 0))
-                        {
-                            playlistItem.PlayMethod = PlayMethod.DirectPlay;
-                        }
-                        else if (directPlayMethods.Contains(PlayMethod.DirectStream))
+                        if (directPlayMethods.Contains(PlayMethod.DirectStream))
                         {
                             playlistItem.PlayMethod = PlayMethod.DirectStream;
                         }
@@ -413,8 +403,8 @@ namespace MediaBrowser.Model.Dlna
             MediaStream videoStream = item.VideoStream;
 
             // TODO: This doesn't accout for situation of device being able to handle media bitrate, but wifi connection not fast enough
-            bool isEligibleForDirectPlay = options.EnableDirectPlay && IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay);
-            bool isEligibleForDirectStream = options.EnableDirectStream && IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream);
+            bool isEligibleForDirectPlay = options.EnableDirectPlay && (options.ForceDirectPlay || IsEligibleForDirectPlay(item, GetBitrateForDirectPlayCheck(item, options), subtitleStream, options, PlayMethod.DirectPlay));
+            bool isEligibleForDirectStream = options.EnableDirectStream && (options.ForceDirectStream || IsEligibleForDirectPlay(item, options.GetMaxBitrate(), subtitleStream, options, PlayMethod.DirectStream));
 
             _logger.Info("Profile: {0}, Path: {1}, isEligibleForDirectPlay: {2}, isEligibleForDirectStream: {3}",
                 options.Profile.Name ?? "Unknown Profile",
@@ -425,7 +415,7 @@ namespace MediaBrowser.Model.Dlna
             if (isEligibleForDirectPlay || isEligibleForDirectStream)
             {
                 // See if it can be direct played
-                PlayMethod? directPlay = GetVideoDirectPlayProfile(options.Profile, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
+                PlayMethod? directPlay = GetVideoDirectPlayProfile(options, item, videoStream, audioStream, isEligibleForDirectPlay, isEligibleForDirectStream);
 
                 if (directPlay != null)
                 {
@@ -645,13 +635,24 @@ namespace MediaBrowser.Model.Dlna
             return Math.Min(defaultBitrate, encoderAudioBitrateLimit);
         }
 
-        private PlayMethod? GetVideoDirectPlayProfile(DeviceProfile profile,
+        private PlayMethod? GetVideoDirectPlayProfile(VideoOptions options,
             MediaSourceInfo mediaSource,
             MediaStream videoStream,
             MediaStream audioStream,
             bool isEligibleForDirectPlay,
             bool isEligibleForDirectStream)
         {
+            DeviceProfile profile = options.Profile;
+
+            if (options.ForceDirectPlay)
+            {
+                return PlayMethod.DirectPlay;
+            }
+            if (options.ForceDirectStream)
+            {
+                return PlayMethod.DirectStream;
+            }
+
             if (videoStream == null)
             {
                 _logger.Info("Profile: {0}, Cannot direct stream with no known video stream. Path: {1}",
@@ -829,25 +830,6 @@ namespace MediaBrowser.Model.Dlna
                 }
             }
 
-            if (isEligibleForDirectPlay && mediaSource.SupportsDirectPlay)
-            {
-                if (mediaSource.Protocol == MediaProtocol.Http)
-                {
-                    if (_localPlayer.CanAccessUrl(mediaSource.Path, mediaSource.RequiredHttpHeaders.Count > 0))
-                    {
-                        return PlayMethod.DirectPlay;
-                    }
-                }
-
-                else if (mediaSource.Protocol == MediaProtocol.File)
-                {
-                    if (_localPlayer.CanAccessFile(mediaSource.Path))
-                    {
-                        return PlayMethod.DirectPlay;
-                    }
-                }
-            }
-
             if (isEligibleForDirectStream && mediaSource.SupportsDirectStream)
             {
                 return PlayMethod.DirectStream;

+ 1 - 2
MediaBrowser.Model/MediaBrowser.Model.csproj

@@ -118,9 +118,8 @@
     <Compile Include="Devices\DeviceInfo.cs" />
     <Compile Include="Devices\DevicesOptions.cs" />
     <Compile Include="Dlna\EncodingContext.cs" />
-    <Compile Include="Dlna\ILocalPlayer.cs" />
+    <Compile Include="Dlna\ITranscoderSupport.cs" />
     <Compile Include="Dlna\StreamInfoSorter.cs" />
-    <Compile Include="Dlna\NullLocalPlayer.cs" />
     <Compile Include="Dlna\PlaybackErrorCode.cs" />
     <Compile Include="Dlna\PlaybackException.cs" />
     <Compile Include="Dlna\ResolutionConfiguration.cs" />

+ 1 - 9
MediaBrowser.WebDashboard/Api/PackageCreator.cs

@@ -440,15 +440,7 @@ namespace MediaBrowser.WebDashboard.Api
                 files.Insert(0, "cordova.js");
             }
 
-            var tags = files.Select(s =>
-            {
-                if (s.IndexOf("require", StringComparison.OrdinalIgnoreCase) == -1 && s.IndexOf("alameda", StringComparison.OrdinalIgnoreCase) == -1)
-                {
-                    return string.Format("<script src=\"{0}\" async></script>", s);
-                }
-                return string.Format("<script src=\"{0}\"></script>", s);
-
-            }).ToArray();
+            var tags = files.Select(s => string.Format("<script src=\"{0}\" defer></script>", s)).ToArray();
 
             builder.Append(string.Join(string.Empty, tags));