aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-26 15:18:21 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-26 15:18:21 -0400
commitcd99ad43661a5353ba70b8f4b260e52b31efe737 (patch)
treed9a8bb3b1e9084522bfed3c202ec894b32ca747c
parent3ec7090c6e7d2f33524cc269f0c374cd6bb2ef8b (diff)
use server to build stream url's
-rw-r--r--MediaBrowser.Api/Playback/MediaInfoService.cs60
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs23
-rw-r--r--MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs2
3 files changed, 70 insertions, 15 deletions
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index 379b69710..ce140365b 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/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;
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 46efd4231..60615d1da 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/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());
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
index ffd4995ad..783fb4120 100644
--- a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
+++ b/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; }
}
}