aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-26 12:58:02 -0400
committerLuke Pulverenti <luke.pulverenti@gmail.com>2015-03-26 12:58:02 -0400
commit348b8c44142ce14a8395552f8d429fb9d0b24a36 (patch)
treec853efe8395ded4ea0f5c08f521c2863028a46e3
parent46c92107490263f8e6abefbd2259780013fa195d (diff)
use server to build initial stream url's
-rw-r--r--MediaBrowser.Api/Playback/MediaInfoService.cs146
-rw-r--r--MediaBrowser.Controller/Channels/ChannelMediaInfo.cs3
-rw-r--r--MediaBrowser.Controller/Entities/Video.cs3
-rw-r--r--MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj9
-rw-r--r--MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj9
-rw-r--r--MediaBrowser.Model/ApiClient/IApiClient.cs2
-rw-r--r--MediaBrowser.Model/Dlna/StreamBuilder.cs8
-rw-r--r--MediaBrowser.Model/Dlna/StreamInfo.cs8
-rw-r--r--MediaBrowser.Model/Dto/MediaSourceInfo.cs8
-rw-r--r--MediaBrowser.Model/MediaBrowser.Model.csproj3
-rw-r--r--MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs9
-rw-r--r--MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs (renamed from MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs)4
12 files changed, 178 insertions, 34 deletions
diff --git a/MediaBrowser.Api/Playback/MediaInfoService.cs b/MediaBrowser.Api/Playback/MediaInfoService.cs
index 2a17b2fe8..379b69710 100644
--- a/MediaBrowser.Api/Playback/MediaInfoService.cs
+++ b/MediaBrowser.Api/Playback/MediaInfoService.cs
@@ -1,8 +1,11 @@
-using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Devices;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Net;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Dto;
using MediaBrowser.Model.MediaInfo;
+using MediaBrowser.Model.Session;
using ServiceStack;
using System;
using System.Collections.Generic;
@@ -13,7 +16,7 @@ using System.Threading.Tasks;
namespace MediaBrowser.Api.Playback
{
[Route("/Items/{Id}/MediaInfo", "GET", Summary = "Gets live playback media info for an item")]
- public class GetLiveMediaInfo : IReturn<LiveMediaInfoResult>
+ public class GetLiveMediaInfo : IReturn<PlaybackInfoResponse>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
@@ -23,7 +26,17 @@ namespace MediaBrowser.Api.Playback
}
[Route("/Items/{Id}/PlaybackInfo", "GET", Summary = "Gets live playback media info for an item")]
- public class GetPlaybackInfo : IReturn<LiveMediaInfoResult>
+ public class GetPlaybackInfo : IReturn<PlaybackInfoResponse>
+ {
+ [ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
+ public string Id { get; set; }
+
+ [ApiMember(Name = "UserId", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "GET")]
+ public string UserId { get; set; }
+ }
+
+ [Route("/Items/{Id}/PlaybackInfo", "POST", Summary = "Gets live playback media info for an item")]
+ public class GetPostedPlaybackInfo : PlaybackInfoRequest, IReturn<PlaybackInfoResponse>
{
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
public string Id { get; set; }
@@ -36,26 +49,55 @@ namespace MediaBrowser.Api.Playback
public class MediaInfoService : BaseApiService
{
private readonly IMediaSourceManager _mediaSourceManager;
+ private readonly IDeviceManager _deviceManager;
+ private readonly ILibraryManager _libraryManager;
- public MediaInfoService(IMediaSourceManager mediaSourceManager)
+ public MediaInfoService(IMediaSourceManager mediaSourceManager, IDeviceManager deviceManager, ILibraryManager libraryManager)
{
_mediaSourceManager = mediaSourceManager;
+ _deviceManager = deviceManager;
+ _libraryManager = libraryManager;
+ }
+
+ public async Task<object> Get(GetPlaybackInfo request)
+ {
+ var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
+ return ToOptimizedResult(result);
}
- public Task<object> Get(GetPlaybackInfo request)
+ public async Task<object> Get(GetLiveMediaInfo request)
{
- return GetPlaybackInfo(request.Id, request.UserId);
+ var result = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
+ return ToOptimizedResult(result);
}
- public Task<object> Get(GetLiveMediaInfo request)
+ public async Task<object> Post(GetPostedPlaybackInfo request)
{
- return GetPlaybackInfo(request.Id, request.UserId);
+ var info = await GetPlaybackInfo(request.Id, request.UserId).ConfigureAwait(false);
+ var authInfo = AuthorizationContext.GetAuthorizationInfo(Request);
+
+ var profile = request.DeviceProfile;
+ //if (profile == null)
+ //{
+ // var caps = _deviceManager.GetCapabilities(authInfo.DeviceId);
+ // if (caps != null)
+ // {
+ // profile = caps.DeviceProfile;
+ // }
+ //}
+
+ if (profile != null)
+ {
+ SetDeviceSpecificData(request.Id, info, profile, authInfo, null);
+ }
+
+ return ToOptimizedResult(info);
}
- private async Task<object> GetPlaybackInfo(string id, string userId)
+ private async Task<PlaybackInfoResponse> GetPlaybackInfo(string id, string userId)
{
IEnumerable<MediaSourceInfo> mediaSources;
- var result = new LiveMediaInfoResult();
+ var result = new PlaybackInfoResponse();
try
{
@@ -68,9 +110,89 @@ namespace MediaBrowser.Api.Playback
}
result.MediaSources = mediaSources.ToList();
- result.StreamId = Guid.NewGuid().ToString("N");
- return ToOptimizedResult(result);
+ if (result.MediaSources.Count == 0)
+ {
+ if (!result.ErrorCode.HasValue)
+ {
+ result.ErrorCode = PlaybackErrorCode.NoCompatibleStream;
+ }
+ }
+ else
+ {
+ result.StreamId = Guid.NewGuid().ToString("N");
+ }
+
+ return result;
+ }
+
+ private void SetDeviceSpecificData(string itemId, PlaybackInfoResponse result, DeviceProfile profile, AuthorizationInfo auth, int? maxBitrate)
+ {
+ var streamBuilder = new StreamBuilder();
+
+ var item = _libraryManager.GetItemById(itemId);
+
+ foreach (var mediaSource in result.MediaSources)
+ {
+ var options = new VideoOptions
+ {
+ MediaSources = new List<MediaSourceInfo> { mediaSource },
+ Context = EncodingContext.Streaming,
+ DeviceId = auth.DeviceId,
+ ItemId = item.Id.ToString("N"),
+ Profile = profile,
+ MaxBitrate = maxBitrate
+ };
+
+ 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) :
+ streamBuilder.BuildAudioItem(options);
+
+ if (streamInfo == null || !streamInfo.IsDirectStream)
+ {
+ mediaSource.SupportsDirectPlay = false;
+ }
+
+ // Set this back to what it was
+ mediaSource.SupportsDirectStream = supportsDirectStream;
+ }
+
+ if (mediaSource.SupportsDirectStream)
+ {
+ // The MediaSource supports direct stream, now test to see if the client supports it
+ var streamInfo = item is Video ?
+ streamBuilder.BuildVideoItem(options) :
+ streamBuilder.BuildAudioItem(options);
+
+ if (streamInfo == null || !streamInfo.IsDirectStream)
+ {
+ mediaSource.SupportsDirectStream = false;
+ }
+ }
+
+ if (mediaSource.SupportsTranscoding)
+ {
+ // The MediaSource supports direct stream, now test to see if the client supports it
+ var streamInfo = item is Video ?
+ streamBuilder.BuildVideoItem(options) :
+ streamBuilder.BuildAudioItem(options);
+
+ if (streamInfo != null && streamInfo.PlayMethod == PlayMethod.Transcode)
+ {
+ mediaSource.TranscodingUrl = streamInfo.ToUrl("-", auth.Token).Substring(1);
+ mediaSource.TranscodingContainer = streamInfo.Container;
+ mediaSource.TranscodingSubProtocol = streamInfo.SubProtocol;
+ }
+ }
+ }
}
}
}
diff --git a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
index 0c2e30923..94fa1ac02 100644
--- a/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
+++ b/MediaBrowser.Controller/Channels/ChannelMediaInfo.cs
@@ -62,7 +62,8 @@ namespace MediaBrowser.Controller.Channels
RunTimeTicks = RunTimeTicks,
Name = id,
Id = id,
- ReadAtNativeFramerate = ReadAtNativeFramerate
+ ReadAtNativeFramerate = ReadAtNativeFramerate,
+ SupportsDirectStream = Protocol == MediaProtocol.File || Protocol == MediaProtocol.Http
};
var bitrate = (AudioBitrate ?? 0) + (VideoBitrate ?? 0);
diff --git a/MediaBrowser.Controller/Entities/Video.cs b/MediaBrowser.Controller/Entities/Video.cs
index ba84beca3..00dc5dc67 100644
--- a/MediaBrowser.Controller/Entities/Video.cs
+++ b/MediaBrowser.Controller/Entities/Video.cs
@@ -501,7 +501,8 @@ namespace MediaBrowser.Controller.Entities
Formats = (i.FormatName ?? string.Empty).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(),
Timestamp = i.Timestamp,
Type = type,
- PlayableStreamFileNames = i.PlayableStreamFileNames.ToList()
+ PlayableStreamFileNames = i.PlayableStreamFileNames.ToList(),
+ SupportsDirectStream = i.VideoType == VideoType.VideoFile
};
if (i.IsShortcut)
diff --git a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
index c2d46b9b3..118e5659a 100644
--- a/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
+++ b/MediaBrowser.Model.Portable/MediaBrowser.Model.Portable.csproj
@@ -800,12 +800,15 @@
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
<Link>MediaInfo\IBlurayExaminer.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveMediaInfoResult.cs">
- <Link>MediaInfo\LiveMediaInfoResult.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
<Link>MediaInfo\MediaProtocol.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\MediaInfo\PlaybackInfoRequest.cs">
+ <Link>MediaInfo\PlaybackInfoRequest.cs</Link>
+ </Compile>
+ <Compile Include="..\MediaBrowser.Model\MediaInfo\PlaybackInfoResponse.cs">
+ <Link>MediaInfo\PlaybackInfoResponse.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\MediaInfo\SubtitleFormat.cs">
<Link>MediaInfo\SubtitleFormat.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
index 52745b5de..a97bf2a8c 100644
--- a/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
+++ b/MediaBrowser.Model.net35/MediaBrowser.Model.net35.csproj
@@ -756,12 +756,15 @@
<Compile Include="..\MediaBrowser.Model\MediaInfo\IBlurayExaminer.cs">
<Link>MediaInfo\IBlurayExaminer.cs</Link>
</Compile>
- <Compile Include="..\MediaBrowser.Model\MediaInfo\LiveMediaInfoResult.cs">
- <Link>MediaInfo\LiveMediaInfoResult.cs</Link>
- </Compile>
<Compile Include="..\MediaBrowser.Model\MediaInfo\MediaProtocol.cs">
<Link>MediaInfo\MediaProtocol.cs</Link>
</Compile>
+ <Compile Include="..\MediaBrowser.Model\MediaInfo\PlaybackInfoRequest.cs">
+ <Link>MediaInfo\PlaybackInfoRequest.cs</Link>
+ </Compile>
+ <Compile Include="..\MediaBrowser.Model\MediaInfo\PlaybackInfoResponse.cs">
+ <Link>MediaInfo\PlaybackInfoResponse.cs</Link>
+ </Compile>
<Compile Include="..\MediaBrowser.Model\MediaInfo\SubtitleFormat.cs">
<Link>MediaInfo\SubtitleFormat.cs</Link>
</Compile>
diff --git a/MediaBrowser.Model/ApiClient/IApiClient.cs b/MediaBrowser.Model/ApiClient/IApiClient.cs
index 14cdbdc9a..19d6acf33 100644
--- a/MediaBrowser.Model/ApiClient/IApiClient.cs
+++ b/MediaBrowser.Model/ApiClient/IApiClient.cs
@@ -251,7 +251,7 @@ namespace MediaBrowser.Model.ApiClient
/// <param name="itemId">The item identifier.</param>
/// <param name="userId">The user identifier.</param>
/// <returns>Task&lt;LiveMediaInfoResult&gt;.</returns>
- Task<LiveMediaInfoResult> GetPlaybackInfo(string itemId, string userId);
+ Task<PlaybackInfoResponse> GetPlaybackInfo(string itemId, string userId);
/// <summary>
/// Gets the users async.
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index 3f88f9ac0..7338f604c 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -118,9 +118,7 @@ namespace MediaBrowser.Model.Dlna
return stream;
}
- PlaybackException error = new PlaybackException();
- error.ErrorCode = PlaybackErrorCode.NoCompatibleStream;
- throw error;
+ return null;
}
private StreamInfo BuildAudioItem(MediaSourceInfo item, AudioOptions options)
@@ -221,7 +219,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.EstimateContentLength = transcodingProfile.EstimateContentLength;
playlistItem.Container = transcodingProfile.Container;
playlistItem.AudioCodec = transcodingProfile.AudioCodec;
- playlistItem.Protocol = transcodingProfile.Protocol;
+ playlistItem.SubProtocol = transcodingProfile.Protocol;
List<CodecProfile> audioCodecProfiles = new List<CodecProfile>();
foreach (CodecProfile i in options.Profile.CodecProfiles)
@@ -374,7 +372,7 @@ namespace MediaBrowser.Model.Dlna
playlistItem.TranscodeSeekInfo = transcodingProfile.TranscodeSeekInfo;
playlistItem.AudioCodec = transcodingProfile.AudioCodec.Split(',')[0];
playlistItem.VideoCodec = transcodingProfile.VideoCodec;
- playlistItem.Protocol = transcodingProfile.Protocol;
+ playlistItem.SubProtocol = transcodingProfile.Protocol;
playlistItem.AudioStreamIndex = audioStreamIndex;
List<ProfileCondition> videoTranscodingConditions = new List<ProfileCondition>();
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs
index 4eb1c0a8e..63ddd07cd 100644
--- a/MediaBrowser.Model/Dlna/StreamInfo.cs
+++ b/MediaBrowser.Model/Dlna/StreamInfo.cs
@@ -24,7 +24,7 @@ namespace MediaBrowser.Model.Dlna
public string Container { get; set; }
- public string Protocol { get; set; }
+ public string SubProtocol { get; set; }
public long StartPositionTicks { get; set; }
@@ -69,7 +69,7 @@ namespace MediaBrowser.Model.Dlna
public SubtitleDeliveryMethod SubtitleDeliveryMethod { get; set; }
public string SubtitleFormat { get; set; }
- public LiveMediaInfoResult PlaybackInfo { get; set; }
+ public PlaybackInfoResponse PlaybackInfo { get; set; }
public string MediaSourceId
{
@@ -115,7 +115,7 @@ namespace MediaBrowser.Model.Dlna
return string.Format("{0}/audio/{1}/stream{2}?{3}", baseUrl, ItemId, extension, dlnaCommand);
}
- if (StringHelper.EqualsIgnoreCase(Protocol, "hls"))
+ if (StringHelper.EqualsIgnoreCase(SubProtocol, "hls"))
{
return string.Format("{0}/videos/{1}/master.m3u8?{2}", baseUrl, ItemId, dlnaCommand);
}
@@ -207,7 +207,7 @@ namespace MediaBrowser.Model.Dlna
List<SubtitleStreamInfo> list = new List<SubtitleStreamInfo>();
// HLS will preserve timestamps so we can just grab the full subtitle stream
- long startPositionTicks = StringHelper.EqualsIgnoreCase(Protocol, "hls")
+ long startPositionTicks = StringHelper.EqualsIgnoreCase(SubProtocol, "hls")
? 0
: StartPositionTicks;
diff --git a/MediaBrowser.Model/Dto/MediaSourceInfo.cs b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
index 5495a1f69..31d310acd 100644
--- a/MediaBrowser.Model/Dto/MediaSourceInfo.cs
+++ b/MediaBrowser.Model/Dto/MediaSourceInfo.cs
@@ -24,6 +24,7 @@ namespace MediaBrowser.Model.Dto
public bool ReadAtNativeFramerate { get; set; }
public bool SupportsTranscoding { get; set; }
public bool SupportsDirectStream { get; set; }
+ public bool SupportsDirectPlay { get; set; }
public VideoType? VideoType { get; set; }
@@ -39,7 +40,11 @@ namespace MediaBrowser.Model.Dto
public int? Bitrate { get; set; }
public TransportStreamTimestamp? Timestamp { get; set; }
- public Dictionary<string, string> RequiredHttpHeaders { get; set; }
+ public Dictionary<string, string> RequiredHttpHeaders { get; set; }
+
+ public string TranscodingUrl { get; set; }
+ public string TranscodingSubProtocol { get; set; }
+ public string TranscodingContainer { get; set; }
public MediaSourceInfo()
{
@@ -49,6 +54,7 @@ namespace MediaBrowser.Model.Dto
PlayableStreamFileNames = new List<string>();
SupportsTranscoding = true;
SupportsDirectStream = true;
+ SupportsDirectPlay = true;
}
public int? DefaultAudioStreamIndex { get; set; }
diff --git a/MediaBrowser.Model/MediaBrowser.Model.csproj b/MediaBrowser.Model/MediaBrowser.Model.csproj
index 3a6eda620..30eec434d 100644
--- a/MediaBrowser.Model/MediaBrowser.Model.csproj
+++ b/MediaBrowser.Model/MediaBrowser.Model.csproj
@@ -140,7 +140,8 @@
<Compile Include="Dto\MetadataEditorInfo.cs" />
<Compile Include="Dto\NameIdPair.cs" />
<Compile Include="Dto\NameValuePair.cs" />
- <Compile Include="MediaInfo\LiveMediaInfoResult.cs" />
+ <Compile Include="MediaInfo\PlaybackInfoRequest.cs" />
+ <Compile Include="MediaInfo\PlaybackInfoResponse.cs" />
<Compile Include="Dto\MediaSourceType.cs" />
<Compile Include="Configuration\DynamicDayOfWeek.cs" />
<Compile Include="Entities\ExtraType.cs" />
diff --git a/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
new file mode 100644
index 000000000..ffd4995ad
--- /dev/null
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoRequest.cs
@@ -0,0 +1,9 @@
+using MediaBrowser.Model.Dlna;
+
+namespace MediaBrowser.Model.MediaInfo
+{
+ public class PlaybackInfoRequest
+ {
+ public DeviceProfile DeviceProfile { get; set; }
+ }
+}
diff --git a/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs
index 16f4f76ee..ed0824e8a 100644
--- a/MediaBrowser.Model/MediaInfo/LiveMediaInfoResult.cs
+++ b/MediaBrowser.Model/MediaInfo/PlaybackInfoResponse.cs
@@ -4,7 +4,7 @@ using System.Collections.Generic;
namespace MediaBrowser.Model.MediaInfo
{
- public class LiveMediaInfoResult
+ public class PlaybackInfoResponse
{
/// <summary>
/// Gets or sets the media sources.
@@ -24,7 +24,7 @@ namespace MediaBrowser.Model.MediaInfo
/// <value>The error code.</value>
public PlaybackErrorCode? ErrorCode { get; set; }
- public LiveMediaInfoResult()
+ public PlaybackInfoResponse()
{
MediaSources = new List<MediaSourceInfo>();
}