ソースを参照

use server to build stream url's

Luke Pulverenti 10 年 前
コミット
cd99ad4366

+ 47 - 13
MediaBrowser.Api/Playback/MediaInfoService.cs

@@ -43,6 +43,15 @@ namespace MediaBrowser.Api.Playback
 
         [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
         public string UserId { get; set; }
+
+        [ApiMember(Name = "StartTimeTicks", Description = "Optional. Specify a starting offset, in ticks. 1 tick = 10000 ms", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public long? StartTimeTicks { get; set; }
+
+        [ApiMember(Name = "AudioStreamIndex", Description = "Optional. The index of the audio stream to use. If omitted the first audio stream will be used.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? AudioStreamIndex { get; set; }
+
+        [ApiMember(Name = "SubtitleStreamIndex", Description = "Optional. The index of the subtitle stream to use. If omitted no subtitles will be used.", IsRequired = false, DataType = "int", ParameterType = "query", Verb = "GET")]
+        public int? SubtitleStreamIndex { get; set; }
     }
 
     [Authenticated]
@@ -73,7 +82,7 @@ namespace MediaBrowser.Api.Playback
 
         public async Task<object> Post(GetPostedPlaybackInfo request)
         {
-            var info = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
+            var info = await GetPlaybackInfo(request.Id, request.UserId, request.MediaSource).ConfigureAwait(false);
             var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
 
             var profile = request.DeviceProfile;
@@ -88,29 +97,38 @@ namespace MediaBrowser.Api.Playback
 
             if (profile != null)
             {
-                SetDeviceSpecificData(request.Id, info, profile, authInfo, null);
+                var mediaSourceId = request.MediaSource == null ? null : request.MediaSource.Id;
+                SetDeviceSpecificData(request.Id, info, profile, authInfo, null, request.StartTimeTicks ?? 0, mediaSourceId, request.AudioStreamIndex, request.SubtitleStreamIndex);
             }
 
             return ToOptimizedResult(info);
         }
 
-        private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId)
+        private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId, MediaSourceInfo mediaSource = null)
         {
-            IEnumerable<MediaSourceInfo> mediaSources;
             var result = new PlaybackInfoResponse();
 
-            try
+            if (mediaSource == null)
             {
-                mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, CancellationToken.None).ConfigureAwait(false);
+                IEnumerable<MediaSourceInfo> mediaSources;
+
+                try
+                {
+                    mediaSources = await _mediaSourceManager.GetPlayackMediaSources(id, userId, true, CancellationToken.None).ConfigureAwait(false);
+                }
+                catch (PlaybackException ex)
+                {
+                    mediaSources = new List<MediaSourceInfo>();
+                    result.ErrorCode = ex.ErrorCode;
+                }
+
+                result.MediaSources = mediaSources.ToList();
             }
-            catch (PlaybackException ex)
+            else
             {
-                mediaSources = new List<MediaSourceInfo>();
-                result.ErrorCode = ex.ErrorCode;
+                result.MediaSources = new List<MediaSourceInfo> { mediaSource };
             }
 
-            result.MediaSources = mediaSources.ToList();
-
             if (result.MediaSources.Count == 0)
             {
                 if (!result.ErrorCode.HasValue)
@@ -126,7 +144,15 @@ namespace MediaBrowser.Api.Playback
             return result;
         }
 
-        private void SetDeviceSpecificData(string itemId, PlaybackInfoResponse result, DeviceProfile profile, AuthorizationInfo auth, int? maxBitrate)
+        private void SetDeviceSpecificData(string itemId, 
+            PlaybackInfoResponse result, 
+            DeviceProfile profile, 
+            AuthorizationInfo auth, 
+            int? maxBitrate, 
+            long startTimeTicks,
+            string mediaSourceId,
+            int? audioStreamIndex,
+            int? subtitleStreamIndex)
         {
             var streamBuilder = new StreamBuilder();
 
@@ -144,13 +170,20 @@ namespace MediaBrowser.Api.Playback
                     MaxBitrate = maxBitrate
                 };
 
+                if (string.Equals(mediaSourceId, mediaSource.Id, StringComparison.OrdinalIgnoreCase))
+                {
+                    options.MediaSourceId = mediaSourceId;
+                    options.AudioStreamIndex = audioStreamIndex;
+                    options.SubtitleStreamIndex = subtitleStreamIndex;
+                }
+
                 if (mediaSource.SupportsDirectPlay)
                 {
                     var supportsDirectStream = mediaSource.SupportsDirectStream;
 
                     // Dummy this up to fool StreamBuilder
                     mediaSource.SupportsDirectStream = true;
-                    
+
                     // The MediaSource supports direct stream, now test to see if the client supports it
                     var streamInfo = item is Video ?
                         streamBuilder.BuildVideoItem(options) :
@@ -187,6 +220,7 @@ namespace MediaBrowser.Api.Playback
 
                     if (streamInfo != null && streamInfo.PlayMethod == PlayMethod.Transcode)
                     {
+                        streamInfo.StartPositionTicks = startTimeTicks;
                         mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).Substring(1);
                         mediaSource.TranscodingContainer = streamInfo.Container;
                         mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;

+ 21 - 2
MediaBrowser.Model/Dlna/StreamInfo.cs

@@ -102,10 +102,29 @@ namespace MediaBrowser.Model.Dlna
             List<string> list = new List<string>();
             foreach (NameValuePair pair in BuildParams(this, accessToken))
             {
-                if (!string.IsNullOrEmpty(pair.Value))
+                if (string.IsNullOrEmpty(pair.Value))
                 {
-                    list.Add(string.Format("{0}={1}", pair.Name, pair.Value));
+                    continue;
                 }
+
+                // Try to keep the url clean by omitting defaults
+                if (StringHelper.EqualsIgnoreCase(pair.Name, "StartTimeTicks") &&
+                    StringHelper.EqualsIgnoreCase(pair.Value, "0"))
+                {
+                    continue;
+                }
+                if (StringHelper.EqualsIgnoreCase(pair.Name, "SubtitleStreamIndex") &&
+                    StringHelper.EqualsIgnoreCase(pair.Value, "-1"))
+                {
+                    continue;
+                }
+                if (StringHelper.EqualsIgnoreCase(pair.Name, "Static") &&
+                    StringHelper.EqualsIgnoreCase(pair.Value, "false"))
+                {
+                    continue;
+                }
+
+                list.Add(string.Format("{0}={1}", pair.Name, pair.Value));
             }
 
             string queryString = string.Join("&", list.ToArray());

+ 2 - 0
MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs

@@ -1,9 +1,11 @@
 using MediaBrowser.Model.Dlna;
+using MediaBrowser.Model.Dto;
 
 namespace MediaBrowser.Model.MediaInfo
 {
     public class PlaybackInfoRequest
     {
         public DeviceProfile DeviceProfile { get; set; }
+        public MediaSourceInfo MediaSource { get; set; }
     }
 }